ZenTest 4.4.0 → 4.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,33 @@
1
+ === 4.4.1 / 2010-12-01
2
+
3
+ * 12 minor enhancements:
4
+
5
+ * Merged in most things from the autotest gem:
6
+ * Added --no-full-after-failed. (grosser)
7
+ * Added --rc path-to-dot-autotest. (grosser)
8
+ * Added --style autotest-style. (grosser)
9
+ * Added clarification comments. (grosser)
10
+ * Added rake task descriptions. (grosser)
11
+ * Switched to optparse. (grosser)
12
+ * Switched windoze detection. (grosser, tenderlove)
13
+ * Did not merge test parallelization. It should be a plugin. Awaiting patch.
14
+ * Added autotest/bundler plugin.
15
+ * Added autotest/isolate plugin.
16
+ * Added capture of skips (for minitest) from result line.
17
+ * Added focus_re to focus.rb.
18
+ * Added latest_results hash.
19
+ * Cleaned up unit_diff matcher by using any?
20
+ * Enhanced the help/usage for autotest and zentest. (hugh sasse)
21
+ * Refactored autotest runner discovery.
22
+ * Refactored ruby_cmd to allow plugins to affect ruby execution.
23
+ * Removed befuddling override of Dir.[] from 2007. *shrug*
24
+ * Removed deny method in favor of aliasing refute.
25
+
26
+ * 2 bug fixes:
27
+
28
+ * 1.9 shadowed variable fix
29
+ * autotest/restart now passes ARGV back through to exec. yay!
30
+
1
31
  === 4.4.0 / 2010-09-01
2
32
 
3
33
  * 1 major enhancement:
@@ -18,6 +18,8 @@ example2.rb
18
18
  example_dot_autotest.rb
19
19
  lib/autotest.rb
20
20
  lib/autotest/autoupdate.rb
21
+ lib/autotest/bundler.rb
22
+ lib/autotest/isolate.rb
21
23
  lib/autotest/once.rb
22
24
  lib/autotest/rcov.rb
23
25
  lib/autotest/restart.rb
data/README.txt CHANGED
@@ -63,30 +63,27 @@ implementation.
63
63
 
64
64
  (and other stuff for Test::Rails)
65
65
 
66
+ == Windows and Color
67
+
68
+ Read this: http://blog.mmediasys.com/2010/11/24/we-all-love-colors/
69
+
66
70
  == REQUIREMENTS
67
71
 
68
72
  * Ruby 1.6+, JRuby 1.1.2+, or rubinius
69
- * Test::Unit or miniunit (or something else ... I have no idea)
70
- * Hoe
73
+ * A test/spec framework of your choice.
74
+ * Hoe (development)
71
75
  * rubygems
72
- * diff.exe on windoze. Try http://gnuwin32.sourceforge.net/packages.html
76
+ * diff.exe on windows. Use http://gnuwin32.sourceforge.net/packages.html
73
77
 
74
78
  == INSTALL
75
79
 
76
- Using Rubygems:
77
-
78
80
  * sudo gem install ZenTest
79
81
 
80
- Using Rake:
81
-
82
- * rake test
83
- * sudo rake install
84
-
85
82
  == LICENSE
86
83
 
87
84
  (The MIT License)
88
85
 
89
- Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
86
+ Copyright (c) Ryan Davis, Eric Hodel, Zen Spider Software, Seattle.rb
90
87
 
91
88
  Permission is hereby granted, free of charge, to any person obtaining
92
89
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- ruby -*-
2
2
 
3
- $: << 'lib'
3
+ $LOAD_PATH << 'lib'
4
4
 
5
5
  require 'rubygems'
6
6
  require 'hoe'
@@ -14,10 +14,12 @@ Hoe.spec "ZenTest" do
14
14
  developer 'Eric Hodel', 'drbrain@segment7.net'
15
15
  end
16
16
 
17
+ desc "run autotest on itself"
17
18
  task :autotest do
18
19
  ruby "-Ilib -w ./bin/autotest"
19
20
  end
20
21
 
22
+ desc "update example_dot_autotest.rb with all possible constants"
21
23
  task :update do
22
24
  system "p4 edit example_dot_autotest.rb"
23
25
  File.open "example_dot_autotest.rb", "w" do |f|
@@ -46,14 +48,5 @@ task :update do
46
48
  system "p4 diff -du example_dot_autotest.rb"
47
49
  end
48
50
 
49
- task :sort do
50
- begin
51
- sh 'for f in lib/*.rb; do echo $f; grep "^ *def " $f | grep -v sort=skip > x; sort x > y; echo $f; echo; diff x y; done'
52
- sh 'for f in test/test_*.rb; do echo $f; grep "^ *def.test_" $f > x; sort x > y; echo $f; echo; diff x y; done'
53
- ensure
54
- sh 'rm x y'
55
- end
56
- end
57
-
58
51
  # vim:syntax=ruby
59
52
 
@@ -1,55 +1,7 @@
1
- #!/usr/local/bin/ruby -ws
2
-
3
- $v ||= false
4
- $h ||= false
5
- $f ||= false
6
- $q ||= false
7
- $help ||= false
8
-
9
- if $h or $help then
10
- help = [
11
- "autotest [options]",
12
- nil,
13
- "options:",
14
- "\t-h",
15
- "\t-help\t\tYou're looking at it.",
16
- nil,
17
- "\t-v\t\tBe verbose.",
18
- "\t\t\tPrints files that autotest doesn't know how to map to",
19
- "\t\t\ttests.",
20
- nil,
21
- "\t-q\t\tBe more quiet.",
22
- nil,
23
- "\t-f\t\tFast start.",
24
- "\t\t\tDoesn't initially run tests at start.",
25
- ]
26
- STDERR.puts help.join("\n")
27
- exit 1
28
- end
29
-
30
- class Dir
31
- class << self
32
- alias :old_index :[]
33
- def [](*args)
34
- $-w, old_warn = false, $-w
35
- old_index(*args)
36
- ensure
37
- $-w = old_warn
38
- end
39
- end
40
- end
1
+ #!/usr/bin/env ruby
2
+ $-w = true
41
3
 
42
4
  require 'autotest'
43
- style = Autotest.autodiscover
44
- target = Autotest
45
- unless style.empty? then
46
- mod = "autotest/#{style.join("_")}"
47
- puts "loading #{mod}"
48
- begin
49
- require mod
50
- rescue LoadError
51
- abort "Autotest style #{mod} doesn't seem to exist. Aborting."
52
- end
53
- target = Autotest.const_get(style.map {|s| s.capitalize}.join)
54
- end
55
- target.run
5
+
6
+ Autotest.parse_options
7
+ Autotest.runner.run
@@ -10,12 +10,7 @@ if defined? $v then
10
10
  end
11
11
 
12
12
  if defined? $h then
13
- puts "usage: #{File.basename $0} [-h -v] test-and-implementation-files..."
14
- puts " -h display this information"
15
- puts " -v display version information"
16
- puts " -r Reverse mapping (ClassTest instead of TestClass)"
17
- puts " -e (Rapid XP) eval the code generated instead of printing it"
18
- exit 0
13
+ ZenTest.usage_with_exit
19
14
  end
20
15
 
21
16
  code = ZenTest.fix(*ARGV)
@@ -1,6 +1,8 @@
1
1
  # -*- ruby -*-
2
2
 
3
3
  # require 'autotest/autoupdate'
4
+ # require 'autotest/bundler'
5
+ # require 'autotest/isolate'
4
6
  # require 'autotest/once'
5
7
  # require 'autotest/rcov'
6
8
  # require 'autotest/restart'
@@ -8,5 +10,7 @@
8
10
 
9
11
  # Autotest::AutoUpdate.sleep_time = o
10
12
  # Autotest::AutoUpdate.update_cmd = o
13
+ # Autotest::Isolate.dir = o
11
14
  # Autotest::RCov.command = o
12
15
  # Autotest::RCov.pattern = o
16
+ # Autotest::RCov.options = o
@@ -1,7 +1,6 @@
1
1
  require 'find'
2
2
  require 'rbconfig'
3
3
 
4
- $v ||= false
5
4
  $TESTING = false unless defined? $TESTING
6
5
 
7
6
  ##
@@ -66,14 +65,100 @@ class Autotest
66
65
  ALL_HOOKS = [ :all_good, :died, :green, :initialize, :interrupt, :quit,
67
66
  :ran_command, :red, :reset, :run_command, :updated, :waiting ]
68
67
 
68
+ def self.options
69
+ @@options ||= {}
70
+ end
71
+
72
+ def options
73
+ self.class.options
74
+ end
75
+
69
76
  HOOKS = Hash.new { |h,k| h[k] = [] }
70
77
  unless defined? WINDOZE then
71
- WINDOZE = /win32/ =~ RUBY_PLATFORM
78
+ WINDOZE = /mswin|mingw/ =~ RbConfig::CONFIG['host_os']
72
79
  SEP = WINDOZE ? '&' : ';'
73
80
  end
74
81
 
75
82
  @@discoveries = []
76
83
 
84
+ def self.parse_options
85
+ require 'optparse'
86
+ options = {}
87
+ OptionParser.new do |opts|
88
+ opts.banner = <<-BANNER.gsub(/^ /, '')
89
+ Continuous testing for your ruby app.
90
+
91
+ Autotest automatically tests code that has changed. It
92
+ assumes the code is in lib, and tests are in tests. Autotest
93
+ uses plugins to control what happens. You configure plugins
94
+ with require statements in the .autotest file in your
95
+ project base directory, and a default configuration for all
96
+ your projects in the .autotest file in your home directory.
97
+
98
+ Usage:
99
+ autotest [options]
100
+ BANNER
101
+
102
+ opts.on "-f", "--fast-start", "Do not run full tests at start" do
103
+ options[:no_full_after_start] = true
104
+ end
105
+
106
+ opts.on("-c", "--no-full-after-failed",
107
+ "Do not run all tests on red->green") do
108
+ options[:no_full_after_failed] = true
109
+ end
110
+
111
+ opts.on "-v", "--verbose", "Be annoyingly verbose (debugs .autotest)." do
112
+ options[:verbose] = true
113
+ end
114
+
115
+ opts.on "-q", "--quiet", "Be quiet." do
116
+ options[:quiet] = true
117
+ end
118
+
119
+ opts.on("-r", "--rc CONF", String, "Override path to config file") do |o|
120
+ options[:rc] = o
121
+ end
122
+
123
+ opts.on("-s", "--style STYLE", String,
124
+ "Manually specify test style. (default: autodiscover)") do |style|
125
+ options[:style] = Array(style)
126
+ end
127
+
128
+ opts.on "-h", "--help", "Show this." do
129
+ puts opts
130
+ exit 1
131
+ end
132
+ end.parse!
133
+
134
+ Autotest.options.merge! options
135
+
136
+ options
137
+ end
138
+
139
+ ##
140
+ # Calculates the autotest runner to use to run the tests.
141
+ #
142
+ # Can be overridden with --style, otherwise uses ::autodiscover.
143
+
144
+ def self.runner
145
+ style = options[:style] || Autotest.autodiscover
146
+ target = Autotest
147
+
148
+ unless style.empty? then
149
+ mod = "autotest/#{style.join "_"}"
150
+ puts "loading #{mod}"
151
+ begin
152
+ require mod
153
+ rescue LoadError
154
+ abort "Autotest style #{mod} doesn't seem to exist. Aborting."
155
+ end
156
+ target = Autotest.const_get(style.map {|s| s.capitalize}.join)
157
+ end
158
+
159
+ target
160
+ end
161
+
77
162
  ##
78
163
  # Add a proc to the collection of discovery procs. See
79
164
  # +autodiscover+.
@@ -114,7 +199,8 @@ class Autotest
114
199
  load f
115
200
  end
116
201
 
117
- @@discoveries.map { |proc| proc.call }.flatten.compact.sort.uniq
202
+ # call all discovery procs and determine the style to use
203
+ @@discoveries.map{ |proc| proc.call }.flatten.compact.sort.uniq
118
204
  end
119
205
 
120
206
  ##
@@ -132,10 +218,12 @@ class Autotest
132
218
  :files_to_test,
133
219
  :find_order,
134
220
  :interrupted,
221
+ :latest_results,
135
222
  :last_mtime,
136
223
  :libs,
137
224
  :order,
138
225
  :output,
226
+ :prefix,
139
227
  :results,
140
228
  :sleep,
141
229
  :tainted,
@@ -155,7 +243,8 @@ class Autotest
155
243
  @exception_list = []
156
244
  @test_mappings = []
157
245
 
158
- self.completed_re = /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/
246
+ self.completed_re =
247
+ /\d+ tests, \d+ assertions, \d+ failures, \d+ errors(, \d+ skips)?/
159
248
  self.extra_class_map = {}
160
249
  self.extra_files = []
161
250
  self.failed_results_re = /^\s+\d+\) (?:Failure|Error):\n(.*?)\((.*?)\)/
@@ -165,21 +254,28 @@ class Autotest
165
254
  self.libs = %w[. lib test].join(File::PATH_SEPARATOR)
166
255
  self.order = :random
167
256
  self.output = $stderr
257
+ self.prefix = nil
168
258
  self.sleep = 1
169
259
  self.testlib = "test/unit"
170
260
  self.find_directories = ['.']
171
261
  self.unit_diff = "unit_diff -u"
262
+ self.latest_results = nil
172
263
 
264
+ # file in /lib -> run test in /test
173
265
  self.add_mapping(/^lib\/.*\.rb$/) do |filename, _|
174
- possible = File.basename(filename).gsub '_', '_?'
266
+ possible = File.basename(filename).gsub '_', '_?' # ' stupid emacs
175
267
  files_matching %r%^test/.*#{possible}$%
176
268
  end
177
269
 
270
+ # file in /test -> run it
178
271
  self.add_mapping(/^test.*\/test_.*rb$/) do |filename, _|
179
272
  filename
180
273
  end
181
274
 
182
- [File.expand_path('~/.autotest'), './.autotest'].each do |f|
275
+ default_configs = [File.expand_path('~/.autotest'), './.autotest']
276
+ configs = options[:rc] || default_configs
277
+
278
+ configs.each do |f|
183
279
  load f if File.exist? f
184
280
  end
185
281
  end
@@ -193,12 +289,12 @@ class Autotest
193
289
  reset
194
290
  add_sigint_handler
195
291
 
196
- self.last_mtime = Time.now if $f
292
+ self.last_mtime = Time.now if options[:no_full_after_start]
197
293
 
198
- loop do # ^c handler
199
- begin
294
+ loop do
295
+ begin # ^c handler
200
296
  get_to_green
201
- if tainted? then
297
+ if tainted? and not options[:no_full_after_failed] then
202
298
  rerun_all_tests
203
299
  else
204
300
  hook :all_good
@@ -237,14 +333,14 @@ class Autotest
237
333
  cmd = self.make_test_cmd self.files_to_test
238
334
  return if cmd.empty?
239
335
 
240
- puts cmd unless $q
336
+ puts cmd unless options[:quiet]
241
337
 
242
338
  old_sync = $stdout.sync
243
339
  $stdout.sync = true
244
340
  self.results = []
245
341
  line = []
246
342
  begin
247
- open("| #{cmd}", "r") do |f|
343
+ open "| #{cmd}", "r" do |f|
248
344
  until f.eof? do
249
345
  c = f.getc or break
250
346
  if RUBY19 then
@@ -269,7 +365,7 @@ class Autotest
269
365
  hook :ran_command
270
366
  self.results = self.results.join
271
367
 
272
- handle_results(self.results)
368
+ handle_results self.results
273
369
  end
274
370
 
275
371
  ############################################################
@@ -305,26 +401,26 @@ class Autotest
305
401
  # Convert a path in a string, s, into a class name, changing
306
402
  # underscores to CamelCase, etc.
307
403
 
308
- def path_to_classname(s)
404
+ def path_to_classname s
309
405
  sep = File::SEPARATOR
310
- f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split(sep)
406
+ f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split sep
311
407
  f = f.map { |path| path.split(/_|(\d+)/).map { |seg| seg.capitalize }.join }
312
408
  f = f.map { |path| path =~ /^Test/ ? path : "Test#{path}" }
313
409
 
314
- f.join('::')
410
+ f.join '::'
315
411
  end
316
412
 
317
413
  ##
318
414
  # Returns a hash mapping a file name to the known failures for that
319
415
  # file.
320
416
 
321
- def consolidate_failures(failed)
417
+ def consolidate_failures failed
322
418
  filters = new_hash_of_arrays
323
419
 
324
420
  class_map = Hash[*self.find_order.grep(/^test/).map { |f| # TODO: ugly
325
421
  [path_to_classname(f), f]
326
422
  }.flatten]
327
- class_map.merge!(self.extra_class_map)
423
+ class_map.merge! self.extra_class_map
328
424
 
329
425
  failed.each do |method, klass|
330
426
  if class_map.has_key? klass then
@@ -334,7 +430,7 @@ class Autotest
334
430
  end
335
431
  end
336
432
 
337
- return filters
433
+ filters
338
434
  end
339
435
 
340
436
  ##
@@ -349,7 +445,7 @@ class Autotest
349
445
 
350
446
  targets.each do |target|
351
447
  order = []
352
- Find.find(target) do |f|
448
+ Find.find target do |f|
353
449
  Find.prune if f =~ self.exceptions
354
450
 
355
451
  next if test ?d, f
@@ -364,23 +460,26 @@ class Autotest
364
460
  self.find_order.push(*order.sort)
365
461
  end
366
462
 
367
- return result
463
+ result
368
464
  end
369
465
 
370
466
  ##
371
467
  # Find the files which have been modified, update the recorded
372
- # timestamps, and use this to update the files to test. Returns true
373
- # if any file is newer than the previously recorded most recent
374
- # file.
468
+ # timestamps, and use this to update the files to test. Returns
469
+ # the latest mtime of the files modified or nil when nothing was
470
+ # modified.
375
471
 
376
472
  def find_files_to_test files = find_files
377
473
  updated = files.select { |filename, mtime| self.last_mtime < mtime }
378
474
 
379
- p updated if $v unless updated.empty? || self.last_mtime.to_i == 0
475
+ # nothing to update or initially run
476
+ unless updated.empty? || self.last_mtime.to_i == 0 then
477
+ p updated if options[:verbose]
380
478
 
381
- hook :updated, updated unless updated.empty? || self.last_mtime.to_i == 0
479
+ hook :updated, updated
480
+ end
382
481
 
383
- updated.map { |f,m| test_files_for(f) }.flatten.uniq.each do |filename|
482
+ updated.map { |f,m| test_files_for f }.flatten.uniq.each do |filename|
384
483
  self.files_to_test[filename] # creates key with default value
385
484
  end
386
485
 
@@ -395,14 +494,21 @@ class Autotest
395
494
  # Check results for failures, set the "bar" to red or green, and if
396
495
  # there are failures record this.
397
496
 
398
- def handle_results(results)
399
- failed = results.scan(self.failed_results_re)
400
- completed = results =~ self.completed_re
497
+ def handle_results results
498
+ failed = results.scan self.failed_results_re
499
+ completed = results[self.completed_re]
500
+
501
+ if completed then
502
+ completed = completed.scan(/(\d+) (\w+)/).map { |v, k| [k, v.to_i] }
401
503
 
402
- self.files_to_test = consolidate_failures failed if completed
504
+ self.latest_results = Hash[*completed.flatten]
505
+ self.files_to_test = consolidate_failures failed
403
506
 
404
- color = completed && self.files_to_test.empty? ? :green : :red
405
- hook color unless $TESTING
507
+ color = self.files_to_test.empty? ? :green : :red
508
+ hook color unless $TESTING
509
+ else
510
+ self.latest_results = nil
511
+ end
406
512
 
407
513
  self.tainted = true unless self.files_to_test.empty?
408
514
  end
@@ -417,26 +523,32 @@ class Autotest
417
523
  @known_files
418
524
  end
419
525
 
526
+ ##
527
+ # Returns the base of the ruby command.
528
+
529
+ def ruby_cmd
530
+ "#{prefix}#{ruby} -I#{libs} -rubygems"
531
+ end
532
+
420
533
  ##
421
534
  # Generate the commands to test the supplied files
422
535
 
423
536
  def make_test_cmd files_to_test
424
537
  cmds = []
425
538
  full, partial = reorder(files_to_test).partition { |k,v| v.empty? }
426
- base_cmd = "#{ruby} -I#{libs} -rubygems"
427
539
 
428
540
  unless full.empty? then
429
541
  classes = full.map {|k,v| k}.flatten.uniq
430
542
  classes.unshift testlib
431
- cmds << "#{base_cmd} -e \"%w[#{classes.join(' ')}].each { |f| require f }\" | #{unit_diff}"
543
+ cmds << "#{ruby_cmd} -e \"%w[#{classes.join ' '}].each { |f| require f }\" | #{unit_diff}"
432
544
  end
433
545
 
434
546
  partial.each do |klass, methods|
435
547
  regexp = Regexp.union(*methods).source
436
- cmds << "#{base_cmd} #{klass} -n \"/^(#{regexp})$/\" | #{unit_diff}"
548
+ cmds << "#{ruby_cmd} #{klass} -n \"/^(#{regexp})$/\" | #{unit_diff}"
437
549
  end
438
550
 
439
- return cmds.join("#{SEP} ")
551
+ cmds.join "#{SEP} "
440
552
  end
441
553
 
442
554
  def new_hash_of_arrays
@@ -451,7 +563,7 @@ class Autotest
451
563
  files_to_test.sort_by { |k,v| k }.reverse
452
564
  when :random then
453
565
  max = files_to_test.size
454
- files_to_test.sort_by { |k,v| rand(max) }
566
+ files_to_test.sort_by { |k,v| rand max }
455
567
  when :natural then
456
568
  (self.find_order & files_to_test.keys).map { |f| [f, files_to_test[f]] }
457
569
  else
@@ -476,10 +588,11 @@ class Autotest
476
588
  def reset
477
589
  self.files_to_test.clear
478
590
  self.find_order.clear
479
- self.interrupted = false
480
- self.known_files = nil
481
- self.last_mtime = T0
482
- self.tainted = false
591
+
592
+ self.interrupted = false
593
+ self.known_files = nil
594
+ self.last_mtime = T0
595
+ self.tainted = false
483
596
  self.wants_to_quit = false
484
597
 
485
598
  hook :reset
@@ -503,7 +616,7 @@ class Autotest
503
616
  # a +test_mapping+ that matches the file and executing the mapping's
504
617
  # proc.
505
618
 
506
- def test_files_for(filename)
619
+ def test_files_for filename
507
620
  result = @test_mappings.find { |file_re, ignored| filename =~ file_re }
508
621
 
509
622
  p :test_file_for => [filename, result.first] if result and $DEBUG
@@ -511,7 +624,7 @@ class Autotest
511
624
  result = result.nil? ? [] : [result.last.call(filename, $~)].flatten
512
625
 
513
626
  output.puts "No tests matched #{filename}" if
514
- ($v or $TESTING) and result.empty?
627
+ (options[:verbose] or $TESTING) and result.empty?
515
628
 
516
629
  result.sort.uniq.select { |f| known_files[f] }
517
630
  end
@@ -546,7 +659,7 @@ class Autotest
546
659
  # at.files_matching(/^test.*rb$/)
547
660
  # end
548
661
 
549
- def add_mapping(regexp, prepend = false, &proc)
662
+ def add_mapping regexp, prepend = false, &proc
550
663
  if prepend then
551
664
  @test_mappings.unshift [regexp, proc]
552
665
  else
@@ -616,11 +729,11 @@ class Autotest
616
729
 
617
730
  def exceptions
618
731
  unless defined? @exceptions then
619
- if @exception_list.empty? then
620
- @exceptions = nil
621
- else
622
- @exceptions = Regexp.union(*@exception_list)
623
- end
732
+ @exceptions = if @exception_list.empty? then
733
+ nil
734
+ else
735
+ Regexp.union(*@exception_list)
736
+ end
624
737
  end
625
738
 
626
739
  @exceptions
@@ -630,11 +743,17 @@ class Autotest
630
743
  # Hooks:
631
744
 
632
745
  ##
633
- # Call the event hook named +name+, executing all registered hooks
634
- # until one returns true. Returns false if no hook handled the
635
- # event.
746
+ # Call the event hook named +name+, passing in optional args
747
+ # depending on the hook itself.
748
+ #
749
+ # Returns false if no hook handled the event.
750
+ #
751
+ # === Hook Writers!
752
+ #
753
+ # This executes all registered hooks <em>until one returns truthy</em>.
754
+ # Pay attention to the return value of your block!
636
755
 
637
- def hook(name, *args)
756
+ def hook name, *args
638
757
  deprecated = {
639
758
  # none currently
640
759
  }
@@ -643,16 +762,14 @@ class Autotest
643
762
  warn "hook #{name} has been deprecated, use #{deprecated[name]}"
644
763
  end
645
764
 
646
- HOOKS[name].any? do |plugin|
647
- plugin[self, *args]
648
- end
765
+ HOOKS[name].any? { |plugin| plugin[self, *args] }
649
766
  end
650
767
 
651
768
  ##
652
769
  # Add the supplied block to the available hooks, with the given
653
770
  # name.
654
771
 
655
- def self.add_hook(name, &block)
772
+ def self.add_hook name, &block
656
773
  HOOKS[name] << block
657
774
  end
658
775
  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,18 @@
1
+ ##
2
+ # Run autotest with isolate support.
3
+
4
+ module Autotest::Isolate
5
+ @@dir = "tmp/isolate/#{Gem.ruby_engine}-#{RbConfig::CONFIG['ruby_version']}"
6
+
7
+ def self.dir= o
8
+ @@dir = o
9
+ end
10
+
11
+ Autotest.add_hook :initialize do |at|
12
+ ENV["GEM_PATH"] = dir
13
+ ENV["PATH"] += ":#{@@dir}/bin"
14
+
15
+ Gem.clear_paths
16
+ false
17
+ end
18
+ end
@@ -2,10 +2,11 @@ module Autotest::Restart
2
2
  Autotest.add_hook :updated do |at, *args|
3
3
  if args.flatten.include? ".autotest" then
4
4
  warn "Detected change to .autotest, restarting"
5
- cmd = "autotest"
5
+ cmd = %w(autotest)
6
6
  cmd << " -v" if $v
7
-
8
- exec cmd
7
+ cmd += ARGV
8
+
9
+ exec(*cmd)
9
10
  end
10
11
  end
11
12
  end
@@ -7,6 +7,10 @@ class Module
7
7
  end
8
8
  end
9
9
 
10
+ def focus_re regexp
11
+ focus(*public_instance_methods.grep(regexp))
12
+ end
13
+
10
14
  def blur
11
15
  parent = self.superclass
12
16
 
@@ -97,12 +97,10 @@ class UnitDiff
97
97
  footer = data.pop
98
98
 
99
99
  data.map do |result|
100
- break if result.find do |line|
101
- line =~ / expected( but was|, not)/
102
- end
100
+ break if result.any? { |l| l =~ / expected( but was|, not)/ }
103
101
 
104
- header = result.find do |line|
105
- line =~ /^\(?\s*\d+\) (Failure|Error):/
102
+ header = result.find do |l|
103
+ l =~ /^\(?\s*\d+\) (Failure|Error):/
106
104
  end
107
105
 
108
106
  break unless header
@@ -53,7 +53,7 @@ end
53
53
 
54
54
  class ZenTest
55
55
 
56
- VERSION = '4.4.0'
56
+ VERSION = '4.4.1'
57
57
 
58
58
  include ZenTestMapping
59
59
 
@@ -524,10 +524,51 @@ class ZenTest
524
524
  return @result.join("\n")
525
525
  end
526
526
 
527
+ # Provide a certain amount of help.
528
+ def self.usage
529
+ puts <<-EO_USAGE
530
+ usage: #{File.basename $0} [options] test-and-implementation-files...
531
+
532
+ ZenTest scans your target and unit-test code and writes your missing
533
+ code based on simple naming rules, enabling XP at a much quicker
534
+ pace. ZenTest only works with Ruby and Test::Unit.
535
+
536
+ ZenTest uses the following rules to figure out what code should be
537
+ generated:
538
+
539
+ * Definition:
540
+ * CUT = Class Under Test
541
+ * TC = Test Class (for CUT)
542
+ * TC's name is the same as CUT w/ "Test" prepended at every scope level.
543
+ * Example: TestA::TestB vs A::B.
544
+ * CUT method names are used in CT, with "test_" prependend and optional "_ext" extensions for differentiating test case edge boundaries.
545
+ * Example:
546
+ * A::B#blah
547
+ * TestA::TestB#test_blah_normal
548
+ * TestA::TestB#test_blah_missing_file
549
+ * All naming conventions are bidirectional with the exception of test extensions.
550
+
551
+ options:
552
+ -h display this information
553
+ -v display version information
554
+ -r Reverse mapping (ClassTest instead of TestClass)
555
+ -e (Rapid XP) eval the code generated instead of printing it
556
+
557
+ EO_USAGE
558
+ end
559
+
560
+ # Give help, then quit.
561
+ def self.usage_with_exit
562
+ self.usage
563
+ exit 0
564
+ end
565
+
527
566
  # Runs ZenTest over all the supplied files so that
528
567
  # they are analysed and the missing methods have
529
568
  # skeleton code written.
569
+ # If no files are supplied, splutter out some help.
530
570
  def self.fix(*files)
571
+ ZenTest.usage_with_exit if files.empty?
531
572
  zentest = ZenTest.new
532
573
  zentest.scan_files(*files)
533
574
  zentest.analyze
@@ -28,13 +28,7 @@ end
28
28
 
29
29
  class TestAutotest < MiniTest::Unit::TestCase
30
30
 
31
- def deny test, msg=nil
32
- if msg then
33
- assert ! test, msg
34
- else
35
- assert ! test
36
- end
37
- end unless respond_to? :deny
31
+ alias :deny :refute
38
32
 
39
33
  RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) unless defined? RUBY
40
34
 
@@ -288,6 +282,9 @@ Finished in 0.001655 seconds.
288
282
  @a.handle_results(s1)
289
283
  assert_equal empty, @a.files_to_test, "must stay empty"
290
284
 
285
+ exp = { "tests" => 12, "assertions" => 18, "failures" => 0, "errors" => 0 }
286
+ assert_equal exp, @a.latest_results
287
+
291
288
  s2 = "
292
289
  1) Failure:
293
290
  test_fail1(#{@test_class}) [#{@test}:59]:
@@ -305,6 +302,8 @@ test_error2(#{@test_class}):
305
302
  expected = { @test => %w( test_fail1 test_fail2 test_error1 test_error2 ) }
306
303
  assert_equal expected, @a.files_to_test
307
304
  assert @a.tainted
305
+ exp = { "tests" => 12, "assertions" => 18, "failures" => 2, "errors" => 2 }
306
+ assert_equal exp, @a.latest_results
308
307
 
309
308
  @a.handle_results(s1)
310
309
  assert_equal empty, @a.files_to_test
metadata CHANGED
@@ -1,54 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ZenTest
3
3
  version: !ruby/object:Gem::Version
4
- hash: 47
5
4
  prerelease: false
6
5
  segments:
7
6
  - 4
8
7
  - 4
9
- - 0
10
- version: 4.4.0
8
+ - 1
9
+ version: 4.4.1
11
10
  platform: ruby
12
11
  authors:
13
12
  - Ryan Davis
14
13
  - Eric Hodel
15
14
  autorequire:
16
15
  bindir: bin
17
- cert_chain:
18
- - |
19
- -----BEGIN CERTIFICATE-----
20
- MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
21
- ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
22
- GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE
23
- AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
24
- JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
25
- b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
26
- taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT
27
- oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
28
- GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
29
- qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
30
- gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
31
- HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
32
- AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m
33
- vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/
34
- w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0
35
- l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl
36
- n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T
37
- FBHgymkyj/AOSqKRIpXPhjC6
38
- -----END CERTIFICATE-----
16
+ cert_chain: []
39
17
 
40
- date: 2010-09-01 00:00:00 -07:00
18
+ date: 2010-12-01 00:00:00 -08:00
41
19
  default_executable:
42
20
  dependencies:
43
21
  - !ruby/object:Gem::Dependency
44
22
  name: rubyforge
45
23
  prerelease: false
46
24
  requirement: &id001 !ruby/object:Gem::Requirement
47
- none: false
48
25
  requirements:
49
26
  - - ">="
50
27
  - !ruby/object:Gem::Version
51
- hash: 7
52
28
  segments:
53
29
  - 2
54
30
  - 0
@@ -60,32 +36,28 @@ dependencies:
60
36
  name: minitest
61
37
  prerelease: false
62
38
  requirement: &id002 !ruby/object:Gem::Requirement
63
- none: false
64
39
  requirements:
65
40
  - - ">="
66
41
  - !ruby/object:Gem::Version
67
- hash: 11
68
42
  segments:
69
- - 1
70
- - 7
43
+ - 2
44
+ - 0
71
45
  - 0
72
- version: 1.7.0
46
+ version: 2.0.0
73
47
  type: :development
74
48
  version_requirements: *id002
75
49
  - !ruby/object:Gem::Dependency
76
50
  name: hoe
77
51
  prerelease: false
78
52
  requirement: &id003 !ruby/object:Gem::Requirement
79
- none: false
80
53
  requirements:
81
54
  - - ">="
82
55
  - !ruby/object:Gem::Version
83
- hash: 21
84
56
  segments:
85
57
  - 2
86
58
  - 6
87
- - 1
88
- version: 2.6.1
59
+ - 0
60
+ version: 2.6.0
89
61
  type: :development
90
62
  version_requirements: *id003
91
63
  description: |-
@@ -146,6 +118,8 @@ files:
146
118
  - example_dot_autotest.rb
147
119
  - lib/autotest.rb
148
120
  - lib/autotest/autoupdate.rb
121
+ - lib/autotest/bundler.rb
122
+ - lib/autotest/isolate.rb
149
123
  - lib/autotest/once.rb
150
124
  - lib/autotest/rcov.rb
151
125
  - lib/autotest/restart.rb
@@ -172,27 +146,23 @@ rdoc_options:
172
146
  require_paths:
173
147
  - lib
174
148
  required_ruby_version: !ruby/object:Gem::Requirement
175
- none: false
176
149
  requirements:
177
150
  - - ">="
178
151
  - !ruby/object:Gem::Version
179
- hash: 3
180
152
  segments:
181
153
  - 0
182
154
  version: "0"
183
155
  required_rubygems_version: !ruby/object:Gem::Requirement
184
- none: false
185
156
  requirements:
186
157
  - - ">="
187
158
  - !ruby/object:Gem::Version
188
- hash: 3
189
159
  segments:
190
160
  - 0
191
161
  version: "0"
192
162
  requirements: []
193
163
 
194
164
  rubyforge_project: zentest
195
- rubygems_version: 1.3.7
165
+ rubygems_version: 1.3.6
196
166
  signing_key:
197
167
  specification_version: 3
198
168
  summary: "ZenTest provides 4 different tools: zentest, unit_diff, autotest, and multiruby"
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
@@ -1 +0,0 @@
1
- �ж/�Hl5�<����ņsm�8C�����8��9��S�ᷴ�{V���o۳�da�p--������i�#[���55����g�ggԏ�VD��8B������.�3]  ���3�����}�E����Bb�4��F�����g!�T���R��x(�Z�y��~��׶�c�C0LЯ-�Eu>c k�p����ϐ\��/�D�<��yï��zJ���5�.$,6��`�� �c]���F��;ﳎ��H�&<w���