BanzaiMan-ZenTest 4.2

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.
@@ -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,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,22 @@
1
+ module Autotest::RCov
2
+ @@command, @@pattern = "rcov", "test/*.rb"
3
+
4
+ def self.command= o
5
+ @@command = o
6
+ end
7
+
8
+ def self.pattern= o
9
+ @@pattern = o
10
+ end
11
+
12
+ Autotest.add_hook :all_good do |at|
13
+ system "rake #{@@command} PATTERN=#{@@pattern}"
14
+ end
15
+
16
+ Autotest.add_hook :initialize do |at|
17
+ at.add_exception 'coverage'
18
+ at.add_exception 'coverage.info'
19
+ false
20
+ end
21
+ end
22
+
@@ -0,0 +1,11 @@
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 = "autotest"
6
+ cmd << " -v" if $v
7
+
8
+ exec cmd
9
+ end
10
+ end
11
+ 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,21 @@
1
+ class Module
2
+ def focus *wanteds
3
+ wanteds.map! { |m| m.to_s }
4
+ unwanteds = public_instance_methods(false).grep(/test_/) - wanteds
5
+ unwanteds.each do |unwanted|
6
+ remove_method unwanted
7
+ end
8
+ end
9
+
10
+ def blur
11
+ parent = self.superclass
12
+
13
+ ObjectSpace.each_object Class do |klass|
14
+ next unless parent > klass
15
+ next if klass == self
16
+
17
+ klass.send :focus
18
+ klass.send :undef_method, :default_test
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,92 @@
1
+
2
+ ########################################################################
3
+ # The Idea:
4
+ #
5
+ # This is supposed to get us thinking about the various dimensions our
6
+ # testing should address. If there are states orthogonal to each other
7
+ # (eg. readable vs unreadable, logged in vs not logged in) each of
8
+ # those states should comprise a dimension in the matrix. By
9
+ # addressing it this way, we should be able to minimize the amount of
10
+ # setup/teardown code and get full coverage across our actions for all
11
+ # these edge cases and as a result have extremely clear tests.
12
+ #
13
+ ########################################################################
14
+ # Example Test Matrix Specification:
15
+ #
16
+ # matrix :example, :edge1, :edge2, :edge3, ...
17
+ # action :action1, :OK, :e_NF, :mod, ...
18
+ # action :action2, :OK, :e_RO, :na, ...
19
+ # action ...
20
+ #
21
+ ########################################################################
22
+ # Matrix:
23
+ #
24
+ # I envision the setups being a code that combines the different
25
+ # dimensions of edge case state.
26
+ #
27
+ # Something for a CMS might look like: `[df]_[ugo]_[rRwW]` where:
28
+ #
29
+ # + `[df]` for dir/file.
30
+ # + and the rest is in the style of symbolic args to chmod:
31
+ # + u/g/o = user, group, or other
32
+ # + lowercase `X` == `X`able, uppercase `X` == un`X`able, where `X`
33
+ # is read/write.
34
+ #
35
+ ########################################################################
36
+ # Action:
37
+ #
38
+ # :new/:err/:del are just examples, they should have semantic info
39
+ # attached to them.
40
+ #
41
+ # Use :na to specify an inapplicable edge case for that action.
42
+ #
43
+ # Use :OK to specify the standard positive state. It is equivalent to
44
+ # a result with the same name as the action. (eg
45
+ # matrix_test_index). This cleans up the matrix a lot and allows for
46
+ # narrower and more readable columns.
47
+ #
48
+ # Edge cases specific to an action that fall outside the matrix are
49
+ # regular tests.
50
+ #
51
+ ########################################################################
52
+ # Matrix Methods (the legos):
53
+ #
54
+ # Everything else basically equates to lego pieces:
55
+ #
56
+ # + There is one "init" method per matrix: matrix_init_#{descr}(setup_args)
57
+ # + There is one "setup" method per action: matrix_setup_#{action}(setup, expect)
58
+ # + There is one "test" method per result: matrix_test_#{result}(setup)
59
+ #
60
+ # Thus, for the matrix "example" above, the top left-most test will
61
+ # end up calling:
62
+ #
63
+ # matrix_init_example(:edge1)
64
+ # matrix_setup_action1(:edge1, :new)
65
+ # matrix_test_new(:edge1)
66
+ #
67
+ # Read the action method for exact details.
68
+ ########################################################################
69
+
70
+ module FunctionalTestMatrix
71
+ def matrix(name, *setups)
72
+ @@matrix, @@setups = name, setups
73
+ end
74
+
75
+ def action(action, *results)
76
+ testcases = @@setups.zip(results).reject { |a,b| b == :na }
77
+ testcases = Hash[*testcases.flatten]
78
+ matrix = @@matrix # bind to local scope for define_method closure
79
+
80
+ testcases.each do |setup, expected|
81
+ expected_action = expected == :OK ? action : expected
82
+ define_method "test_#{matrix}_#{action}_#{setup}" do
83
+ @action = action
84
+ send "matrix_init_#{matrix}", *setup.to_s.split(/_/).map {|c| c.intern }
85
+ send "matrix_setup_#{action}", setup, expected
86
+ send "matrix_test_#{expected_action}", setup
87
+ end
88
+ end
89
+ end
90
+
91
+ module_function :matrix, :action
92
+ end
@@ -0,0 +1,472 @@
1
+ require 'fileutils'
2
+ require 'open-uri'
3
+
4
+ ##
5
+ # multiruby_setup is a script to help you manage multiruby.
6
+ #
7
+ # usage: multiruby_setup [-h|cmd|spec...]
8
+ #
9
+ # cmds:
10
+ #
11
+ # -h, --help, help = show this help.
12
+ # build = build and install everything. used internally.
13
+ # clean = clean scm build dirs and remove non-scm build dirs.
14
+ # list = print installed versions.
15
+ # rm:$version = remove a particular version.
16
+ # rubygems:merge = symlink all rubygem dirs to one dir.
17
+ # tags = list all tags from svn.
18
+ # update = update svn builds.
19
+ # update:rubygems = update rubygems and nuke install dirs.
20
+ #
21
+ # specs:
22
+ #
23
+ # the_usual = alias for latest versions from tar + rubygems
24
+ # mri:svn:current = alias for mri:svn:releases and mri:svn:branches.
25
+ # mri:svn:releases = alias for supported releases of mri ruby.
26
+ # mri:svn:branches = alias for active branches of mri ruby.
27
+ # mri:svn:branch:$branch = install a specific $branch of mri from svn.
28
+ # mri:svn:tag:$tag = install a specific $tag of mri from svn.
29
+ # mri:tar:$version = install a specific $version of mri from tarball.
30
+ # rbx:ln:$dir = symlink your rbx $dir
31
+ # rbx:git:current = install rbx from git
32
+ # jruby:git:current = install jruby from git
33
+ # jruby-$version = install a specific $version of jruby
34
+ #
35
+ # environment variables:
36
+ #
37
+ # GEM_URL = url for rubygems tarballs
38
+ # MRI_SVN = url for MRI SVN
39
+ # RBX_GIT = url for rubinius git
40
+ # RUBY_URL = url for MRI tarballs
41
+ # JRUBY_GIT = url for JRuby git
42
+ # JRUBY_URL = url for JRuby tarballs
43
+ # VERSIONS = what versions to install
44
+ #
45
+ # RUBYOPT is cleared on installs.
46
+ #
47
+ # NOTES:
48
+ #
49
+ # * you can add a symlink to your rubinius build into ~/.multiruby/install
50
+ # * I need patches/maintainers for other implementations.
51
+ #
52
+ module Multiruby
53
+ def self.env name, fallback; ENV[name] || fallback; end # :nodoc:
54
+
55
+ TAGS = %w( 1_8_6 1_8_7 1_9_1)
56
+ BRANCHES = %w(1_8 1_8_6 1_8_7 trunk)
57
+
58
+ VERSIONS = env('VERSIONS', TAGS.join(":").gsub(/_/, '.')).split(/:/)
59
+ MRI_SVN = env 'MRI_SVN', 'http://svn.ruby-lang.org/repos/ruby'
60
+ RBX_GIT = env 'RBX_GIT', 'git://github.com/evanphx/rubinius.git'
61
+ RUBY_URL = env 'RUBY_URL', 'http://ftp.ruby-lang.org/pub/ruby'
62
+ GEM_URL = env 'GEM_URL', 'http://files.rubyforge.vm.bytemark.co.uk/rubygems'
63
+ JRUBY_GIT = env 'JRUBY_GIT', 'git://github.com/jruby/jruby.git'
64
+ JRUBY_URL = env 'JRUBY_URL', 'http://dist.codehaus.org/jruby'
65
+
66
+ HELP = []
67
+
68
+ File.readlines(__FILE__).each do |line|
69
+ next unless line =~ /^#( |$)/
70
+ HELP << line.sub(/^# ?/, '')
71
+ end
72
+
73
+ def self.build_and_install
74
+ ENV.delete 'RUBYOPT'
75
+
76
+ root_dir = self.root_dir
77
+ versions = []
78
+
79
+ Dir.chdir root_dir do
80
+ self.setup_dirs
81
+
82
+ rubygems = Dir["versions/rubygems*.tgz"]
83
+ abort "You should delete all but one rubygem tarball" if rubygems.size > 1
84
+ rubygem_tarball = File.expand_path rubygems.last rescue nil
85
+
86
+ Dir.chdir "build" do
87
+ Dir["../versions/*"].sort.each do |tarball|
88
+ next if tarball =~ /rubygems/
89
+
90
+ build_dir = File.basename tarball, ".tar.gz"
91
+ build_dir.sub!(/-bin/,'') # e.g., jruby-bin-1.3.1.tar.gz
92
+ version = build_dir.sub(/^ruby-?/, '')
93
+ versions << version
94
+ inst_dir = "#{root_dir}/install/#{version}"
95
+
96
+ unless test ?d, inst_dir then
97
+ unless test ?d, build_dir then
98
+ if test ?d, tarball then
99
+ dir = File.basename tarball
100
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
101
+ else
102
+ puts "creating #{inst_dir}"
103
+ Dir.mkdir inst_dir
104
+ run "tar zxf #{tarball}"
105
+ end
106
+ end
107
+ Dir.chdir build_dir do
108
+ puts "building and installing #{version}"
109
+ if test ?f, "configure.in" then
110
+ gnu_utils_build inst_dir
111
+ elsif test ?f, "Rakefile" then
112
+ rake_build inst_dir
113
+ elsif version =~ /jruby/
114
+ # git master should have built JRuby with 'Rakefile' above,
115
+ # and there is no need to build expanded jruby-bin tarball
116
+ FileUtils.ln_sf build_dir, inst_dir
117
+ else
118
+ raise "dunno how to build"
119
+ end
120
+
121
+ if rubygem_tarball and version !~ /1[._-]9|mri_trunk|rubinius/ then
122
+ rubygems = File.basename rubygem_tarball, ".tgz"
123
+ run "tar zxf #{rubygem_tarball}" unless test ?d, rubygems
124
+
125
+ Dir.chdir rubygems do
126
+ run "../ruby ./setup.rb --no-rdoc --no-ri", "../log.rubygems"
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ versions
136
+ end
137
+
138
+ def self.clean
139
+ self.each_scm_build_dir do |style|
140
+ case style
141
+ when :svn, :git then
142
+ if File.exist? "Rakefile" then
143
+ run "rake clean"
144
+ elsif File.exist? "Makefile" then
145
+ run "make clean"
146
+ end
147
+ else
148
+ FileUtils.rm_rf Dir.pwd
149
+ end
150
+ end
151
+ end
152
+
153
+ def self.each_scm_build_dir
154
+ Multiruby.in_build_dir do
155
+ Dir["*"].each do |dir|
156
+ next unless File.directory? dir
157
+ Dir.chdir dir do
158
+ if File.exist?(".svn") || File.exist?(".git") then
159
+ scm = File.exist?(".svn") ? :svn : :git
160
+ yield scm
161
+ else
162
+ yield :none
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ def self.extract_latest_version url, matching=nil
170
+ file = URI.parse(url).read
171
+ versions = file.scan(/href="(j?ruby.*tar.gz)"/).flatten.reject { |s|
172
+ s =~ /preview|-rc\d|src/
173
+ }.sort_by { |s|
174
+ s.split(/\D+/).map { |i| i.to_i }
175
+ }.flatten
176
+ versions = versions.grep(/#{Regexp.escape(matching)}/) if matching
177
+ versions.last
178
+ end
179
+
180
+ def self.fetch_tar v, base_url = RUBY_URL
181
+ in_versions_dir do
182
+ warn " Determining latest version for #{v}"
183
+ case base_url
184
+ when RUBY_URL
185
+ ver = v[/\d+\.\d+/]
186
+ when JRUBY_URL
187
+ ver = v[/\d+\.\d+\.\d+/]
188
+ else
189
+ warn "Unknown URL #{base_url}"
190
+ end
191
+ base = extract_latest_version("#{base_url}/#{ver}/", v)
192
+ abort "Could not determine release for #{v}" unless base
193
+ url = File.join base_url, ver, base
194
+ unless File.file? base then
195
+ warn " Fetching #{base} via HTTP... this might take a while."
196
+ open(url) do |f|
197
+ File.open base, 'w' do |out|
198
+ out.write f.read
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ def self.git_clone url, dir
206
+ Multiruby.in_versions_dir do
207
+ Multiruby.run "git clone #{url} #{dir}" unless File.directory? dir
208
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
209
+ end
210
+ end
211
+
212
+ def self.gnu_utils_build inst_dir
213
+ run "autoconf" unless test ?f, "configure"
214
+ run "./configure --enable-shared --prefix #{inst_dir}", "log.configure" unless
215
+ test ?f, "Makefile"
216
+ run "(nice make -j4; nice make)", "log.build"
217
+ run "make install", "log.install"
218
+ end
219
+
220
+ def self.help
221
+ puts HELP.join
222
+ end
223
+
224
+ def self.in_build_dir
225
+ Dir.chdir File.join(self.root_dir, "build") do
226
+ yield
227
+ end
228
+ end
229
+
230
+ def self.in_install_dir
231
+ Dir.chdir File.join(self.root_dir, "install") do
232
+ yield
233
+ end
234
+ end
235
+
236
+ def self.in_root_dir
237
+ Dir.chdir self.root_dir do
238
+ yield
239
+ end
240
+ end
241
+
242
+ def self.in_tmp_dir
243
+ Dir.chdir File.join(self.root_dir, "tmp") do
244
+ yield
245
+ end
246
+ end
247
+
248
+ def self.in_versions_dir
249
+ Dir.chdir File.join(self.root_dir, "versions") do
250
+ yield
251
+ end
252
+ end
253
+
254
+ def self.list
255
+ puts "Known versions:"
256
+ in_install_dir do
257
+ Dir["*"].sort.each do |d|
258
+ puts " #{d}"
259
+ end
260
+ end
261
+ end
262
+
263
+ def self.merge_rubygems
264
+ in_install_dir do
265
+ gems = Dir["*/lib/ruby/gems"]
266
+
267
+ unless test ?d, "../gems" then
268
+ FileUtils.mv gems.first, ".."
269
+ end
270
+
271
+ gems.each do |d|
272
+ FileUtils.rm_rf d
273
+ FileUtils.ln_sf "../../../../gems", d
274
+ end
275
+ end
276
+ end
277
+
278
+ def self.mri_latest_tag v
279
+ Multiruby.tags.grep(/#{v}/).last
280
+ end
281
+
282
+ def self.rake_build inst_dir
283
+ run "rake", "log.build"
284
+ FileUtils.ln_sf "../build/#{File.basename Dir.pwd}", inst_dir
285
+ end
286
+
287
+ def self.rbx_ln dir
288
+ dir = File.expand_path dir
289
+ Multiruby.in_versions_dir do
290
+ FileUtils.ln_sf dir, "rubinius"
291
+ FileUtils.ln_sf "../versions/rubinius", "../install/rubinius"
292
+ end
293
+ end
294
+
295
+ def self.rm name
296
+ Multiruby.in_root_dir do
297
+ FileUtils.rm_rf Dir["*/#{name}"]
298
+ f = "versions/ruby-#{name}.tar.gz"
299
+ File.unlink f if test ?f, f
300
+ end
301
+ end
302
+
303
+ def self.root_dir
304
+ root_dir = File.expand_path(ENV['MULTIRUBY'] ||
305
+ File.join(ENV['HOME'], ".multiruby"))
306
+
307
+ unless test ?d, root_dir then
308
+ puts "creating #{root_dir}"
309
+ Dir.mkdir root_dir, 0700
310
+ end
311
+
312
+ root_dir
313
+ end
314
+
315
+ def self.run base_cmd, log = nil
316
+ cmd = base_cmd
317
+ cmd += " > #{log} 2>&1" if log
318
+ puts "Running command: #{cmd}"
319
+ raise "ERROR: Command failed with exit code #{$?}" unless system cmd
320
+ end
321
+
322
+ def self.setup_dirs download = true
323
+ %w(build install versions tmp).each do |dir|
324
+ unless test ?d, dir then
325
+ puts "creating #{dir}"
326
+ Dir.mkdir dir
327
+ if dir == "versions" && download then
328
+ warn " Downloading initial ruby tarballs to ~/.multiruby/versions:"
329
+ VERSIONS.each do |v|
330
+ self.fetch_tar v
331
+ end
332
+ warn " ...done"
333
+ warn " Put other ruby tarballs in ~/.multiruby/versions to use them."
334
+ end
335
+ end
336
+ end
337
+ end
338
+
339
+ def self.svn_co url, dir
340
+ Multiruby.in_versions_dir do
341
+ Multiruby.run "svn co #{url} #{dir}" unless File.directory? dir
342
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
343
+ end
344
+ end
345
+
346
+ def self.git_co repo, tag
347
+ Multiruby.in_versions_dir do
348
+ Dir.chdir repo do
349
+ Multiruby.run "git checkout #{tag}"
350
+ unless File.directory? "../../versions/#{repo}-#{tag}"
351
+ FileUtils.cp_r "../../versions/#{repo}", "../../versions/#{repo}-#{tag}"
352
+ FileUtils.ln_sf "../../versions/#{repo}-#{tag}", "../../build/#{repo}-#{tag}"
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ def self.git_co_master repo
359
+ Multiruby.in_versions_dir do
360
+ Dir.chdir repo do
361
+ Multiruby.run "git checkout master"
362
+ end
363
+ end
364
+ end
365
+
366
+ def self.tags(scm="svn")
367
+ tags = nil
368
+ Multiruby.in_tmp_dir do
369
+ cache = "#{scm}.tag.cache"
370
+ File.unlink cache if Time.now - File.mtime(cache) > 3600 rescue nil
371
+
372
+ File.open cache, "w" do |f|
373
+ case scm
374
+ when "svn" then
375
+ f.write `svn ls #{MRI_SVN}/tags/`
376
+ when "git" then
377
+ f.write `git tag`
378
+ else
379
+ warn "Unsupported SCM: #{scm}"
380
+ end
381
+ end unless File.exist? cache
382
+
383
+ tags = File.read(cache).split(/\n/).grep(/^v/).reject {|s| s =~ /preview/}
384
+ end
385
+
386
+ tags = tags.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }
387
+ end
388
+
389
+ def self.update
390
+ # TODO:
391
+ # update will look at the dir name and act accordingly rel_.* will
392
+ # figure out latest tag on that name and svn sw to it trunk and
393
+ # others will just svn update
394
+
395
+ clean = []
396
+
397
+ self.each_scm_build_dir do |style|
398
+ dir = File.basename(Dir.pwd)
399
+ warn dir
400
+
401
+ case style
402
+ when :svn then
403
+ case dir
404
+ when /mri_\d/ then
405
+ system "svn cleanup" # just in case
406
+ svn_up = `svn up`
407
+ in_build_dir do
408
+ if svn_up =~ /^[ADUCG] / then
409
+ clean << dir
410
+ else
411
+ warn " no update"
412
+ end
413
+ FileUtils.ln_sf "../build/#{dir}", "../versions/#{dir}"
414
+ end
415
+ when /mri_rel_(.+)/ then
416
+ ver = $1
417
+ url = `svn info`[/^URL: (.*)/, 1]
418
+ latest = self.mri_latest_tag(ver).chomp('/')
419
+ new_url = File.join(File.dirname(url), latest)
420
+ if new_url != url then
421
+ run "svn sw #{new_url}"
422
+ clean << dir
423
+ else
424
+ warn " no update"
425
+ end
426
+ else
427
+ warn " update in this svn dir not supported yet: #{dir}"
428
+ end
429
+ when :git then
430
+ case dir
431
+ when /rubinius|jruby/ then
432
+ run "git pull", nil
433
+ run "rake build" # minor cheat by building here
434
+ else
435
+ warn " update in this git dir not supported yet: #{dir}"
436
+ end
437
+ else
438
+ warn " update in non-svn dir not supported yet: #{dir}"
439
+ end
440
+ end
441
+
442
+ in_install_dir do
443
+ clean.each do |dir|
444
+ warn "removing install/#{dir}"
445
+ FileUtils.rm_rf dir
446
+ end
447
+ end
448
+ end
449
+
450
+ def self.update_rubygems
451
+ warn " Determining latest version for rubygems"
452
+ html = URI.parse(GEM_URL).read
453
+
454
+ versions = html.scan(/href="rubygems-update-(\d+(?:\.\d+)+).gem/i).flatten
455
+ latest = versions.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }.last
456
+
457
+ Multiruby.in_versions_dir do
458
+ file = "rubygems-#{latest}.tgz"
459
+ unless File.file? file then
460
+ warn " Fetching rubygems-#{latest}.tgz via HTTP."
461
+ File.unlink(*Dir["rubygems*"])
462
+ File.open file, 'w' do |f|
463
+ f.write URI.parse(GEM_URL+"/"+file).read
464
+ end
465
+ end
466
+ end
467
+
468
+ Multiruby.in_install_dir do
469
+ FileUtils.rm_rf Dir["*"]
470
+ end
471
+ end
472
+ end