| 1 |
require 'test/unit' |
|---|
| 2 |
require 'yaml' |
|---|
| 3 |
|
|---|
| 4 |
module YamlTest |
|---|
| 5 |
module Helper |
|---|
| 6 |
def self.included(obj) |
|---|
| 7 |
obj.extend YamlTest::ClassMethods |
|---|
| 8 |
end |
|---|
| 9 |
end |
|---|
| 10 |
|
|---|
| 11 |
module ClassMethods |
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
def file_list(caller_dir, opts) |
|---|
| 15 |
directories = opts[:directories] || [:default] |
|---|
| 16 |
|
|---|
| 17 |
if files = opts[:files] |
|---|
| 18 |
files.map!{|f| f.to_s} |
|---|
| 19 |
end |
|---|
| 20 |
|
|---|
| 21 |
directories = directories.map do |dir| |
|---|
| 22 |
if dir == :default |
|---|
| 23 |
if caller_dir.split('/').last =~ /^(.*)_test.rb/ |
|---|
| 24 |
directories = [File.join(File.dirname(caller_dir), $1)] |
|---|
| 25 |
else |
|---|
| 26 |
puts "Bad file name for yaml_tests '#{caller_dir}'. Should be '..._test.rb'. Trying parent directory." |
|---|
| 27 |
directories = [File.dirname(caller_dir)] |
|---|
| 28 |
end |
|---|
| 29 |
else |
|---|
| 30 |
Dir[dir] |
|---|
| 31 |
end |
|---|
| 32 |
end.flatten |
|---|
| 33 |
|
|---|
| 34 |
file_list = [] |
|---|
| 35 |
|
|---|
| 36 |
directories.each do |dir| |
|---|
| 37 |
Dir.foreach(dir) do |f| |
|---|
| 38 |
next unless f =~ /^([\w_-]+).yml/ |
|---|
| 39 |
next if files && !files.include?($1) |
|---|
| 40 |
file_list << [$1, File.join(dir, "#{$1}.yml"), opts[$1] || opts[$1.to_sym] || {}] |
|---|
| 41 |
end |
|---|
| 42 |
end |
|---|
| 43 |
|
|---|
| 44 |
file_list |
|---|
| 45 |
end |
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
def yaml_test(opts = {}) |
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 |
class_eval %Q{ |
|---|
| 70 |
@@test_strings = {} |
|---|
| 71 |
@@test_methods = {} |
|---|
| 72 |
@@test_options = {} |
|---|
| 73 |
@@test_files = [] |
|---|
| 74 |
@@file_list = file_list(#{caller[0].inspect}, #{opts.inspect}) |
|---|
| 75 |
|
|---|
| 76 |
@@file_list.each do |file_name, file_path, opts| |
|---|
| 77 |
strings = {} |
|---|
| 78 |
test_methods = [] |
|---|
| 79 |
begin |
|---|
| 80 |
YAML::load_documents( File.open( file_path ) ) do |doc| |
|---|
| 81 |
doc.each do |elem| |
|---|
| 82 |
test_methods << elem[0] |
|---|
| 83 |
strings[elem[0]] = elem[1] |
|---|
| 84 |
end |
|---|
| 85 |
end |
|---|
| 86 |
rescue ArgumentError => err |
|---|
| 87 |
puts "Error while loading test file \#{file_path}" |
|---|
| 88 |
raise err |
|---|
| 89 |
end |
|---|
| 90 |
class_eval " |
|---|
| 91 |
def \#{file_name} |
|---|
| 92 |
@@test_strings['\#{file_name}'] |
|---|
| 93 |
end |
|---|
| 94 |
" |
|---|
| 95 |
@@test_strings[file_name] = strings.freeze |
|---|
| 96 |
@@test_methods[file_name] = test_methods |
|---|
| 97 |
@@test_files << file_name |
|---|
| 98 |
end |
|---|
| 99 |
|
|---|
| 100 |
|
|---|
| 101 |
def parse(key, source, context) |
|---|
| 102 |
source |
|---|
| 103 |
end |
|---|
| 104 |
|
|---|
| 105 |
def do_test(file, test) |
|---|
| 106 |
context = @@test_strings[file][test]['context'] || {} |
|---|
| 107 |
default_context = (@@test_strings[file]['default'] || {})['context'] || {} |
|---|
| 108 |
context = Hash[*default_context.merge(context).map{|k,v| [k.to_sym,v]}.flatten] |
|---|
| 109 |
@@test_strings[file][test].keys.each do |key| |
|---|
| 110 |
next if ['src', 'context'].include?(key) |
|---|
| 111 |
assert_yaml_test @@test_strings[file][test][key], parse(key, @@test_strings[file][test]['src'] || test.gsub('_',' '), context) |
|---|
| 112 |
end |
|---|
| 113 |
end |
|---|
| 114 |
|
|---|
| 115 |
protected |
|---|
| 116 |
def assert_yaml_test(test_res, res) |
|---|
| 117 |
if test_res.kind_of?(String) && test_res[0..1] == '!/' |
|---|
| 118 |
assert_no_match %r{\#{test_res[2..-2]}}m, res |
|---|
| 119 |
elsif test_res.kind_of?(String) && test_res[0..0] == '/' |
|---|
| 120 |
assert_match %r{\#{test_res[1..-2]}}m, res |
|---|
| 121 |
else |
|---|
| 122 |
assert_equal test_res, res |
|---|
| 123 |
end |
|---|
| 124 |
end |
|---|
| 125 |
} |
|---|
| 126 |
end |
|---|
| 127 |
|
|---|
| 128 |
def make_tests |
|---|
| 129 |
class_eval %q{ |
|---|
| 130 |
return unless @@test_methods |
|---|
| 131 |
tests = self.instance_methods.reject! {|m| !( m =~ /^test_/ )} |
|---|
| 132 |
@@test_files.each do |tf| |
|---|
| 133 |
@@test_methods[tf].each do |test| |
|---|
| 134 |
unless tests.include?("test_#{tf}_#{test}") |
|---|
| 135 |
tests << "test_#{tf}_#{test}" |
|---|
| 136 |
class_eval <<-END |
|---|
| 137 |
def test_#{tf}_#{test} |
|---|
| 138 |
do_test(#{tf.inspect}, #{test.inspect}) |
|---|
| 139 |
end |
|---|
| 140 |
END |
|---|
| 141 |
end |
|---|
| 142 |
end |
|---|
| 143 |
end |
|---|
| 144 |
} |
|---|
| 145 |
end |
|---|
| 146 |
end |
|---|
| 147 |
end |
|---|
| 148 |
|
|---|
| 149 |
Test::Unit::TestCase.send :include, YamlTest::Helper |
|---|