ryanbriones-ZenTest 3.11.1

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.
Files changed (70) hide show
  1. data/History.txt +523 -0
  2. data/Manifest.txt +69 -0
  3. data/README.txt +110 -0
  4. data/Rakefile +68 -0
  5. data/articles/Article.css +721 -0
  6. data/articles/getting_started_with_autotest.html +532 -0
  7. data/articles/how_to_use_zentest.txt +393 -0
  8. data/bin/autotest +55 -0
  9. data/bin/multiruby +40 -0
  10. data/bin/multiruby_setup +68 -0
  11. data/bin/rails_test_audit +80 -0
  12. data/bin/unit_diff +38 -0
  13. data/bin/zentest +28 -0
  14. data/example.txt +42 -0
  15. data/example1.rb +7 -0
  16. data/example2.rb +15 -0
  17. data/example_dot_autotest.rb +45 -0
  18. data/lib/autotest.rb +654 -0
  19. data/lib/autotest/autoupdate.rb +26 -0
  20. data/lib/autotest/camping.rb +37 -0
  21. data/lib/autotest/cctray.rb +57 -0
  22. data/lib/autotest/discover.rb +6 -0
  23. data/lib/autotest/emacs.rb +35 -0
  24. data/lib/autotest/email_notify.rb +66 -0
  25. data/lib/autotest/fixtures.rb +12 -0
  26. data/lib/autotest/growl.rb +28 -0
  27. data/lib/autotest/heckle.rb +14 -0
  28. data/lib/autotest/html_report.rb +31 -0
  29. data/lib/autotest/jabber_notify.rb +111 -0
  30. data/lib/autotest/kdenotify.rb +14 -0
  31. data/lib/autotest/menu.rb +51 -0
  32. data/lib/autotest/migrate.rb +7 -0
  33. data/lib/autotest/notify.rb +34 -0
  34. data/lib/autotest/once.rb +9 -0
  35. data/lib/autotest/pretty.rb +83 -0
  36. data/lib/autotest/rails.rb +81 -0
  37. data/lib/autotest/rcov.rb +22 -0
  38. data/lib/autotest/redgreen.rb +21 -0
  39. data/lib/autotest/restart.rb +11 -0
  40. data/lib/autotest/screen.rb +73 -0
  41. data/lib/autotest/shame.rb +45 -0
  42. data/lib/autotest/snarl.rb +51 -0
  43. data/lib/autotest/timestamp.rb +9 -0
  44. data/lib/functional_test_matrix.rb +92 -0
  45. data/lib/multiruby.rb +401 -0
  46. data/lib/test/rails.rb +295 -0
  47. data/lib/test/rails/controller_test_case.rb +382 -0
  48. data/lib/test/rails/functional_test_case.rb +79 -0
  49. data/lib/test/rails/helper_test_case.rb +64 -0
  50. data/lib/test/rails/ivar_proxy.rb +31 -0
  51. data/lib/test/rails/pp_html_document.rb +74 -0
  52. data/lib/test/rails/rake_tasks.rb +50 -0
  53. data/lib/test/rails/render_tree.rb +93 -0
  54. data/lib/test/rails/test_case.rb +28 -0
  55. data/lib/test/rails/view_test_case.rb +597 -0
  56. data/lib/test/zentest_assertions.rb +134 -0
  57. data/lib/unit_diff.rb +259 -0
  58. data/lib/zentest.rb +566 -0
  59. data/lib/zentest_mapping.rb +99 -0
  60. data/test/test_autotest.rb +449 -0
  61. data/test/test_help.rb +36 -0
  62. data/test/test_rails_autotest.rb +229 -0
  63. data/test/test_rails_controller_test_case.rb +58 -0
  64. data/test/test_rails_helper_test_case.rb +48 -0
  65. data/test/test_rails_view_test_case.rb +275 -0
  66. data/test/test_unit_diff.rb +319 -0
  67. data/test/test_zentest.rb +566 -0
  68. data/test/test_zentest_assertions.rb +128 -0
  69. data/test/test_zentest_mapping.rb +222 -0
  70. metadata +151 -0
@@ -0,0 +1,51 @@
1
+ # special thanks to: Patrick Hurley <phurley@gmail.com>
2
+ # requires the ruby-snarl gem.
3
+
4
+ begin require 'rubygems'; rescue LoadError; end
5
+ require 'snarl'
6
+
7
+ module Autotest::Snarl
8
+ def self.icon
9
+ # icons from http://www.famfamfam.com/lab/icons/silk/
10
+ path = File.join(File.dirname(__FILE__), "/../icons")
11
+ {
12
+ :green => "#{path}/accept.png",
13
+ :red => "#{path}/exclamation.png",
14
+ :info => "#{path}/information.png"
15
+ }
16
+ end
17
+
18
+ def self.snarl title, msg, ico = nil
19
+ Snarl.show_message(title, msg, icon[ico])
20
+ end
21
+
22
+ Autotest.add_hook :run do |at|
23
+ snarl "Run", "Run" unless $TESTING
24
+ end
25
+
26
+ Autotest.add_hook :red do |at|
27
+ failed_tests = at.files_to_test.inject(0){ |s,a| k,v = a; s + v.size}
28
+ snarl "Tests Failed", "#{failed_tests} tests failed", :red
29
+ end
30
+
31
+ Autotest.add_hook :green do |at|
32
+ snarl "Tests Passed", "All tests passed", :green #if at.tainted
33
+ end
34
+
35
+ Autotest.add_hook :run do |at|
36
+ snarl "autotest", "autotest was started", :info unless $TESTING
37
+ end
38
+
39
+ Autotest.add_hook :interrupt do |at|
40
+ snarl "autotest", "autotest was reset", :info unless $TESTING
41
+ end
42
+
43
+ Autotest.add_hook :quit do |at|
44
+ snarl "autotest", "autotest is exiting", :info unless $TESTING
45
+ end
46
+
47
+ Autotest.add_hook :all do |at|_hook
48
+ snarl "autotest", "Tests have fully passed", :green unless $TESTING
49
+ end
50
+
51
+ 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,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
data/lib/multiruby.rb ADDED
@@ -0,0 +1,401 @@
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 - show this help.
12
+ # list - print installed versions.
13
+ # update - update svn builds.
14
+ # update:rubygems - update rubygems and nuke install dirs.
15
+ # rubygems:merge - symlink all rubygem dirs to one dir.
16
+ # rm:$version - remove a particular version.
17
+ # clean - clean scm build dirs and remove non-scm build dirs.
18
+ #
19
+ # specs:
20
+ #
21
+ # mri:svn:current - alias for mri:svn:releases and mri:svn:branches.
22
+ # mri:svn:releases - alias for supported releases of mri ruby.
23
+ # mri:svn:branches - alias for active branches of mri ruby.
24
+ # mri:svn:branch:$branch - install a specific $branch of mri from svn.
25
+ # mri:svn:tag:$tag - install a specific $tag of mri from svn.
26
+ # mri:tar:$version - install a specific $version of mri from tarball.
27
+ # rbx:ln:$dir - symlink your rbx $dir
28
+ # rbx:git:current - install rbx from git
29
+ #
30
+ # NOTES:
31
+ #
32
+ # * you can add a symlink to your rubinius build into ~/.multiruby/install
33
+ # * I'll get to adding support for other implementations soon.
34
+ #
35
+ module Multiruby
36
+ MRI_SVN = "http://svn.ruby-lang.org/repos/ruby"
37
+ RBX_GIT = "git://git.rubini.us"
38
+
39
+ TAGS = %w( 1_8_6 1_8_7 1_9 )
40
+ BRANCHES = %w(1_8 1_8_6 1_8_7 trunk)
41
+
42
+ HELP = []
43
+
44
+ File.readlines(__FILE__).each do |line|
45
+ next unless line =~ /^#( |$)/
46
+ HELP << line.sub(/^# ?/, '')
47
+ end
48
+
49
+ def self.build_and_install
50
+ root_dir = self.root_dir
51
+ versions = []
52
+
53
+ Dir.chdir root_dir do
54
+ self.setup_dirs
55
+
56
+ rubygems = Dir["versions/rubygems*.tgz"]
57
+ abort "You should delete all but one rubygem tarball" if rubygems.size > 1
58
+ rubygem_tarball = File.expand_path rubygems.last rescue nil
59
+
60
+ Dir.chdir "build" do
61
+ Dir["../versions/*"].each do |tarball|
62
+ next if tarball =~ /rubygems/
63
+
64
+ build_dir = File.basename tarball, ".tar.gz"
65
+ version = build_dir.sub(/^ruby-?/, '')
66
+ versions << version
67
+ inst_dir = "#{root_dir}/install/#{version}"
68
+
69
+ unless test ?d, inst_dir then
70
+ unless test ?d, build_dir then
71
+ if test ?d, tarball then
72
+ dir = File.basename tarball
73
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
74
+ else
75
+ puts "creating #{inst_dir}"
76
+ Dir.mkdir inst_dir
77
+ run "tar zxf #{tarball}"
78
+ end
79
+ end
80
+ Dir.chdir build_dir do
81
+ puts "building and installing #{version}"
82
+ if test ?f, "configure.in" then
83
+ gnu_utils_build inst_dir
84
+ elsif test ?f, "Rakefile" then
85
+ rake_build inst_dir
86
+ else
87
+ raise "dunno how to build"
88
+ end
89
+
90
+ if rubygem_tarball and version !~ /1[._-]9|mri_trunk|rubinius/ then
91
+ rubygems = File.basename rubygem_tarball, ".tgz"
92
+ run "tar zxf #{rubygem_tarball}" unless test ?d, rubygems
93
+
94
+ Dir.chdir rubygems do
95
+ run "../ruby ./setup.rb --no-rdoc --no-ri &> ../log.rubygems"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ versions
105
+ end
106
+
107
+ def self.clean
108
+ self.each_scm_build_dir do |style|
109
+ case style
110
+ when :svn, :git then
111
+ if File.exist? "Rakefile" then
112
+ run "rake clean"
113
+ elsif File.exist? "Makefile" then
114
+ run "make clean"
115
+ end
116
+ else
117
+ FileUtils.rm_rf Dir.pwd
118
+ end
119
+ end
120
+ end
121
+
122
+ def self.each_scm_build_dir
123
+ Multiruby.in_build_dir do
124
+ Dir["*"].each do |dir|
125
+ next unless File.directory? dir
126
+ Dir.chdir dir do
127
+ if File.exist?(".svn") || File.exist?(".git") then
128
+ scm = File.exist?(".svn") ? :svn : :git
129
+ yield scm
130
+ else
131
+ yield :none
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ def self.extract_latest_version url, matching=nil
139
+ file = URI.parse(url).read
140
+ versions = file.scan(/href="(ruby.*tar.gz)"/).flatten.reject { |s|
141
+ s =~ /preview/
142
+ }.sort_by { |s|
143
+ s.split(/\D+/).map { |i| i.to_i }
144
+ }.flatten
145
+ versions = versions.grep(/#{Regexp.escape(matching)}/) if matching
146
+ versions.last
147
+ end
148
+
149
+ def self.fetch_tar v
150
+ require 'open-uri'
151
+ base_url = "http://ftp.ruby-lang.org/pub/ruby"
152
+
153
+ in_versions_dir do
154
+ warn " Determining latest version for #{v}"
155
+ ver = v[/\d+\.\d+/]
156
+ base = extract_latest_version("#{base_url}/#{ver}/", v)
157
+ abort "Could not determine release for #{v}" unless base
158
+ url = File.join base_url, ver, base
159
+ warn " Fetching #{base} via HTTP... this might take a while."
160
+ open(url) do |f|
161
+ File.open base, 'w' do |out|
162
+ out.write f.read
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def self.git_clone url, dir
169
+ Multiruby.in_versions_dir do
170
+ Multiruby.run "git clone #{url} #{dir}" unless File.directory? dir
171
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
172
+ end
173
+ end
174
+
175
+ def self.gnu_utils_build inst_dir
176
+ run "autoconf" unless test ?f, "configure"
177
+ run "./configure --prefix #{inst_dir} &> log.configure" unless test ?f, "Makefile"
178
+ run "nice make -j4 &> log.build"
179
+ run "make install &> log.install"
180
+ end
181
+
182
+ def self.rake_build inst_dir
183
+ run "rake &> log.build"
184
+ FileUtils.ln_sf "../build/#{File.basename Dir.pwd}", inst_dir
185
+ end
186
+
187
+ def self.help
188
+ puts HELP.join
189
+ end
190
+
191
+ def self.in_build_dir
192
+ Dir.chdir File.join(self.root_dir, "build") do
193
+ yield
194
+ end
195
+ end
196
+
197
+ def self.in_install_dir
198
+ Dir.chdir File.join(self.root_dir, "install") do
199
+ yield
200
+ end
201
+ end
202
+
203
+ def self.in_root_dir
204
+ Dir.chdir self.root_dir do
205
+ yield
206
+ end
207
+ end
208
+
209
+ def self.in_tmp_dir
210
+ Dir.chdir File.join(self.root_dir, "tmp") do
211
+ yield
212
+ end
213
+ end
214
+
215
+ def self.in_versions_dir
216
+ Dir.chdir File.join(self.root_dir, "versions") do
217
+ yield
218
+ end
219
+ end
220
+
221
+ def self.list
222
+ puts "Known versions:"
223
+ in_install_dir do
224
+ Dir["*"].sort.each do |d|
225
+ puts " #{d}"
226
+ end
227
+ end
228
+ end
229
+
230
+ def self.merge_rubygems
231
+ in_install_dir do
232
+ gems = Dir["*/lib/ruby/gems"]
233
+
234
+ unless test ?d, "../gems" then
235
+ FileUtils.mv gems.first, ".."
236
+ end
237
+
238
+ gems.each do |d|
239
+ FileUtils.rm_rf d
240
+ FileUtils.ln_sf "../../../../gems", d
241
+ end
242
+ end
243
+ end
244
+
245
+ def self.mri_latest_tag v
246
+ Multiruby.tags.grep(/#{v}/).last
247
+ end
248
+
249
+ def self.rbx_ln dir
250
+ dir = File.expand_path dir
251
+ Multiruby.in_versions_dir do
252
+ FileUtils.ln_sf dir, "rubinius"
253
+ FileUtils.ln_sf "../versions/rubinius", "../install/rubinius"
254
+ end
255
+ end
256
+
257
+ def self.rm name
258
+ Multiruby.in_root_dir do
259
+ FileUtils.rm_rf Dir["*/#{name}"]
260
+ f = "versions/ruby-#{name}.tar.gz"
261
+ File.unlink f if test ?f, f
262
+ end
263
+ end
264
+
265
+ def self.root_dir
266
+ root_dir = File.expand_path(ENV['MULTIRUBY'] ||
267
+ File.join(ENV['HOME'], ".multiruby"))
268
+
269
+ unless test ?d, root_dir then
270
+ puts "creating #{root_dir}"
271
+ Dir.mkdir root_dir, 0700
272
+ end
273
+
274
+ root_dir
275
+ end
276
+
277
+ def self.run(cmd)
278
+ puts "Running command: #{cmd}"
279
+ raise "ERROR: Command failed with exit code #{$?}" unless system cmd
280
+ end
281
+
282
+ def self.setup_dirs(download = true)
283
+ %w(build install versions tmp).each do |dir|
284
+ unless test ?d, dir then
285
+ puts "creating #{dir}"
286
+ Dir.mkdir dir
287
+ if dir == "versions" && download then
288
+ warn " Downloading initial ruby tarballs to ~/.multiruby/versions:"
289
+ %w(1.8 1.9).each do |v|
290
+ self.fetch_tar v
291
+ end
292
+ warn " ...done"
293
+ warn " Put other ruby tarballs in ~/.multiruby/versions to use them."
294
+ end
295
+ end
296
+ end
297
+ end
298
+
299
+ def self.svn_co url, dir
300
+ Multiruby.in_versions_dir do
301
+ Multiruby.run "svn co #{url} #{dir}" unless File.directory? dir
302
+ FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}"
303
+ end
304
+ end
305
+
306
+ def self.tags
307
+ tags = nil
308
+ Multiruby.in_tmp_dir do
309
+ cache = "svn.tag.cache"
310
+ File.unlink cache if Time.now - File.mtime(cache) > 3600 rescue nil
311
+
312
+ File.open cache, "w" do |f|
313
+ f.write `svn ls #{MRI_SVN}/tags/`
314
+ end unless File.exist? cache
315
+
316
+ tags = File.read(cache).split(/\n/).grep(/^v/).reject {|s| s =~ /preview/}
317
+ end
318
+
319
+ tags = tags.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }
320
+ end
321
+
322
+ def self.update
323
+ # TODO:
324
+ # update will look at the dir name and act accordingly rel_.* will
325
+ # figure out latest tag on that name and svn sw to it trunk and
326
+ # others will just svn update
327
+
328
+ clean = []
329
+
330
+ self.each_scm_build_dir do |style|
331
+ dir = File.basename(Dir.pwd)
332
+ warn dir
333
+
334
+ case style
335
+ when :svn then
336
+ case dir
337
+ when /mri_\d/ then
338
+ system "svn cleanup" # just in case
339
+ svn_up = `svn up`
340
+ in_build_dir do
341
+ if svn_up =~ /^[ADUCG] / then
342
+ clean << dir
343
+ else
344
+ warn " no update"
345
+ end
346
+ FileUtils.ln_sf "../build/#{dir}", "../versions/#{dir}"
347
+ end
348
+ when /mri_rel_(.+)/ then
349
+ ver = $1
350
+ url = `svn info`[/^URL: (.*)/, 1]
351
+ latest = self.mri_latest_tag(ver).chomp('/')
352
+ new_url = File.join(File.dirname(url), latest)
353
+ if new_url != url then
354
+ run "svn sw #{new_url}"
355
+ clean << dir
356
+ else
357
+ warn " no update"
358
+ end
359
+ else
360
+ warn " update in this svn dir not supported yet: #{dir}"
361
+ end
362
+ when :git then
363
+ case dir
364
+ when /rubinius/ then
365
+ run "rake git:update build" # minor cheat by building here
366
+ else
367
+ warn " update in this git dir not supported yet: #{dir}"
368
+ end
369
+ else
370
+ warn " update in non-svn dir not supported yet: #{dir}"
371
+ end
372
+ end
373
+
374
+ in_install_dir do
375
+ clean.each do |dir|
376
+ warn "removing install/#{dir}"
377
+ FileUtils.rm_rf dir
378
+ end
379
+ end
380
+ end
381
+
382
+ def self.update_rubygems
383
+ url = "http://files.rubyforge.rubyuser.de/rubygems/"
384
+ html = URI.parse(url).read
385
+
386
+ versions = html.scan(/href="rubygems-update-(\d+(?:\.\d+)+).gem/).flatten
387
+ latest = versions.sort_by { |s| s.scan(/\d+/).map { |s| s.to_i } }.last
388
+
389
+ Multiruby.in_versions_dir do
390
+ File.unlink(*Dir["rubygems*"])
391
+ file = "rubygems-#{latest}.tgz"
392
+ File.open file, 'w' do |f|
393
+ f.write URI.parse(url+file).read
394
+ end
395
+ end
396
+
397
+ Multiruby.in_install_dir do
398
+ FileUtils.rm_rf Dir["*"]
399
+ end
400
+ end
401
+ end