ZenTest 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|