require 'mustache' require 'tmpdir' require 'yaml' require 'test/unit' # Calls appropriate method on YAML. See: https://gist.github.com/tenderlove/958999ab4240b93bd3cd if RUBY_VERSION > "1.8" YAML.add_domain_type(nil, 'code') { |_, val| eval(val['ruby']) } else YAML.add_builtin_type('code') { |_, val| eval(val['ruby']) } end # A simple base class for Mustache specs. # Creates a partials directory, then points a (dynamic) subclass of Mustache at # that directory before each test; the partials directory is destroyed after # each test is run. class MustacheSpec < Test::Unit::TestCase def setup @partials = File.join(File.dirname(__FILE__), 'partials') Dir.mkdir(@partials) @Mustache = Class.new(Mustache) @Mustache.template_path = @partials end def teardown Dir[File.join(@partials, '*')].each { |file| File.delete(file) } Dir.rmdir(@partials) end # Extracts the partials from the test, and dumps them into the partials # directory for inclusion. def setup_partials(test) (test['partials'] || {}).each do |name, content| File.open(File.join(@partials, "#{name}.mustache"), 'w') do |f| f.print(content) end end end # Asserts equality between the rendered template and the expected value, # printing additional context data on failure. def assert_mustache_spec(test) actual = @Mustache.render(test['template'], test['data']) assert_equal test['expected'], actual, "" << "#{ test['desc'] }\n" << "Data: #{ test['data'].inspect }\n" << "Template: #{ test['template'].inspect }\n" << "Partials: #{ (test['partials'] || {}).inspect }\n" end def test_noop; assert(true); end end spec_files = File.join(File.dirname(__FILE__), '..', 'ext', 'spec', 'specs', '*.yml') Dir[spec_files].each do |file| spec = YAML.load_file(file) klass_name = "Test" + File.basename(file, ".yml").sub(/~/, '').capitalize instance_eval "class ::#{klass_name} < MustacheSpec; end" test_suite = Kernel.const_get(klass_name) test_suite.class_eval do spec['tests'].each do |test| define_method :"test - #{test['name']}" do setup_partials(test) assert_mustache_spec(test) end end end end