autotest-standalone 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ module Autotest::AutoUpdate
2
+ @@sleep_time, @@update_cmd, @@updater = 60, "svn up", nil
3
+
4
+ def self.sleep_time= o
5
+ @@sleep_time = o
6
+ end
7
+
8
+ def self.update_cmd= o
9
+ @@update_cmd = o
10
+ end
11
+
12
+ Autotest.add_hook :run_command do |at|
13
+ @@updater.kill if @@updater
14
+ end
15
+
16
+ Autotest.add_hook :ran_command do |at|
17
+ @@updater = Thread.start do
18
+ loop do
19
+ puts "# Waiting for #{@@sleep_time} seconds before updating"
20
+ sleep @@sleep_time
21
+ puts "# Running #{@@update_cmd}"
22
+ system @@update_cmd
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ ##
2
+ # Prefix all test runs with `bundle exec` so the runs use the bundled
3
+ # environment.
4
+
5
+ module Autotest::Bundler
6
+ Autotest.add_hook :initialize do |at|
7
+ at.prefix = "bundle exec "
8
+ false
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ ##
2
+ # this is for autotest plugin developers only...
3
+
4
+ module Autotest::Once
5
+ Autotest.add_hook :ran_command do |at|
6
+ exit 0
7
+ end
8
+ end
9
+
@@ -0,0 +1,27 @@
1
+ module Autotest::RCov
2
+ @@command, @@options = "rcov", nil
3
+
4
+ def self.command= o
5
+ @@command = o
6
+ end
7
+
8
+ def self.pattern= o
9
+ warn "RCov.pattern= no longer has any functionality. please remove."
10
+ end
11
+
12
+ def self.options= o
13
+ @@options = o
14
+ end
15
+
16
+ Autotest.add_hook :all_good do |at|
17
+ options = @@options ? "RCOVOPTS=\"#{@@options}\"" : ""
18
+ system "rake #{@@command} #{options}"
19
+ false
20
+ end
21
+
22
+ Autotest.add_hook :initialize do |at|
23
+ at.add_exception 'coverage'
24
+ at.add_exception 'coverage.info'
25
+ false
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ module Autotest::Restart
2
+ Autotest.add_hook :updated do |at, *args|
3
+ if args.flatten.include? ".autotest" then
4
+ warn "Detected change to .autotest, restarting"
5
+ cmd = %w(autotest)
6
+ cmd << " -v" if $v
7
+ cmd += ARGV
8
+
9
+ exec(*cmd)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # -*- ruby -*-
2
+
3
+ module Autotest::Timestamp
4
+ Autotest.add_hook :waiting do
5
+ puts
6
+ puts "# Waiting since #{Time.now.strftime "%Y-%m-%d %H:%M:%S"}"
7
+ puts
8
+ end
9
+ end
@@ -0,0 +1,272 @@
1
+ require 'tempfile'
2
+
3
+ ##
4
+ # UnitDiff makes reading Test::Unit output easy and fun. Instead of a
5
+ # confusing jumble of text with nearly unnoticable changes like this:
6
+ #
7
+ # 1) Failure:
8
+ # test_to_gpoints(RouteTest) [test/unit/route_test.rb:29]:
9
+ # <"new GPolyline([\n new GPoint( 47.00000, -122.00000),\n new GPoint( 46.5000
10
+ # 0, -122.50000),\n new GPoint( 46.75000, -122.75000),\n new GPoint( 46.00000,
11
+ # -123.00000)])"> expected but was
12
+ # <"new Gpolyline([\n new GPoint( 47.00000, -122.00000),\n new GPoint( 46.5000
13
+ # 0, -122.50000),\n new GPoint( 46.75000, -122.75000),\n new GPoint( 46.00000,
14
+ # -123.00000)])">.
15
+ #
16
+ #
17
+ # You get an easy-to-read diff output like this:
18
+ #
19
+ # 1) Failure:
20
+ # test_to_gpoints(RouteTest) [test/unit/route_test.rb:29]:
21
+ # 1c1
22
+ # < new GPolyline([
23
+ # ---
24
+ # > new Gpolyline([
25
+ #
26
+ # == Usage
27
+ #
28
+ # test.rb | unit_diff [options]
29
+ # options:
30
+ # -b ignore whitespace differences
31
+ # -c contextual diff
32
+ # -h show usage
33
+ # -k keep temp diff files around
34
+ # -l prefix line numbers on the diffs
35
+ # -u unified diff
36
+ # -v display version
37
+
38
+ class UnitDiff
39
+
40
+ WINDOZE = /win32/ =~ RUBY_PLATFORM unless defined? WINDOZE
41
+ DIFF = if WINDOZE
42
+ 'diff.exe'
43
+ else
44
+ if system("gdiff", __FILE__, __FILE__)
45
+ 'gdiff' # solaris and kin suck
46
+ else
47
+ 'diff'
48
+ end
49
+ end unless defined? DIFF
50
+
51
+ ##
52
+ # Handy wrapper for UnitDiff#unit_diff.
53
+
54
+ def self.unit_diff
55
+ trap 'INT' do exit 1 end
56
+ puts UnitDiff.new.unit_diff
57
+ end
58
+
59
+ def parse_input(input, output)
60
+ current = []
61
+ data = []
62
+ data << current
63
+ print_lines = true
64
+
65
+ term = "\nFinished".split(//).map { |c| c[0] }
66
+ term_length = term.size
67
+
68
+ old_sync = output.sync
69
+ output.sync = true
70
+ while line = input.gets
71
+ case line
72
+ when /^(Loaded suite|Started)/ then
73
+ print_lines = true
74
+ output.puts line
75
+ chars = []
76
+ while c = input.getc do
77
+ output.putc c
78
+ chars << c
79
+ tail = chars[-term_length..-1]
80
+ break if chars.size >= term_length and tail == term
81
+ end
82
+ output.puts input.gets # the rest of "Finished in..."
83
+ output.puts
84
+ next
85
+ when /^\s*$/, /^\(?\s*\d+\) (Failure|Error):/, /^\d+\)/ then
86
+ print_lines = false
87
+ current = []
88
+ data << current
89
+ when /^Finished in \d/ then
90
+ print_lines = false
91
+ end
92
+ output.puts line if print_lines
93
+ current << line
94
+ end
95
+ output.sync = old_sync
96
+ data = data.reject { |o| o == ["\n"] or o.empty? }
97
+ footer = data.pop
98
+
99
+ data.map do |result|
100
+ break if result.any? { |l| l =~ / expected( but was|, not)/ }
101
+
102
+ header = result.find do |l|
103
+ l =~ /^\(?\s*\d+\) (Failure|Error):/
104
+ end
105
+
106
+ break unless header
107
+
108
+ message_index = result.index(header) + 2
109
+
110
+ result[message_index..-1] = result[message_index..-1].join
111
+ end
112
+
113
+ return data, footer
114
+ end
115
+
116
+ # Parses a single diff recording the header and what
117
+ # was expected, and what was actually obtained.
118
+ def parse_diff(result)
119
+ header = []
120
+ expect = []
121
+ butwas = []
122
+ footer = []
123
+ found = false
124
+ state = :header
125
+
126
+ until result.empty? do
127
+ case state
128
+ when :header then
129
+ header << result.shift
130
+ state = :expect if result.first =~ /^<|^Expected/
131
+ when :expect then
132
+ case result.first
133
+ when /^Expected (.*?) to equal (.*?):$/ then
134
+ expect << $1
135
+ butwas << $2
136
+ state = :footer
137
+ result.shift
138
+ when /^Expected (.*?), not (.*)$/m then
139
+ expect << $1
140
+ butwas << $2
141
+ state = :footer
142
+ result.shift
143
+ when /^Expected (.*?)$/ then
144
+ expect << "#{$1}\n"
145
+ result.shift
146
+ when /^to equal / then
147
+ state = :spec_butwas
148
+ bw = result.shift.sub(/^to equal (.*):?$/, '\1')
149
+ butwas << bw
150
+ else
151
+ state = :butwas if result.first.sub!(/ expected( but was|, not)/, '')
152
+ expect << result.shift
153
+ end
154
+ when :butwas then
155
+ butwas = result[0..-1]
156
+ result.clear
157
+ when :spec_butwas then
158
+ if result.first =~ /^\s+\S+ at |^:\s*$/
159
+ state = :footer
160
+ else
161
+ butwas << result.shift
162
+ end
163
+ when :footer then
164
+ butwas.last.sub!(/:$/, '')
165
+ footer = result.map {|l| l.chomp }
166
+ result.clear
167
+ else
168
+ raise "unknown state #{state}"
169
+ end
170
+ end
171
+
172
+ return header, expect, nil, footer if butwas.empty?
173
+
174
+ expect.last.chomp!
175
+ expect.first.sub!(/^<\"/, '')
176
+ expect.last.sub!(/\">$/, '')
177
+
178
+ butwas.last.chomp!
179
+ butwas.last.chop! if butwas.last =~ /\.$/
180
+ butwas.first.sub!( /^<\"/, '')
181
+ butwas.last.sub!(/\">$/, '')
182
+
183
+ return header, expect, butwas, footer
184
+ end
185
+
186
+ ##
187
+ # Scans Test::Unit output +input+ looking for comparison failures and makes
188
+ # them easily readable by passing them through diff.
189
+
190
+ def unit_diff(input=ARGF, output=$stdout)
191
+ $b = false unless defined? $b
192
+ $c = false unless defined? $c
193
+ $k = false unless defined? $k
194
+ $u = false unless defined? $u
195
+
196
+ data, footer = self.parse_input(input, output)
197
+
198
+ output = []
199
+
200
+ # Output
201
+ data.each do |result|
202
+ first = []
203
+ second = []
204
+
205
+ if result.first =~ /Error/ then
206
+ output.push result.join('')
207
+ next
208
+ end
209
+
210
+ prefix, expect, butwas, result_footer = parse_diff(result)
211
+
212
+ output.push prefix.compact.map {|line| line.strip}.join("\n")
213
+
214
+ if butwas then
215
+ output.push self.diff(expect, butwas)
216
+
217
+ output.push result_footer
218
+ output.push ''
219
+ else
220
+ output.push expect.join('')
221
+ end
222
+ end
223
+
224
+ if footer then
225
+ footer.shift if footer.first.strip.empty?# unless footer.first.nil?
226
+ output.push footer.compact.map {|line| line.strip}.join("\n")
227
+ end
228
+
229
+ return output.flatten.join("\n")
230
+ end
231
+
232
+ def diff expect, butwas
233
+ output = nil
234
+
235
+ Tempfile.open("expect") do |a|
236
+ a.write(massage(expect))
237
+ a.rewind
238
+ Tempfile.open("butwas") do |b|
239
+ b.write(massage(butwas))
240
+ b.rewind
241
+
242
+ diff_flags = $u ? "-u" : $c ? "-c" : ""
243
+ diff_flags += " -b" if $b
244
+
245
+ result = `#{DIFF} #{diff_flags} #{a.path} #{b.path}`
246
+ output = if result.empty? then
247
+ "[no difference--suspect ==]"
248
+ else
249
+ result.split(/\n/)
250
+ end
251
+
252
+ if $k then
253
+ warn "moving #{a.path} to #{a.path}.keep"
254
+ File.rename a.path, a.path + ".keep"
255
+ warn "moving #{b.path} to #{b.path}.keep"
256
+ File.rename b.path, b.path + ".keep"
257
+ end
258
+ end
259
+ end
260
+
261
+ output
262
+ end
263
+
264
+ def massage(data)
265
+ count = 0
266
+ # unescape newlines, strip <> from entire string
267
+ data = data.join
268
+ data = data.gsub(/\\n/, "\n").gsub(/0x[a-f0-9]+/m, '0xXXXXXX') + "\n"
269
+ data += "\n" unless data[-1] == ?\n
270
+ data
271
+ end
272
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH << File.join(File.dirname('..'), 'lib')
2
+ $TESTING = true
3
+
4
+ require 'stringio'
5
+ require 'rubygems'
6
+ require 'test/unit'
@@ -0,0 +1,520 @@
1
+ require File.expand_path('test/helper')
2
+ require 'autotest'
3
+
4
+
5
+ # NOT TESTED:
6
+ # class_run
7
+ # add_sigint_handler
8
+ # all_good
9
+ # get_to_green
10
+ # reset
11
+ # ruby
12
+ # run
13
+ # run_tests
14
+
15
+ class Autotest
16
+ attr_reader :test_mappings, :exception_list
17
+
18
+ def self.clear_hooks
19
+ HOOKS.clear
20
+ end
21
+ end
22
+
23
+ class TestAutotest < Test::Unit::TestCase
24
+ def refute test, msg=nil
25
+ if msg then
26
+ assert ! test, msg
27
+ else
28
+ assert ! test
29
+ end
30
+ end unless respond_to? :refute
31
+ alias :deny :refute
32
+
33
+ RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) unless defined? RUBY
34
+
35
+ def setup
36
+ @test_class = 'TestBlah'
37
+ @test = 'test/test_blah.rb'
38
+ @other_test = 'test/test_blah_other.rb'
39
+ @impl = 'lib/blah.rb'
40
+ @inner_test = 'test/outer/test_inner.rb'
41
+ @outer_test = 'test/test_outer.rb'
42
+ @inner_test_class = "TestOuter::TestInner"
43
+
44
+ klassname = self.class.name.sub(/^Test/, '')
45
+ klassname.sub!(/^(\w+)(Autotest)$/, '\2::\1') unless klassname == "Autotest"
46
+ @a = klassname.split(/::/).inject(Object) { |k,n| k.const_get(n) }.new
47
+ @a.output = StringIO.new
48
+ @a.last_mtime = Time.at(2)
49
+ @a.options[:bundle_exec] = nil
50
+ @a.options[:parallel] = nil
51
+
52
+ @files = {}
53
+ @files[@impl] = Time.at(1)
54
+ @files[@test] = Time.at(2)
55
+
56
+ @a.find_order = @files.keys.sort
57
+ end
58
+
59
+ def test_add_exception
60
+ current = util_exceptions
61
+ @a.add_exception 'blah'
62
+
63
+ actual = util_exceptions
64
+ expect = current + ["blah"]
65
+
66
+ assert_equal expect, actual
67
+ end
68
+
69
+ def test_add_mapping
70
+ current = util_mappings
71
+ @a.add_mapping(/blah/) do 42 end
72
+
73
+ actual = util_mappings
74
+ expect = current + [/blah/]
75
+
76
+ assert_equal expect, actual
77
+ end
78
+
79
+ def test_add_mapping_front
80
+ current = util_mappings
81
+ @a.add_mapping(/blah/, :front) do 42 end
82
+
83
+ actual = util_mappings
84
+ expect = [/blah/] + current
85
+
86
+ assert_equal expect, actual
87
+ end
88
+
89
+ def test_clear_exceptions
90
+ test_add_exception
91
+ @a.clear_exceptions
92
+
93
+ actual = util_exceptions
94
+ expect = []
95
+
96
+ assert_equal expect, actual
97
+ end
98
+
99
+ def test_clear_mapping
100
+ @a.clear_mappings
101
+
102
+ actual = util_mappings
103
+ expect = []
104
+
105
+ assert_equal expect, actual
106
+ end
107
+
108
+ def test_consolidate_failures_experiment
109
+ @files.clear
110
+ @files[@impl] = Time.at(1)
111
+ @files[@test] = Time.at(2)
112
+
113
+ @a.find_order = @files.keys.sort
114
+
115
+ input = [['test_fail1', @test_class],
116
+ ['test_fail2', @test_class],
117
+ ['test_error1', @test_class],
118
+ ['test_error2', @test_class]]
119
+ result = @a.consolidate_failures input
120
+ expected = { @test => %w( test_fail1 test_fail2 test_error1 test_error2 ) }
121
+ assert_equal expected, result
122
+ end
123
+
124
+ def test_consolidate_failures_green
125
+ result = @a.consolidate_failures([])
126
+ expected = {}
127
+ assert_equal expected, result
128
+ end
129
+
130
+ def test_consolidate_failures_multiple_possibilities
131
+ @files[@other_test] = Time.at(42)
132
+ result = @a.consolidate_failures([['test_unmatched', @test_class]])
133
+ expected = { @test => ['test_unmatched']}
134
+ assert_equal expected, result
135
+ expected = ""
136
+ assert_equal expected, @a.output.string
137
+ end
138
+
139
+ def test_consolidate_failures_nested_classes
140
+ @files.clear
141
+ @files['lib/outer.rb'] = Time.at(5)
142
+ @files['lib/outer/inner.rb'] = Time.at(5)
143
+ @files[@inner_test] = Time.at(5)
144
+ @files[@outer_test] = Time.at(5)
145
+
146
+ @a.find_order = @files.keys.sort
147
+
148
+ result = @a.consolidate_failures([['test_blah1', @inner_test_class]])
149
+ expected = { @inner_test => ['test_blah1'] }
150
+ assert_equal expected, result
151
+ expected = ""
152
+ assert_equal expected, @a.output.string
153
+ end
154
+
155
+ def test_consolidate_failures_no_match
156
+ result = @a.consolidate_failures([['test_blah1', @test_class], ['test_blah2', @test_class], ['test_blah1', 'TestUnknown']])
157
+ expected = {@test => ['test_blah1', 'test_blah2']}
158
+ assert_equal expected, result
159
+ expected = "Unable to map class TestUnknown to a file\n"
160
+ assert_equal expected, @a.output.string
161
+ end
162
+
163
+ def test_consolidate_failures_red
164
+ result = @a.consolidate_failures([['test_blah1', @test_class], ['test_blah2', @test_class]])
165
+ expected = {@test => ['test_blah1', 'test_blah2']}
166
+ assert_equal expected, result
167
+ end
168
+
169
+ def test_exceptions
170
+ @a.clear_exceptions
171
+ test_add_exception
172
+ assert_equal(/blah/, @a.exceptions)
173
+ end
174
+
175
+ def test_exceptions_nil
176
+ @a.clear_exceptions
177
+ assert_nil @a.exceptions
178
+ end
179
+
180
+ # TODO: lots of filename edgecases for find_files_to_test
181
+ def test_find_files_to_test
182
+ @a.last_mtime = Time.at(0)
183
+ assert @a.find_files_to_test(@files)
184
+
185
+ @a.last_mtime = @files.values.sort.last + 1
186
+ deny @a.find_files_to_test(@files)
187
+ end
188
+
189
+ def test_find_files_to_test_dunno
190
+ empty = {}
191
+
192
+ files = { "fooby.rb" => Time.at(42) }
193
+ assert @a.find_files_to_test(files) # we find fooby,
194
+ assert_equal empty, @a.files_to_test # but it isn't something to test
195
+ assert_equal "No tests matched fooby.rb\n", @a.output.string
196
+ end
197
+
198
+ def test_find_files_to_test_lib
199
+ # ensure we add test_blah.rb when blah.rb updates
200
+ util_find_files_to_test(@impl, @test => [])
201
+ end
202
+
203
+ def test_find_files_to_test_no_change
204
+ empty = {}
205
+
206
+ # ensure world is virginal
207
+ assert_equal empty, @a.files_to_test
208
+
209
+ # ensure we do nothing when nothing changes...
210
+ files = { @impl => @files[@impl] } # same time
211
+ deny @a.find_files_to_test(files)
212
+ assert_equal empty, @a.files_to_test
213
+ assert_equal "", @a.output.string
214
+
215
+ files = { @impl => @files[@impl] } # same time
216
+ assert(! @a.find_files_to_test(files))
217
+ assert_equal empty, @a.files_to_test
218
+ assert_equal "", @a.output.string
219
+ end
220
+
221
+ def test_find_files_to_test_test
222
+ # ensure we add test_blah.rb when test_blah.rb itself updates
223
+ util_find_files_to_test(@test, @test => [])
224
+ end
225
+
226
+ def test_reorder_alpha
227
+ @a.order = :alpha
228
+ expected = @files.sort
229
+
230
+ assert_equal expected, @a.reorder(@files)
231
+ end
232
+
233
+ def test_reorder_reverse
234
+ @a.order = :reverse
235
+ expected = @files.sort.reverse
236
+
237
+ assert_equal expected, @a.reorder(@files)
238
+ end
239
+
240
+ def test_reorder_random
241
+ @a.order = :random
242
+
243
+ srand 42
244
+ expected, size = @files.dup, @files.size
245
+ expected = expected.sort_by { rand(size) }
246
+
247
+ srand 42
248
+ result = @a.reorder(@files.dup)
249
+
250
+ assert_equal expected, result
251
+ end
252
+
253
+ def test_reorder_natural
254
+ srand 42
255
+
256
+ @files['lib/untested_blah.rb'] = Time.at(2)
257
+ @a.find_order = @files.keys.sort_by { rand }
258
+
259
+ @a.order = :natural
260
+ expected = @a.find_order.map { |f| [f, @files[f]] }
261
+
262
+ assert_equal expected, @a.reorder(@files)
263
+ end
264
+
265
+ def test_handle_results
266
+ @a.files_to_test.clear
267
+ @files.clear
268
+ @files[@impl] = Time.at(1)
269
+ @files[@test] = Time.at(2)
270
+
271
+ @a.find_order = @files.keys.sort
272
+
273
+ empty = {}
274
+ assert_equal empty, @a.files_to_test, "must start empty"
275
+
276
+ s1 = "Loaded suite -e
277
+ Started
278
+ ............
279
+ Finished in 0.001655 seconds.
280
+
281
+ 12 tests, 18 assertions, 0 failures, 0 errors
282
+ "
283
+
284
+ @a.handle_results(s1)
285
+ assert_equal empty, @a.files_to_test, "must stay empty"
286
+
287
+ exp = { "tests" => 12, "assertions" => 18, "failures" => 0, "errors" => 0 }
288
+ assert_equal exp, @a.latest_results
289
+
290
+ s2 = "
291
+ 1) Failure:
292
+ test_fail1(#{@test_class}) [#{@test}:59]:
293
+ 2) Failure:
294
+ test_fail2(#{@test_class}) [#{@test}:60]:
295
+ 3) Error:
296
+ test_error1(#{@test_class}):
297
+ 3) Error:
298
+ test_error2(#{@test_class}):
299
+
300
+ 12 tests, 18 assertions, 2 failures, 2 errors
301
+ "
302
+
303
+ @a.handle_results(s2)
304
+ expected = { @test => %w( test_fail1 test_fail2 test_error1 test_error2 ) }
305
+ assert_equal expected, @a.files_to_test
306
+ assert @a.tainted
307
+ exp = { "tests" => 12, "assertions" => 18, "failures" => 2, "errors" => 2 }
308
+ assert_equal exp, @a.latest_results
309
+
310
+ @a.handle_results(s1)
311
+ assert_equal empty, @a.files_to_test
312
+
313
+ s3 = '
314
+ /opt/bin/ruby -I.:lib:test -rubygems -e "%w[test/unit #{@test}].each { |f| require f }" | unit_diff -u
315
+ -e:1:in `require\': ./#{@test}:23: parse error, unexpected tIDENTIFIER, expecting \'}\' (SyntaxError)
316
+ settings_fields.each {|e| assert_equal e, version.send e.intern}
317
+ ^ from -e:1
318
+ from -e:1:in `each\'
319
+ from -e:1
320
+ '
321
+ @a.files_to_test[@test] = Time.at(42)
322
+ @files[@test] = []
323
+ expected = { @test => Time.at(42) }
324
+ assert_equal expected, @a.files_to_test
325
+ @a.handle_results(s3)
326
+ assert_equal expected, @a.files_to_test
327
+ assert @a.tainted
328
+ @a.tainted = false
329
+
330
+ @a.handle_results(s1)
331
+ assert_equal empty, @a.files_to_test
332
+ deny @a.tainted
333
+ end
334
+
335
+ def test_hook_overlap_returning_false
336
+ util_reset_hooks_returning false
337
+
338
+ @a.hook :blah
339
+
340
+ assert @a.instance_variable_get(:@blah1), "Hook1 should work on blah"
341
+ assert @a.instance_variable_get(:@blah2), "Hook2 should work on blah"
342
+ assert @a.instance_variable_get(:@blah3), "Hook3 should work on blah"
343
+ end
344
+
345
+ def test_hook_overlap_returning_true
346
+ util_reset_hooks_returning true
347
+
348
+ @a.hook :blah
349
+
350
+ assert @a.instance_variable_get(:@blah1), "Hook1 should work on blah"
351
+ deny @a.instance_variable_get(:@blah2), "Hook2 should NOT work on blah"
352
+ deny @a.instance_variable_get(:@blah3), "Hook3 should NOT work on blah"
353
+ end
354
+
355
+ def test_hook_response
356
+ Autotest.clear_hooks
357
+ deny @a.hook(:blah)
358
+
359
+ Autotest.add_hook(:blah) { false }
360
+ deny @a.hook(:blah)
361
+
362
+ Autotest.add_hook(:blah) { false }
363
+ deny @a.hook(:blah)
364
+
365
+ Autotest.add_hook(:blah) { true }
366
+ assert @a.hook(:blah)
367
+ end
368
+
369
+ def test_make_test_cmd_basics
370
+ f = {
371
+ @test => [],
372
+ 'test/test_fooby.rb' => [ 'test_something1', 'test_something2' ]
373
+ }
374
+
375
+ unit_diff = "ruby #{File.expand_path("#{File.dirname(__FILE__)}/../bin/unit_diff")}"
376
+ pre = "#{RUBY} -I.:lib:test -rubygems"
377
+ req = ".each { |f| require f }\""
378
+ post = "| #{unit_diff} -u"
379
+
380
+ expected = [
381
+ "#{pre} -e \"['test/unit', '#{@test}']#{req} #{post}",
382
+ "#{pre} test/test_fooby.rb -n \"/^(test_something1|test_something2)$/\" #{post}"
383
+ ].join("; ")
384
+
385
+ result = @a.make_test_cmd f
386
+ assert_equal expected, result
387
+ end
388
+
389
+ def test_make_test_cmd_uses_bundle_exec_when_given
390
+ @a.prefix = 'bundle exec '
391
+ f = {
392
+ @test => []
393
+ }
394
+ result = @a.make_test_cmd f
395
+ assert_match /^bundle exec \//,result
396
+ end
397
+
398
+ def test_make_test_cmd_uses_prefix_with_parallel_test
399
+ @a.prefix = 'bundle exec '
400
+ @a.options[:parallel] = true
401
+ f = {
402
+ 'test/a.rb' => [],
403
+ 'test/b.rb' => []
404
+ }
405
+ result = @a.make_test_cmd f
406
+ assert_match /^bundle exec parallel_test/, result
407
+ end
408
+
409
+ def test_make_test_cmd_uses_parallel_with_multiple_files
410
+ @a.options[:parallel] = true
411
+ f = {
412
+ 'test/a.rb' => [],
413
+ 'test/b.rb' => []
414
+ }
415
+ result = @a.make_test_cmd f
416
+ assert_match /^parallel_test/, result
417
+ end
418
+
419
+ def test_make_test_cmd_does_not_use_parallel_for_single_file
420
+ @a.options[:parallel] = true
421
+ f = {
422
+ 'test/a.rb' => []
423
+ }
424
+ result = @a.make_test_cmd f
425
+ assert_equal nil, (/^parallel_test/ =~ result)
426
+ end
427
+
428
+ def test_path_to_classname
429
+ # non-rails
430
+ util_path_to_classname 'TestBlah', 'test/test_blah.rb'
431
+ util_path_to_classname 'TestOuter::TestInner', 'test/outer/test_inner.rb'
432
+ util_path_to_classname 'TestRuby2Ruby', 'test/test_ruby2ruby.rb'
433
+ end
434
+
435
+ def test_remove_exception
436
+ test_add_exception
437
+ current = util_exceptions
438
+ @a.remove_exception 'blah'
439
+
440
+ actual = util_exceptions
441
+ expect = current - ["blah"]
442
+
443
+ assert_equal expect, actual
444
+ end
445
+
446
+ def test_remove_mapping
447
+ current = util_mappings
448
+ @a.remove_mapping(/^lib\/.*\.rb$/)
449
+
450
+ actual = util_mappings
451
+ expect = current - [/^lib\/.*\.rb$/]
452
+
453
+ assert_equal expect, actual
454
+ end
455
+
456
+ def test_test_files_for
457
+ assert_equal [@test], @a.test_files_for(@impl)
458
+ assert_equal [@test], @a.test_files_for(@test)
459
+
460
+ assert_equal [], @a.test_files_for('test/test_unknown.rb')
461
+ assert_equal [], @a.test_files_for('lib/unknown.rb')
462
+ assert_equal [], @a.test_files_for('unknown.rb')
463
+ assert_equal [], @a.test_files_for('test_unknown.rb')
464
+ end
465
+
466
+ def test_testlib
467
+ assert_equal "test/unit", @a.testlib
468
+
469
+ @a.testlib = "MONKEY"
470
+ assert_equal "MONKEY", @a.testlib
471
+
472
+ f = { @test => [], "test/test_fooby.rb" => %w(first second) }
473
+ assert_match @a.testlib, @a.make_test_cmd(f)
474
+ end
475
+
476
+ def util_exceptions
477
+ @a.exception_list.sort_by { |r| r.to_s }
478
+ end
479
+
480
+ def util_find_files_to_test(f, expected)
481
+ t = @a.last_mtime
482
+ files = { f => t + 1 }
483
+
484
+ assert @a.find_files_to_test(files)
485
+ assert_equal expected, @a.files_to_test
486
+ assert_equal t, @a.last_mtime
487
+ assert_equal "", @a.output.string
488
+ end
489
+
490
+ def util_mappings
491
+ @a.test_mappings.map { |k,v| k }
492
+ end
493
+
494
+ def util_path_to_classname(e,i)
495
+ assert_equal e, @a.path_to_classname(i)
496
+ end
497
+
498
+ def util_reset_hooks_returning val
499
+ Autotest.clear_hooks
500
+
501
+ @a.instance_variable_set :@blah1, false
502
+ @a.instance_variable_set :@blah2, false
503
+ @a.instance_variable_set :@blah3, false
504
+
505
+ Autotest.add_hook(:blah) do |at|
506
+ at.instance_variable_set :@blah1, true
507
+ val
508
+ end
509
+
510
+ Autotest.add_hook(:blah) do |at|
511
+ at.instance_variable_set :@blah2, true
512
+ val
513
+ end
514
+
515
+ Autotest.add_hook(:blah) do |at|
516
+ at.instance_variable_set :@blah3, true
517
+ val
518
+ end
519
+ end
520
+ end