ZenTest 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +22 -0
- data/Manifest.txt +15 -2
- data/README.txt +11 -2
- data/Rakefile +12 -9
- data/bin/ZenTest +1 -1
- data/bin/autotest +37 -2
- data/bin/multiruby +82 -0
- data/bin/zentest +28 -0
- data/lib/autotest.rb +155 -27
- data/lib/rails_autotest.rb +28 -14
- data/lib/unit_diff.rb +4 -1
- data/lib/{ZenTest.rb → zentest.rb} +4 -3
- data/test/data/normal/lib/.#photo.rb +0 -0
- data/test/data/normal/lib/blah.rb +0 -0
- data/test/data/rails/app/controllers/admin/theme_controller.rb +0 -0
- data/test/data/rails/app/controllers/route_controller.rb +0 -0
- data/test/data/rails/app/models/flickr_photo.rb +0 -0
- data/test/data/rails/app/models/route.rb +0 -0
- data/test/data/rails/config/environment.rb +0 -0
- data/test/data/rails/config/routes.rb +0 -0
- data/test/data/rails/test/functional/admin/themes_controller_test.rb +0 -0
- data/test/data/rails/test/functional/dummy_controller_test.rb +0 -0
- data/test/data/rails/test/unit/flickr_photo_test.rb +0 -0
- data/test/data/rails/test/unit/photo_test.rb +0 -0
- data/test/test_autotest.rb +159 -73
- data/test/test_rails_autotest.rb +86 -39
- data/test/test_zentest.rb +6 -4
- metadata +22 -13
data/History.txt
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
*** 3.1.0 / 2006-03-29
|
2
|
+
|
3
|
+
+ 2 major enhancements
|
4
|
+
+ Added multiruby! YAY!
|
5
|
+
+ Massive improvements to autotest: speed, reliability, reporting, etc.
|
6
|
+
+ 10 minor enhancements
|
7
|
+
+ multiruby builds in a centralized location. YAY!
|
8
|
+
+ multiruby now allows reinstalls quickly and easily (can even skip config).
|
9
|
+
+ multiruby exits with total sum of exit codes.
|
10
|
+
+ autotest file search is muuuuch faster.
|
11
|
+
+ autotest automatically detects rails mode.
|
12
|
+
+ autotest deals with rails dependencies much better.
|
13
|
+
+ autotest reruns a full suite after you go green to ensure full coverage.
|
14
|
+
+ autotest always runs with unit_diff -u.
|
15
|
+
+ autotest can now run cvs/svn/p4 up periodically to be a mini-tinderbox.
|
16
|
+
+ autotest now has real help.
|
17
|
+
+ 4 bug fixes
|
18
|
+
- ZenTest is now zentest. Yay for consistency! (do a rake uninstall to clean)
|
19
|
+
- ZenTest excludes pretty_print methods.
|
20
|
+
- Fixed unary operator issues (they were backwards... oops!) for ZenTest.
|
21
|
+
- unit_diff now runs diff.exe on Windoze. dunno if that will work.
|
22
|
+
|
1
23
|
*** 3.0.0 / 2006-03-06
|
2
24
|
|
3
25
|
+ 2 major enhancements
|
data/Manifest.txt
CHANGED
@@ -3,23 +3,36 @@ LinuxJournalArticle.txt
|
|
3
3
|
Manifest.txt
|
4
4
|
README.txt
|
5
5
|
Rakefile
|
6
|
-
bin/ZenTest
|
7
6
|
bin/autotest
|
7
|
+
bin/multiruby
|
8
8
|
bin/unit_diff
|
9
|
+
bin/zentest
|
9
10
|
example.txt
|
10
11
|
example1.rb
|
11
12
|
example2.rb
|
12
|
-
lib/ZenTest.rb
|
13
13
|
lib/autotest.rb
|
14
14
|
lib/rails_autotest.rb
|
15
15
|
lib/unit_diff.rb
|
16
|
+
lib/zentest.rb
|
17
|
+
test/data/normal/lib/.#photo.rb
|
18
|
+
test/data/normal/lib/blah.rb
|
16
19
|
test/data/normal/lib/photo.rb
|
17
20
|
test/data/normal/test/test_camelcase.rb
|
18
21
|
test/data/normal/test/test_photo.rb
|
19
22
|
test/data/normal/test/test_route.rb
|
20
23
|
test/data/normal/test/test_user.rb
|
24
|
+
test/data/rails/app/controllers/admin/theme_controller.rb
|
25
|
+
test/data/rails/app/controllers/route_controller.rb
|
26
|
+
test/data/rails/app/models/flickr_photo.rb
|
27
|
+
test/data/rails/app/models/route.rb
|
28
|
+
test/data/rails/config/environment.rb
|
29
|
+
test/data/rails/config/routes.rb
|
21
30
|
test/data/rails/test/fixtures/routes.yml
|
31
|
+
test/data/rails/test/functional/admin/themes_controller_test.rb
|
32
|
+
test/data/rails/test/functional/dummy_controller_test.rb
|
22
33
|
test/data/rails/test/functional/route_controller_test.rb
|
34
|
+
test/data/rails/test/unit/flickr_photo_test.rb
|
35
|
+
test/data/rails/test/unit/photo_test.rb
|
23
36
|
test/data/rails/test/unit/route_test.rb
|
24
37
|
test/test_autotest.rb
|
25
38
|
test/test_rails_autotest.rb
|
data/README.txt
CHANGED
@@ -18,6 +18,9 @@ autotest is a continous testing facility meant to be used during
|
|
18
18
|
development. As soon as you save a file, autotest will run the
|
19
19
|
corresponding dependent tests.
|
20
20
|
|
21
|
+
multiruby runs anything you want on multiple versions of ruby. Great
|
22
|
+
for compatibility checking!
|
23
|
+
|
21
24
|
There are two strategies intended for ZenTest: test conformance
|
22
25
|
auditing and rapid XP.
|
23
26
|
|
@@ -35,14 +38,20 @@ implementation.
|
|
35
38
|
* Scans your ruby code and tests and generates missing methods for you.
|
36
39
|
* Includes a very helpful filter for Test::Unit output called unit_diff.
|
37
40
|
* Continually and intelligently test only those files you change with autotest.
|
41
|
+
* Test against multiple versions with multiruby.
|
42
|
+
- Not the best doco in the world (my fault)
|
38
43
|
* Includes a LinuxJournal article on testing with ZenTest written by Pat Eyler.
|
44
|
+
* See also: http://blog.zenspider.com/archives/zentest/
|
39
45
|
|
40
46
|
== SYNOPSYS
|
41
47
|
|
42
48
|
ZenTest MyProject.rb TestMyProject.rb > missing.rb
|
43
|
-
|
49
|
+
|
44
50
|
./TestMyProject.rb | unit_diff
|
45
|
-
|
51
|
+
|
52
|
+
autotest
|
53
|
+
|
54
|
+
multiruby ./TestMyProject.rb
|
46
55
|
|
47
56
|
== RULES
|
48
57
|
|
data/Rakefile
CHANGED
@@ -6,8 +6,7 @@ require 'rake/rdoctask'
|
|
6
6
|
require 'rake/gempackagetask'
|
7
7
|
require 'rbconfig'
|
8
8
|
|
9
|
-
|
10
|
-
require 'ZenTest'
|
9
|
+
require './lib/zentest.rb'
|
11
10
|
|
12
11
|
$VERBOSE = nil
|
13
12
|
|
@@ -19,7 +18,7 @@ spec = Gem::Specification.new do |s|
|
|
19
18
|
|
20
19
|
s.files = File.read('Manifest.txt').split($/)
|
21
20
|
s.require_path = 'lib'
|
22
|
-
s.executables = %w[ZenTest unit_diff autotest]
|
21
|
+
s.executables = %w[ZenTest unit_diff autotest multiruby]
|
23
22
|
|
24
23
|
paragraphs = File.read("README.txt").split(/\n\n+/)
|
25
24
|
s.instance_variable_set "@description", paragraphs[3..9].join("\n\n")
|
@@ -55,10 +54,10 @@ end
|
|
55
54
|
desc 'Generate RDoc'
|
56
55
|
Rake::RDocTask.new :rdoc do |rd|
|
57
56
|
rd.rdoc_dir = 'doc'
|
58
|
-
rd.rdoc_files.add 'lib', 'README.txt', 'History.txt',
|
59
|
-
'LinuxJournalArticle.txt'
|
57
|
+
rd.rdoc_files.add 'lib', 'README.txt', 'History.txt', 'LinuxJournalArticle.txt'
|
60
58
|
rd.main = 'README.txt'
|
61
|
-
rd.options << '-d' if `which dot` =~ /\/dot/
|
59
|
+
rd.options << '-d' if `which dot` =~ /\/dot/ unless RUBY_PLATFORM =~ /win32/
|
60
|
+
rd.options << '-t "ZenTest RDoc"'
|
62
61
|
end
|
63
62
|
|
64
63
|
desc 'Build Gem'
|
@@ -69,8 +68,8 @@ end
|
|
69
68
|
$prefix = ENV['PREFIX'] || Config::CONFIG['prefix']
|
70
69
|
$bin = File.join($prefix, 'bin')
|
71
70
|
$lib = Config::CONFIG['sitelibdir']
|
72
|
-
$bins = %w(
|
73
|
-
$libs = %w(
|
71
|
+
$bins = %w(zentest autotest unit_diff multiruby)
|
72
|
+
$libs = %w(zentest.rb autotest.rb rails_autotest.rb unit_diff.rb)
|
74
73
|
|
75
74
|
task :install do
|
76
75
|
$bins.each do |f|
|
@@ -83,6 +82,10 @@ task :install do
|
|
83
82
|
end
|
84
83
|
|
85
84
|
task :uninstall do
|
85
|
+
# add old versions
|
86
|
+
$bins << "ZenTest"
|
87
|
+
$libs << "ZenTest.rb"
|
88
|
+
|
86
89
|
$bins.each do |f|
|
87
90
|
rm_f File.join($bin, f)
|
88
91
|
end
|
@@ -94,5 +97,5 @@ end
|
|
94
97
|
|
95
98
|
desc 'Clean up'
|
96
99
|
task :clean => [ :clobber_rdoc, :clobber_package ] do
|
97
|
-
|
100
|
+
rm_f Dir["**/*~"]
|
98
101
|
end
|
data/bin/ZenTest
CHANGED
data/bin/autotest
CHANGED
@@ -1,8 +1,43 @@
|
|
1
1
|
#!/usr/local/bin/ruby -ws
|
2
2
|
|
3
|
-
$
|
3
|
+
$h ||= false
|
4
|
+
$help ||= false
|
4
5
|
|
5
|
-
if $
|
6
|
+
if $h or $help then
|
7
|
+
help = []
|
8
|
+
help << "autotest [options]"
|
9
|
+
help << nil
|
10
|
+
help << "options:"
|
11
|
+
help << "\t-h"
|
12
|
+
help << "\t-help\t\tYou're looking at it."
|
13
|
+
help << nil
|
14
|
+
help << "\t-v\t\tBe verbose."
|
15
|
+
help << "\t\t\tPrints files that autotest doesn't know how to map to"
|
16
|
+
help << "\t\t\ttests."
|
17
|
+
help << nil
|
18
|
+
help << "\t-rails\t\tForce rails mode."
|
19
|
+
help << "\t\t\tRails will be automatically detected by the presence of"
|
20
|
+
help << "\t\t\tconfig/environment.rb"
|
21
|
+
help << nil
|
22
|
+
help << "\t-vcs=NAME\tVersion control system to update."
|
23
|
+
help << "\t\t\tAutotest will automatically update every vcstime"
|
24
|
+
help << "\t\t\tseconds."
|
25
|
+
help << "\t\t\tAutotest understands Perforce (p4), CVS (cvs) and"
|
26
|
+
help << "\t\t\tSubversion (svn)."
|
27
|
+
help << nil
|
28
|
+
help << "\t-vcstime=N\tUpdate source control every N seconds."
|
29
|
+
help << "\t\t\tDefaults to every five minutes (300 seconds)."
|
30
|
+
STDERR.puts help.join("\n")
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
$v ||= false
|
35
|
+
$rails ||= false
|
36
|
+
$vcs ||= nil
|
37
|
+
$vcstime ||= 300
|
38
|
+
$vcstime = $vcstime.to_i
|
39
|
+
|
40
|
+
if $rails or File.exist? 'config/environment.rb' then
|
6
41
|
require 'rails_autotest'
|
7
42
|
RailsAutotest.run
|
8
43
|
else
|
data/bin/multiruby
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
def run(cmd)
|
6
|
+
puts "Running command: #{cmd}"
|
7
|
+
raise "ERROR: Command failed with exit code #{$?}" unless system cmd
|
8
|
+
end
|
9
|
+
|
10
|
+
root_dir = File.expand_path(ENV['MULTIRUBY'] || File.join(ENV['HOME'], ".multiruby"))
|
11
|
+
unless test ?d, root_dir then
|
12
|
+
puts "creating #{root_dir}"
|
13
|
+
Dir.mkdir root_dir, 0700
|
14
|
+
end
|
15
|
+
|
16
|
+
versions = []
|
17
|
+
Dir.chdir root_dir do
|
18
|
+
%w(build install versions).each do |dir|
|
19
|
+
unless test ?d, dir then
|
20
|
+
puts "creating #{dir}"
|
21
|
+
Dir.mkdir dir
|
22
|
+
if dir == "versions" then
|
23
|
+
file = "ruby-#{RUBY_VERSION}.tar.gz"
|
24
|
+
puts " downloading #{file} via HTTP... this might take a while."
|
25
|
+
puts " Put other ruby tarballs in versions to use them."
|
26
|
+
|
27
|
+
Dir.chdir dir do
|
28
|
+
require 'open-uri'
|
29
|
+
open("http://ftp.ruby-lang.org/pub/ruby/#{file}") do |f|
|
30
|
+
File.open file, 'w' do |out|
|
31
|
+
out.write f.read
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Dir.chdir "build" do
|
40
|
+
Dir["../versions/ruby*.tar.gz"].each do |tarball|
|
41
|
+
build_dir = File.basename tarball, ".tar.gz"
|
42
|
+
version = build_dir.sub(/^ruby-?/, '')
|
43
|
+
versions << version
|
44
|
+
inst_dir = "#{root_dir}/install/#{version}"
|
45
|
+
unless test ?d, inst_dir then
|
46
|
+
unless test ?d, build_dir then
|
47
|
+
puts "creating #{inst_dir}"
|
48
|
+
Dir.mkdir inst_dir
|
49
|
+
puts "unpacking #{tarball}"
|
50
|
+
system "tar zxf #{tarball}"
|
51
|
+
end
|
52
|
+
Dir.chdir build_dir do
|
53
|
+
run "autoconf" unless test ?f, "configure"
|
54
|
+
FileUtils.rm_r "ext/readline" if test ?d, "ext/readline"
|
55
|
+
run "./configure --prefix #{inst_dir} &> log.configure"
|
56
|
+
run "make -j4 &> log.build"
|
57
|
+
run "make install &> log.install"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
results = versions.map do |version|
|
65
|
+
ruby = "#{root_dir}/install/#{version}/bin/ruby"
|
66
|
+
puts
|
67
|
+
puts "VERSION = #{version}"
|
68
|
+
puts
|
69
|
+
system ruby, *ARGV
|
70
|
+
puts
|
71
|
+
puts "RESULT = #{$?}"
|
72
|
+
$?
|
73
|
+
end
|
74
|
+
|
75
|
+
result = results.select { |n| n != 0 }.size
|
76
|
+
|
77
|
+
puts
|
78
|
+
puts "TOTAL RESULT = #{result} failures"
|
79
|
+
|
80
|
+
exit result
|
81
|
+
|
82
|
+
|
data/bin/zentest
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/local/bin/ruby -swI .
|
2
|
+
|
3
|
+
require 'zentest'
|
4
|
+
|
5
|
+
$TESTING = true # for ZenWeb and any other testing infrastructure code
|
6
|
+
|
7
|
+
if defined? $v then
|
8
|
+
puts "#{File.basename $0} v#{ZenTest::VERSION}"
|
9
|
+
exit 0
|
10
|
+
end
|
11
|
+
|
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
|
19
|
+
end
|
20
|
+
|
21
|
+
code = ZenTest.fix(*ARGV)
|
22
|
+
if defined? $e then
|
23
|
+
require 'test/unit'
|
24
|
+
eval code
|
25
|
+
else
|
26
|
+
print code
|
27
|
+
end
|
28
|
+
|
data/lib/autotest.rb
CHANGED
@@ -22,6 +22,17 @@ require 'find'
|
|
22
22
|
# * Implementation files must match up with a test file named
|
23
23
|
# test_.*implementation.rb
|
24
24
|
|
25
|
+
# New (proposed) strategy:
|
26
|
+
#
|
27
|
+
# 1) find all files and associate them from impl <-> test
|
28
|
+
# 2) run all tests
|
29
|
+
# 3) scan for failures
|
30
|
+
# 4) detect changes in ANY (ruby?) file, rerun all failures + changed files
|
31
|
+
# NOTE: this runs in a loop, loop handling should be improved slightly to
|
32
|
+
# have less crap (ruby command, failure count).
|
33
|
+
# 5) until 0 defects, goto 3
|
34
|
+
# 6) when 0 defects, goto 2
|
35
|
+
|
25
36
|
class Autotest
|
26
37
|
|
27
38
|
def self.run
|
@@ -39,20 +50,66 @@ class Autotest
|
|
39
50
|
end
|
40
51
|
|
41
52
|
##
|
42
|
-
#
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
53
|
+
# Consolidates failed tests +failed+ for the same test class into a single
|
54
|
+
# test runner filter. Also maps failed class to its file regexp.
|
55
|
+
|
56
|
+
def consolidate_failures(failed)
|
57
|
+
filters = Hash.new { |h,k| h[k] = [] }
|
58
|
+
|
59
|
+
failed.each do |method, klass|
|
60
|
+
failed_file = klass.sub('Test', '').gsub(/(.)([A-Z])/, '\1_?\2')
|
61
|
+
filters[failed_file.downcase] << method
|
62
|
+
end
|
63
|
+
|
64
|
+
return filters.map do |klass, methods|
|
65
|
+
["'/^(#{methods.join('|')})/'", /#{klass}/]
|
51
66
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
##
|
71
|
+
# Selects test files to run that match failures in +failed_file+ based on
|
72
|
+
# +updated_files+ and +tests+.
|
73
|
+
#
|
74
|
+
# Only test files matching +failed_file+ will be returned so the test
|
75
|
+
# runner's -n flag will correctly match the failed tests.
|
76
|
+
#--
|
77
|
+
# failed_test_files must never check for updated files, retest_failed reuses
|
78
|
+
# +updated_files+.
|
79
|
+
|
80
|
+
def failed_test_files(failed_file, tests, updated_files)
|
81
|
+
return [] if updated_files.empty?
|
82
|
+
|
83
|
+
updated_tests = updated_files.select { |f| f =~ /^test/ }
|
84
|
+
|
85
|
+
tests_to_filter = if updated_files == updated_tests then
|
86
|
+
updated_tests
|
87
|
+
else
|
88
|
+
files = (updated_files + tests).uniq
|
89
|
+
tests_to_filter = map_file_names(files).flatten.uniq
|
90
|
+
end
|
91
|
+
|
92
|
+
return tests_to_filter.select { |test| test =~ failed_file }
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Returns a report of remaining failures in +failures+.
|
97
|
+
|
98
|
+
def failure_report(failed)
|
99
|
+
out = []
|
100
|
+
out << "# failures remain in #{failed.length} files:"
|
101
|
+
failed.each do |filter, failed_test|
|
102
|
+
tests = @files.keys.select { |file| file =~ /^test.*#{failed_test}/ }
|
103
|
+
test = tests.sort_by { |f| f.length }.first
|
104
|
+
|
105
|
+
filter =~ /\((.*)\)/
|
106
|
+
filter = $1.split('|')
|
107
|
+
|
108
|
+
out << "# #{test}:"
|
109
|
+
out << "# #{filter.join "\n# "}"
|
110
|
+
end
|
111
|
+
|
112
|
+
return out.join("\n")
|
56
113
|
end
|
57
114
|
|
58
115
|
##
|
@@ -75,34 +132,61 @@ class Autotest
|
|
75
132
|
when %r%^(doc|pkg)/% then
|
76
133
|
# ignore
|
77
134
|
else
|
78
|
-
STDERR.puts "Dunno! #{filename}"
|
135
|
+
STDERR.puts "Dunno! #{filename}" if $v or $TESTING
|
79
136
|
end
|
80
137
|
end
|
81
138
|
|
82
139
|
return [tests]
|
83
140
|
end
|
84
141
|
|
142
|
+
##
|
143
|
+
# Resets all file timestamps in the list
|
144
|
+
|
145
|
+
def reset_times
|
146
|
+
ago = Time.at 0
|
147
|
+
@files.each_key { |file| @files[file] = ago }
|
148
|
+
end
|
149
|
+
|
85
150
|
##
|
86
151
|
# Retests failed tests.
|
152
|
+
#--
|
153
|
+
# Runs through each failure and runs tests matching the failure. If an
|
154
|
+
# implementation file was updated all failed tests should be run.
|
155
|
+
#
|
156
|
+
# TODO collapse multiple failures in the same file (in test) and use | in
|
157
|
+
# the filter.
|
87
158
|
|
88
159
|
def retest_failed(failed, tests)
|
160
|
+
puts "# Waiting for changes"
|
161
|
+
|
89
162
|
# -t and -n includes all tests that match either filter, not tests that
|
90
163
|
# match both filters, so figure out which TestCase to run from the filename,
|
91
164
|
# and use -n on that.
|
92
165
|
until failed.empty? do
|
93
166
|
sleep 5 unless $TESTING
|
94
167
|
|
95
|
-
|
96
|
-
|
97
|
-
|
168
|
+
updated = updated_files
|
169
|
+
|
170
|
+
# REFACTOR
|
171
|
+
failed.map! do |filter, failed_test|
|
172
|
+
failed_files = failed_test_files failed_test, tests, updated
|
173
|
+
break [filter, failed_test] if failed_files.empty?
|
174
|
+
|
98
175
|
puts "# Rerunning failures: #{failed_files.join ' '}"
|
99
|
-
|
100
|
-
|
176
|
+
|
177
|
+
test_filter = " -n #{filter}" unless filter == "'/^(default_test)/'"
|
178
|
+
cmd = "ruby -Ilib:test #{failed_files.join ' '}#{test_filter} | unit_diff -u"
|
179
|
+
|
101
180
|
puts "+ #{cmd}"
|
102
|
-
|
181
|
+
result = `#{cmd}`
|
182
|
+
puts result
|
183
|
+
status = result.split($/).last
|
184
|
+
rerun = status =~ / 0 failures, 0 errors/ ? nil : [filter, failed_test]
|
185
|
+
puts "# Waiting for changes" if rerun
|
186
|
+
rerun # needed for map!
|
103
187
|
end
|
104
188
|
|
105
|
-
failed.compact!
|
189
|
+
puts failure_report(failed) if failed.compact! and not failed.empty?
|
106
190
|
end
|
107
191
|
end
|
108
192
|
|
@@ -115,6 +199,7 @@ class Autotest
|
|
115
199
|
puts "# Ok, you really want to quit, doing so"
|
116
200
|
exit
|
117
201
|
end
|
202
|
+
# STDERR.puts "\t#{caller.join "\n\t"}"
|
118
203
|
puts "# hit ^C again to quit"
|
119
204
|
sleep 1.5 # give them enough time to hit ^C again
|
120
205
|
@interrupt = true # if they hit ^C again,
|
@@ -122,7 +207,23 @@ class Autotest
|
|
122
207
|
end
|
123
208
|
|
124
209
|
begin
|
210
|
+
last_update = Time.at 0
|
211
|
+
|
125
212
|
loop do
|
213
|
+
if $vcs and Time.now > last_update + $vcstime then
|
214
|
+
last_update = Time.now
|
215
|
+
case $vcs
|
216
|
+
when 'cvs' then
|
217
|
+
system 'cvs up'
|
218
|
+
when 'p4' then
|
219
|
+
system 'p4 sync'
|
220
|
+
when 'svn' then
|
221
|
+
system 'svn up'
|
222
|
+
else
|
223
|
+
puts "# Sorry, I don't know what version control system \"#{$vcs}\" is"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
126
227
|
files = updated_files
|
127
228
|
test files unless files.empty?
|
128
229
|
sleep 5
|
@@ -138,12 +239,16 @@ class Autotest
|
|
138
239
|
##
|
139
240
|
# Runs tests for files in +updated+. Implementation files are looked up
|
140
241
|
# with map_file_names.
|
242
|
+
#
|
243
|
+
# Returns true if any of the tests ever failed.
|
141
244
|
|
142
245
|
def test(updated)
|
246
|
+
ever_failed = false
|
247
|
+
|
143
248
|
map_file_names(updated).each do |tests|
|
144
249
|
next if tests.empty?
|
145
250
|
puts '# Testing updated files'
|
146
|
-
cmd = "ruby -Ilib:test -e '#{tests.inspect}.each { |f| load f }'"
|
251
|
+
cmd = "ruby -Ilib:test -e '#{tests.inspect}.each { |f| load f }' | unit_diff -u"
|
147
252
|
puts "+ #{cmd}"
|
148
253
|
results = `#{cmd}`
|
149
254
|
puts results
|
@@ -153,18 +258,30 @@ class Autotest
|
|
153
258
|
next
|
154
259
|
end
|
155
260
|
|
261
|
+
ever_failed = true
|
262
|
+
|
156
263
|
failed = results.scan(/^\s+\d+\) (?:Failure|Error):\n(.*?)\((.*?)\)/)
|
157
264
|
|
158
265
|
if failed.empty? then
|
159
|
-
puts '# Test::Unit
|
266
|
+
puts '# Test::Unit exited without a parseable failure or error message.'
|
267
|
+
puts '# You probably have a syntax error in your code.'
|
268
|
+
puts '# I\'ll retry in 10 seconds'
|
160
269
|
sleep 10
|
161
270
|
redo
|
162
271
|
end
|
163
272
|
|
273
|
+
failed = consolidate_failures(failed)
|
274
|
+
|
275
|
+
# REFACTOR: I don't think the two routines merit real differences
|
164
276
|
retest_failed failed, tests
|
165
277
|
end
|
166
278
|
|
279
|
+
reset_times if ever_failed
|
280
|
+
|
167
281
|
puts '# All passed'
|
282
|
+
puts "# Waiting for changes"
|
283
|
+
|
284
|
+
return ever_failed
|
168
285
|
end
|
169
286
|
|
170
287
|
##
|
@@ -187,11 +304,22 @@ class Autotest
|
|
187
304
|
updated = []
|
188
305
|
|
189
306
|
Find.find '.' do |f|
|
307
|
+
|
308
|
+
if @exceptions then
|
309
|
+
if f =~ @exceptions then
|
310
|
+
Find.prune if Kernel.test ?d, f
|
311
|
+
next
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
Find.prune if f =~ /(?:\.svn|CVS)$/ # version control files
|
316
|
+
|
190
317
|
next if File.directory? f
|
191
|
-
next if f =~ /(?:swp|~|rej|orig)$/
|
192
|
-
next if f =~
|
193
|
-
|
194
|
-
f = f.sub(/^\.\//, '')
|
318
|
+
next if f =~ /(?:swp|~|rej|orig)$/ # temporary/patch files
|
319
|
+
next if f =~ /\/\.#/ # Emacs autosave/cvs merge files
|
320
|
+
|
321
|
+
f = f.sub(/^\.\//, '')
|
322
|
+
|
195
323
|
updated << f if updated? f
|
196
324
|
end
|
197
325
|
|