test-unit-ext 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,186 @@
1
+ require "test/unit"
2
+
3
+ require "fileutils"
4
+
5
+ module Test
6
+ module Unit
7
+ class TestCase
8
+ class << self
9
+ def inherited(sub)
10
+ super
11
+ sub.instance_variable_set("@priority_initialized", true)
12
+ sub.instance_variable_set("@priority_table", {})
13
+ sub.priority :normal
14
+ end
15
+
16
+ def include(*args)
17
+ args.reverse_each do |mod|
18
+ super(mod)
19
+ next unless defined?(@priority_initialized)
20
+ mod.instance_methods(false).each do |name|
21
+ set_priority(name)
22
+ end
23
+ end
24
+ end
25
+
26
+ alias_method :method_added_without_priority, :method_added
27
+ def method_added(name)
28
+ method_added_without_priority(name)
29
+ set_priority(name) if defined?(@priority_initialized)
30
+ end
31
+
32
+ def priority(name, *tests)
33
+ singleton_class = (class << self; self; end)
34
+ priority_check_method = priority_check_method_name(name)
35
+ unless singleton_class.private_method_defined?(priority_check_method)
36
+ raise ArgumentError, "unknown priority: #{name}"
37
+ end
38
+ if tests.empty?
39
+ @current_priority = name
40
+ else
41
+ tests.each do |test|
42
+ set_priority(test, name)
43
+ end
44
+ end
45
+ end
46
+
47
+ def need_to_run?(test_name)
48
+ normalized_test_name = normalize_test_name(test_name)
49
+ priority = @priority_table[normalized_test_name]
50
+ return true unless priority
51
+ __send__(priority_check_method_name(priority), test_name)
52
+ end
53
+
54
+ private
55
+ def priority_check_method_name(priority_name)
56
+ "run_priority_#{priority_name}?"
57
+ end
58
+
59
+ def normalize_test_name(test_name)
60
+ "test_#{test_name.to_s.sub(/^test_/, '')}"
61
+ end
62
+
63
+ def set_priority(name, priority=@current_priority)
64
+ @priority_table[normalize_test_name(name)] = priority
65
+ end
66
+
67
+ def run_priority_must?(test_name)
68
+ true
69
+ end
70
+
71
+ def run_priority_important?(test_name)
72
+ rand > 0.1
73
+ end
74
+
75
+ def run_priority_high?(test_name)
76
+ rand > 0.3
77
+ end
78
+
79
+ def run_priority_normal?(test_name)
80
+ rand > 0.5
81
+ end
82
+
83
+ def run_priority_low?(test_name)
84
+ rand > 0.75
85
+ end
86
+
87
+ def run_priority_never?(test_name)
88
+ false
89
+ end
90
+ end
91
+
92
+ def need_to_run?
93
+ !previous_test_success? or self.class.need_to_run?(@method_name)
94
+ end
95
+
96
+ alias_method :run_without_priority, :run
97
+ def run(result, &block)
98
+ run_without_priority(result, &block)
99
+ ensure
100
+ if passed?
101
+ FileUtils.touch(passed_file)
102
+ else
103
+ FileUtils.rm_f(passed_file)
104
+ end
105
+ end
106
+
107
+ private
108
+ def previous_test_success?
109
+ File.exist?(passed_file)
110
+ end
111
+
112
+ def result_dir
113
+ components = [".test-result", self.class.name, @method_name.to_s]
114
+ dir = File.join(File.dirname($0), *components)
115
+ dir = File.expand_path(dir)
116
+ begin
117
+ FileUtils.mkdir_p(dir)
118
+ rescue Errno::EACCES
119
+ retry_dir = File.join(File.dirname(__FILE__), "..", *components)
120
+ retry_dir = File.expand_path(retry_dir)
121
+ raise if retry_dir == dir
122
+ dir = retry_dir
123
+ retry
124
+ end
125
+ dir
126
+ end
127
+
128
+ def passed_file
129
+ File.join(result_dir, "passed")
130
+ end
131
+
132
+ def escaped_method_name
133
+ @method_name.to_s.gsub(/[!?]$/) do |matched|
134
+ case matched
135
+ when "!"
136
+ ".destructive"
137
+ when "?"
138
+ ".predicate"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ class TestSuite
145
+ @@priority_mode = false
146
+
147
+ class << self
148
+ def priority_mode=(bool)
149
+ @@priority_mode = bool
150
+ end
151
+ end
152
+
153
+ alias_method :original_run, :run
154
+ def run(*args, &block)
155
+ priority_mode = @@priority_mode
156
+ if priority_mode
157
+ @original_tests = @tests
158
+ apply_priority
159
+ end
160
+ original_run(*args, &block)
161
+ ensure
162
+ @tests = @original_tests if priority_mode
163
+ end
164
+
165
+ def apply_priority
166
+ @tests = @tests.reject {|test| !test.need_to_run?}
167
+ end
168
+
169
+ def need_to_run?
170
+ apply_priority
171
+ !@tests.empty?
172
+ end
173
+ end
174
+
175
+ class AutoRunner
176
+ alias_method :options_without_priority, :options
177
+ def options
178
+ opts = options_without_priority
179
+ opts.on("--[no-]priority", "use priority mode") do |bool|
180
+ TestSuite.priority_mode = bool
181
+ end
182
+ opts
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,3 @@
1
+ module TestUnitExt
2
+ VERSION = "0.1.0"
3
+ end
data/misc/rd2html.rb ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ top = File.expand_path(File.join(File.dirname(__FILE__), ".."))
4
+ html_dir = File.join(top, "html")
5
+
6
+ require "fileutils"
7
+
8
+ css = "base.css"
9
+ kcode = "utf8"
10
+
11
+ options = [
12
+ "-I#{File.join(top, 'misc')}",
13
+ "-S",
14
+ "rd2",
15
+ "-rrd/rd2html-lib",
16
+ "--out-code=#{kcode}",
17
+ proc do |f|
18
+ "--html-title=#{File.basename(f)}"
19
+ end,
20
+ # proc do |f|
21
+ # "--with-css=#{css}"
22
+ # end,
23
+ proc do |f|
24
+ f
25
+ end
26
+ ]
27
+
28
+ Dir[File.join(top, "*.{ja,en}")].each do |f|
29
+ if /(README|NEWS)\.(ja|en)\z/ =~ f
30
+ args = options.collect do |x|
31
+ if x.respond_to?(:call)
32
+ x.call(f)
33
+ else
34
+ x
35
+ end
36
+ end
37
+ output_base = File.basename(f).downcase.sub(/(ja|en)\z/, "html.\\1")
38
+ File.open(File.join(html_dir, output_base), "w") do |out|
39
+ out.puts(`ruby #{args.flatten.join(' ')}`)
40
+ end
41
+ end
42
+ end
data/test/run-test.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift("./lib")
4
+ $LOAD_PATH.unshift("./test")
5
+
6
+ require "test-unit-ext"
7
+
8
+ Dir.glob("test/**/test_*.rb") do |test|
9
+ begin
10
+ require test
11
+ rescue LoadError
12
+ puts "Can't load: #{test}: #{$!.message}"
13
+ end
14
+ end
@@ -0,0 +1,39 @@
1
+ require 'test-unit-ext'
2
+
3
+ class TestColor < Test::Unit::TestCase
4
+ def test_color_escape_sequence
5
+ assert_escape_sequence(["31"], color("red"))
6
+ assert_escape_sequence(["32", "1"], color("green", :bold => true))
7
+ assert_escape_sequence(["0"], color("reset"))
8
+ assert_escape_sequence(["45"], color("magenta", :foreground => false))
9
+ end
10
+
11
+ def test_mix_color_escape_sequence
12
+ assert_escape_sequence(["34", "1"],
13
+ mix_color([color("blue"),
14
+ color("none", :bold => true)]))
15
+ assert_escape_sequence(["34", "1", "4"],
16
+ mix_color([color("blue"),
17
+ color("none", :bold => true)]) +
18
+ color("none", :underline => true))
19
+ assert_escape_sequence(["34", "1", "4"],
20
+ color("blue") +
21
+ color("none", :bold => true) +
22
+ color("none", :underline => true))
23
+ end
24
+
25
+ private
26
+ def color(name, options={})
27
+ Test::Color.new(name, options)
28
+ end
29
+
30
+ def mix_color(colors)
31
+ Test::MixColor.new(colors)
32
+ end
33
+
34
+ def assert_escape_sequence(expected, color)
35
+ assert_equal(expected, color.sequence)
36
+ assert_match(/\e\[(?:\d+;)*\d+m/, color.escape_sequence)
37
+ assert_equal(expected, color.escape_sequence[2..-2].split(";"))
38
+ end
39
+ end
data/test/test_diff.rb ADDED
@@ -0,0 +1,109 @@
1
+ require 'test-unit-ext'
2
+
3
+ class TestDiff < Test::Unit::TestCase
4
+ def test_to_indexes
5
+ assert_to_indexes({"abc def" => [0, 2], "abc" => [1]},
6
+ ["abc def", "abc", "abc def"])
7
+ end
8
+
9
+ def test_longest_match
10
+ assert_longest_match([0, 1, 3],
11
+ %w(b c d), %w(a b c d x y z),
12
+ 0, 2, 0, 7)
13
+ assert_longest_match([1, 2, 2],
14
+ %w(b c d), %w(a b c d x y z),
15
+ 1, 2, 0, 6)
16
+ assert_longest_match([0, 0, 0],
17
+ %w(a b), %w(c),
18
+ 0, 1, 0, 0)
19
+ assert_longest_match([1, 0, 2],
20
+ %w(q a b x c d), %w(a b y c d f),
21
+ 0, 5, 0, 5)
22
+ end
23
+
24
+ def _test_matching_blocks
25
+ assert_matching_blocks([[0, 0, 2],
26
+ [3, 2, 2],
27
+ [5, 4, 0]],
28
+ %w(a b x c d), %w(a b c d))
29
+ assert_matching_blocks([[1, 0, 2],
30
+ [4, 3, 2],
31
+ [6, 6, 0]],
32
+ %w(q a b x c d), %q(a b y c d f))
33
+ end
34
+
35
+ def test_operations
36
+ assert_operations([[:delete, 0, 1, 0, 0],
37
+ [:equal, 1, 3, 0, 2],
38
+ [:replace, 3, 4, 2, 3],
39
+ [:equal, 4, 6, 3, 5],
40
+ [:insert, 6, 6, 5, 6]],
41
+ %w(q a b x c d), %w(a b y c d f))
42
+ end
43
+
44
+ def test_same_contents
45
+ assert_ndiff(" aaa", ["aaa"], ["aaa"])
46
+ assert_ndiff(" aaa\n" \
47
+ " bbb",
48
+ ["aaa", "bbb"], ["aaa", "bbb"])
49
+ end
50
+
51
+ def test_deleted
52
+ assert_ndiff(" aaa\n" \
53
+ " bbb\n" \
54
+ "- bbb",
55
+ ["aaa", "bbb"], ["aaa"])
56
+ assert_ndiff(" aaa\n" \
57
+ " bbb\n" \
58
+ "- bbb\n" \
59
+ "- ccc\n" \
60
+ "- ddd",
61
+ ["aaa", "bbb", "ccc", "ddd"], ["aaa"])
62
+ end
63
+
64
+ def test_format_diff_point
65
+ assert_format_diff_point(["- \tabcDefghiJkl",
66
+ "? \t ^ ^ ^",
67
+ "+ \t\tabcdefGhijkl",
68
+ "? \t ^ ^ ^"],
69
+ "\tabcDefghiJkl",
70
+ "\t\tabcdefGhijkl",
71
+ " ^ ^ ^ ",
72
+ "+ ^ ^ ^ ")
73
+ end
74
+
75
+ private
76
+ def assert_to_indexes(expected, to)
77
+ matcher = Test::Diff::SequenceMatcher.new([""], to)
78
+ assert_equal(expected, matcher.instance_variable_get("@to_indexes"))
79
+ end
80
+
81
+ def assert_longest_match(expected, from, to,
82
+ from_start, from_end,
83
+ to_start, to_end)
84
+ matcher = Test::Diff::SequenceMatcher.new(from, to)
85
+ assert_equal(expected, matcher.longest_match(from_start, from_end,
86
+ to_start, to_end))
87
+ end
88
+
89
+ def assert_matching_blocks(expected, from, to)
90
+ matcher = Test::Diff::SequenceMatcher.new(from, to)
91
+ assert_equal(expected, matcher.matching_blocks)
92
+ end
93
+
94
+ def assert_operations(expected, from, to)
95
+ matcher = Test::Diff::SequenceMatcher.new(from, to)
96
+ assert_equal(expected, matcher.operations)
97
+ end
98
+
99
+ def assert_ndiff(expected, from, to)
100
+ assert_equal(expected, Test::Diff.ndiff(from, to))
101
+ end
102
+
103
+ def assert_format_diff_point(expected, from_line, to_line, from_tags, to_tags)
104
+ differ = Test::Diff::Differ.new([""], [""])
105
+ assert_equal(expected, differ.send(:format_diff_point,
106
+ from_line, to_line,
107
+ from_tags, to_tags))
108
+ end
109
+ end
@@ -0,0 +1,127 @@
1
+ require 'test-unit-ext'
2
+
3
+ class TestMetadata < Test::Unit::TestCase
4
+ class TestStack < Test::Unit::TestCase
5
+ class << self
6
+ def suite
7
+ Test::Unit::TestSuite.new(name)
8
+ end
9
+ end
10
+
11
+ class Stack
12
+ def initialize
13
+ @data = []
14
+ end
15
+
16
+ def push(data)
17
+ @data.push(data)
18
+ end
19
+
20
+ def peek
21
+ @data[-2]
22
+ end
23
+
24
+ def empty?
25
+ @data.empty?
26
+ end
27
+
28
+ def size
29
+ @data.size + 11
30
+ end
31
+ end
32
+
33
+ def setup
34
+ @stack = Stack.new
35
+ end
36
+
37
+ metadata :category, :accessor
38
+ def test_peek
39
+ @stack.push(1)
40
+ @stack.push(2)
41
+ assert_equal(2, @stack.peek)
42
+ end
43
+
44
+ metadata :bug, 1234
45
+ def test_bug_1234
46
+ assert_equal(0, @stack.size)
47
+ end
48
+
49
+ def test_no_metadata
50
+ assert(@stack.empty?)
51
+ @stack.push(1)
52
+ assert(!@stack.empty?)
53
+ assert_equal(1, @stack.size)
54
+ end
55
+ end
56
+
57
+ def test_set_metadata
58
+ test_for_bug_1234 = TestStack.new("test_bug_1234")
59
+ assert_equal({:bug => 1234}, test_for_bug_1234.metadata)
60
+
61
+ test_no_metadata = TestStack.new("test_no_metadata")
62
+ assert_equal({}, test_no_metadata.metadata)
63
+ end
64
+
65
+ def test_show_metadata
66
+ assert_stack_size_line = search_line('assert_equal(0, @stack.size)')
67
+ assert_peek_line = search_line('assert_equal(2, @stack.peek)')
68
+ first_arg_end_line = search_line("\"<11>.\"],")
69
+ method_name = "test_show_metadata"
70
+ assert_result(["Failure:\n" \
71
+ "test_peek(TestMetadata::TestStack)\n" \
72
+ " category: accessor\n" \
73
+ "#{__FILE__}:#{assert_peek_line}:in `test_peek'\n" \
74
+ "#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
75
+ "<2> expected but was\n" \
76
+ "<1>.",
77
+ "Failure:\n" \
78
+ "test_bug_1234(TestMetadata::TestStack)\n" \
79
+ " bug: 1234\n" \
80
+ "#{__FILE__}:#{assert_stack_size_line}:in `test_bug_1234'\n" \
81
+ "#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
82
+ "<0> expected but was\n" \
83
+ "<11>."],
84
+ [],
85
+ ["test_peek", "test_bug_1234"])
86
+ end
87
+
88
+ def test_not_show_metadata
89
+ assert_line = search_line('assert_equal(1, @stack.size')
90
+ first_arg_end_line = search_line("\"<12>.\"],")
91
+ method_name = "test_not_show_metadata"
92
+ assert_result(["Failure:\n" \
93
+ "test_no_metadata(TestMetadata::TestStack)\n" \
94
+ "#{__FILE__}:#{assert_line}:in `test_no_metadata'\n" \
95
+ "#{__FILE__}:#{first_arg_end_line}:in `#{method_name}':\n" \
96
+ "<1> expected but was\n" \
97
+ "<12>."],
98
+ [],
99
+ ["test_no_metadata"])
100
+ end
101
+
102
+ private
103
+ def search_line(pattern)
104
+ if pattern.is_a?(String)
105
+ pattern = /#{Regexp.escape(pattern)}/
106
+ end
107
+ File.open(__FILE__) do |file|
108
+ while line = file.gets
109
+ return file.lineno if pattern =~ line
110
+ end
111
+ end
112
+ nil
113
+ end
114
+
115
+ def assert_result(failure_results, error_results, names)
116
+ tests = names.collect {|name| TestStack.new(name)}
117
+ result = Test::Unit::TestResult.new
118
+ mark = /\A#{Regexp.escape(__FILE__)}:#{__LINE__ + 1}/
119
+ tests.each {|test| test.run(result) {}}
120
+ failures = result.instance_variable_get("@failures")
121
+ errors = result.instance_variable_get("@errors")
122
+ failures.each {|f| f.location.reject! {|l| mark =~ l}}
123
+ assert_equal([failure_results, error_results],
124
+ [failures.collect {|failure| failure.long_display},
125
+ errors.collect {|error| error.long_display}])
126
+ end
127
+ end