ZenTest-4.11.0/0000755000004100000410000000000012432322455013223 5ustar www-datawww-dataZenTest-4.11.0/Rakefile0000444000004100000410000000225312432322455014670 0ustar www-datawww-data# -*- ruby -*- $LOAD_PATH << 'lib' require 'rubygems' require 'hoe' Hoe.add_include_dirs("../../minitest/dev/lib") Hoe.plugin :seattlerb Hoe.spec "ZenTest" do developer 'Ryan Davis', 'ryand-ruby@zenspider.com' developer 'Eric Hodel', 'drbrain@segment7.net' require_rubygems_version [">= 1.8", "< 3.0"] end desc "run autotest on itself" task :autotest do ruby "-Ilib -w ./bin/autotest" end desc "update example_dot_autotest.rb with all possible constants" task :update do system "p4 edit example_dot_autotest.rb" File.open "example_dot_autotest.rb", "w" do |f| f.puts "# -*- ruby -*-" f.puts Dir.chdir "lib" do Dir["autotest/*.rb"].sort.each do |s| next if s =~ /rails|discover/ f.puts "# require '#{s[0..-4]}'" end end f.puts Dir["lib/autotest/*.rb"].sort.each do |file| file = File.read(file) m = file[/module.*/].split(/ /).last rescue nil next unless m file.grep(/def[^(]+=/).each do |setter| setter = setter.sub(/^ *def self\./, '').sub(/\s*=\s*/, ' = ') f.puts "# #{m}.#{setter}" end end end system "p4 diff -du example_dot_autotest.rb" end # vim:syntax=ruby ZenTest-4.11.0/.gemtest0000644000004100000410000000000012432322455014662 0ustar www-datawww-dataZenTest-4.11.0/bin/0000755000004100000410000000000012432322455013773 5ustar www-datawww-dataZenTest-4.11.0/bin/unit_diff0000555000004100000410000000141112432322455015663 0ustar www-datawww-data#!/usr/bin/env ruby -ws # # unit_diff - a ruby unit test filter by Ryan Davis # # usage: # # test.rb | unit_diff [options] # options: # -b ignore whitespace differences # -c contextual diff # -h show usage # -k keep temp diff files around # -u unified diff [default] # -p plain diff # -v display version require 'unit_diff' require 'zentest' ############################################################ if defined? $v then puts "#{File.basename $0} v. #{ZenTest::VERSION}" exit 0 end if defined? $h then File.open(__FILE__) do |f| begin; end until f.readline =~ /usage:/ f.readline while line = f.readline and line.sub!(/^# ?/, '') $stderr.puts line end end exit 0 end UnitDiff.unit_diff ZenTest-4.11.0/bin/autotest0000555000004100000410000000012412432322455015564 0ustar www-datawww-data#!/usr/bin/env ruby require 'autotest' Autotest.parse_options Autotest.runner.run ZenTest-4.11.0/bin/multigem0000555000004100000410000000007612432322455015545 0ustar www-datawww-data#!/usr/bin/env ruby -w exec "multiruby", "-S", "gem", *ARGV ZenTest-4.11.0/bin/multiruby0000555000004100000410000000314712432322455015760 0ustar www-datawww-data#!/usr/bin/env ruby -w require 'multiruby' root_dir = Multiruby.root_dir def setenv dir bin = "#{dir}/bin" gem = Dir["#{dir}/lib/ruby/gems/*"].first ENV['PATH'] = bin + File::PATH_SEPARATOR + ENV['PATH'] ENV['GEM_HOME'] = gem ENV['GEM_PATH'] = gem end ## # multiruby -1 1.8.7 ruby_args... if ARGV.first == "-1" then ARGV.shift vers = Dir["#{root_dir}/install/#{ARGV.shift}*"] abort "ambiguous version: #{vers.map { |p| File.basename p }.inspect}" if vers.size != 1 dir = vers.first setenv dir exec "#{dir}/bin/ruby", *ARGV end versions = Multiruby.build_and_install versions = ENV['VERSIONS'].split(/:/) if ENV.has_key? 'VERSIONS' if ENV.has_key? 'EXCLUDED_VERSIONS' then excludes = Regexp.union(*ENV['EXCLUDED_VERSIONS'].split(/:/)) versions = versions.delete_if { |v| v =~ excludes } end # safekeep original PATH original_path = ENV['PATH'] results = {} versions.each do |version| dir = "#{root_dir}/install/#{version}" ruby = "#{dir}/bin/ruby" ruby.sub!(/bin.ruby/, 'bin/rbx') if version =~ /rubinius/ puts puts "VERSION = #{version}" cmd = [ruby, ARGV].flatten.map { |s| s =~ /\"/ ? "'#{s}'" : s }.join(' ') cmd.sub!(/#{ENV['HOME']}/, '~') puts "CMD = #{cmd}" puts setenv dir system ruby, *ARGV puts puts "RESULT = #{$?}" results[version] = $? # restore the path to original state ENV['PATH'] = original_path end passed, failed = results.keys.partition { |v| results[v] == 0 } puts puts "TOTAL RESULT = #{failed.size} failures out of #{results.size}" puts puts "Passed: #{passed.join(", ")}" puts "Failed: #{failed.join(", ")}" exit failed.size ZenTest-4.11.0/bin/multiruby_setup0000555000004100000410000000376012432322455017201 0ustar www-datawww-data#!/usr/bin/env ruby -w require 'multiruby' ENV.delete 'RUBYOPT' ARGV << "help" if ARGV.empty? Dir.chdir Multiruby.root_dir Multiruby.setup_dirs(false) ARGV.each do |spec| case spec when "-h", "--help", "help" then Multiruby.help exit 0 when "the_usual" then # TODO: update #help ARGV.push(*Multiruby::TAGS.map { |v| "mri:tar:#{v.gsub(/_/, '.')}" }) ARGV << "build" << "update:rubygems" system "multigem install --no-ri --no-rdoc rake minitest ZenTest gemcutter rubyforge hoe" when "build" then Multiruby.build_and_install when "clean" then Multiruby.clean when "list" then Multiruby.list when /rm:(.*)/ then Multiruby.rm $1 when "rubygems:merge" then Multiruby.merge_rubygems when "rubygems:update", "update:rubygems" then Multiruby.update_rubygems ARGV << "build" when "update" then Multiruby.update when "tags" then p Multiruby.tags when "mri:svn:current" then ARGV << "mri:svn:releases" << "mri:svn:branches" << "build" when "mri:svn:releases" then Multiruby::TAGS.each do |v| latest = Multiruby.mri_latest_tag v abort "Can't find tag #{v}" unless latest ARGV << "mri:svn:tag:#{latest}:mri_rel_#{v}" end ARGV << "build" when /mri:svn:branch:(.*)/ then ver = "branches/ruby_#{$1}" unless ver == "trunk" Multiruby.svn_co "#{Multiruby::MRI_SVN}/#{$1}", "mri_#{$1}" ARGV << "build" when "mri:svn:branches" then Multiruby::BRANCHES.each do |v| ARGV << "mri:svn:branch:#{v}" end ARGV << "build" when /mri:svn:tag:(.*):(.*)/ then Multiruby.svn_co "#{Multiruby::MRI_SVN}/tags/#{$1}", $2 ARGV << "build" when /mri:svn:tag:(.*)/ then ARGV << "mri:svn:tag:#{$1}:#{$1}" << "build" when /mri:list:(.*)/ then v = $1 ver = v[/\d+\.\d+/] url = "#{Multiruby::RUBY_URL}/#{ver}/" puts Multiruby.matching_versions(url, v).join("\n") when /mri:tar:(.*)/ then Multiruby.fetch_tar $1 ARGV << "build" else warn "unknown spec #{spec}" end end ZenTest-4.11.0/bin/zentest0000555000004100000410000000054512432322455015417 0ustar www-datawww-data#!/usr/bin/env ruby -swI . require 'zentest' $TESTING = true # for ZenWeb and any other testing infrastructure code if defined? $v then puts "#{File.basename $0} v#{ZenTest::VERSION}" exit 0 end if defined? $h then ZenTest.usage_with_exit end code = ZenTest.fix(*ARGV) if defined? $e then require 'test/unit' eval code else print code end ZenTest-4.11.0/Manifest.txt0000444000004100000410000000133612432322455015533 0ustar www-datawww-data.autotest History.txt Manifest.txt README.txt Rakefile articles/Article.css articles/getting_started_with_autotest.html articles/how_to_use_zentest.txt bin/autotest bin/multigem bin/multiruby bin/multiruby_setup bin/unit_diff bin/zentest example.txt example1.rb example2.rb example_dot_autotest.rb lib/autotest.rb lib/autotest/autoupdate.rb lib/autotest/bundler.rb lib/autotest/isolate.rb lib/autotest/once.rb lib/autotest/preload.rb lib/autotest/rcov.rb lib/autotest/restart.rb lib/autotest/timestamp.rb lib/focus.rb lib/functional_test_matrix.rb lib/multiruby.rb lib/unit_diff.rb lib/zentest.rb lib/zentest_mapping.rb test/test_autotest.rb test/test_focus.rb test/test_unit_diff.rb test/test_zentest.rb test/test_zentest_mapping.rb ZenTest-4.11.0/.autotest0000444000004100000410000000061512432322455015074 0ustar www-datawww-data# -*- ruby -*- require 'autotest/restart' Autotest.add_hook :initialize do |at| at.add_exception 'coverage' at.add_exception 'coverage.info' at.libs << ':../../minitest/dev/lib' at.testlib = ".minitest" %w(TestZenTest).each do |klass| at.extra_class_map[klass] = "test/test_zentest.rb" end end Autotest.add_hook :all_good do |at| system "rake rcov_info" end if ENV['RCOV'] ZenTest-4.11.0/README.txt0000444000004100000410000001211412432322455014716 0ustar www-datawww-data= ZenTest home :: https://github.com/seattlerb/zentest rdoc :: http://docs.seattlerb.org/ZenTest == DESCRIPTION ZenTest provides 4 different tools: zentest, unit_diff, autotest, and multiruby. zentest scans your target and unit-test code and writes your missing code based on simple naming rules, enabling XP at a much quicker pace. zentest only works with Ruby and Minitest or Test::Unit. There is enough evidence to show that this is still proving useful to users, so it stays. unit_diff is a command-line filter to diff expected results from actual results and allow you to quickly see exactly what is wrong. Do note that minitest 2.2+ provides an enhanced assert_equal obviating the need for unit_diff autotest is a continous testing facility meant to be used during development. As soon as you save a file, autotest will run the corresponding dependent tests. multiruby runs anything you want on multiple versions of ruby. Great for compatibility checking! Use multiruby_setup to manage your installed versions. == FEATURES * Scans your ruby code and tests and generates missing methods for you. * Includes a very helpful filter for Test/Spec output called unit_diff. * Continually and intelligently test only those files you change with autotest. * Test against multiple versions with multiruby. * Includes a LinuxJournal article on testing with ZenTest written by Pat Eyler. * See also: http://blog.zenspider.com/archives/zentest/ * See also: http://blog.segment7.net/articles/category/zentest == STRATEGERY There are two strategeries intended for ZenTest: test conformance auditing and rapid XP. For auditing, ZenTest provides an excellent means of finding methods that have slipped through the testing process. I've run it against my own software and found I missed a lot in a well tested package. Writing those tests found 4 bugs I had no idea existed. ZenTest can also be used to evaluate generated code and execute your tests, allowing for very rapid development of both tests and implementation. == AUTOTEST TIPS Setting up your project with a custom setup is easily done by creating a ".autotest" file in your project. Here is an example of adding some plugins, using minitest as your test library, and running rcov on full passes: require 'autotest/restart' Autotest.add_hook :initialize do |at| at.testlib = "minitest/autorun" end Autotest.add_hook :all_good do |at| system "rake rcov_info" end if ENV['RCOV'] Do note, since minitest ships with ruby19, if you want to use the latest minitest gem you need to ensure that the gem activation occurs! To do this, add the gem activation and the proper require to a separate file (like ".minitest.rb" or even a test helper if you have one) and use that for your testlib instead: .minitest.rb: gem "minitest" require "minitest/autorun" .autotest: Autotest.add_hook :initialize do |at| at.testlib = ".minitest" end If you prefer to suffix test files with "_test.rb" (instead of the default which prefixes test files with "test_") you can change the mapping by installing the autotest-suffix plugin. To do this first install the autotest-suffix gem: $ gem install autotest-suffix Then add the following to the ".autotest" file: require "autotest/suffix" If you prefer minitest/spec to minitest/unit, you can still use autotest by installing the autotest-spec plugin. To do this first install the autotest-spec gem: $ gem install autotest-spec Then add the following to the ".autotest" file: require "autotest/spec" == SYNOPSIS ZenTest MyProject.rb TestMyProject.rb > missing.rb ./TestMyProject.rb | unit_diff autotest multiruby_setup mri:svn:current multiruby ./TestMyProject.rb == Windows and Color Read this: http://blog.mmediasys.com/2010/11/24/we-all-love-colors/ == REQUIREMENTS * Ruby 1.8+, JRuby 1.1.2+, or rubinius * A test/spec framework of your choice. * Hoe (development) * rubygems, 1.8+ * diff.exe on windows. Use http://gnuwin32.sourceforge.net/packages.html == INSTALL * sudo gem install ZenTest == LICENSE (The MIT License) Copyright (c) Ryan Davis, Eric Hodel, seattle.rb Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ZenTest-4.11.0/example2.rb0000444000004100000410000000047512432322455015271 0ustar www-datawww-datamodule TestSomething class TestThingy def test_do_something_normal thingy = Thingy.new result = thingy.do_something assert(result.blahblah) end def test_do_something_edgecase thingy = Thingy.new result = thingy.do_something assert(result.blahblah) end end end ZenTest-4.11.0/data.tar.gz.sig0000444000004100000410000000040012432322455016034 0ustar www-datawww-data5dl{ In)ԋ&9#1_BZ-cP}"[|tټInb:5{ᭋ{.8wh;NJ^MF5䍐LlS)J#]+b^|+Cn$:V۫;S3TJ5O,}V ĭE2iP l}+WQxTI5 {RpLFttC;|JJ3CqZenTest-4.11.0/example.txt0000444000004100000410000000154112432322455015416 0ustar www-datawww-data What do we do to get people writing tests? What do we do to get people writing tests first? I didn't know it's name, but apparently it's the Lettuce Principal, (see http://blog.toolshed.com/2003/03/the_lettuce_pri.html). We NEED to make testing as easy as possible to get them testing. Class Under Test Test Class ###################################################################### module Something module TestSomething class Thingy class TestThingy def do_something def test_do_something_normal # ... thingy = Thingy.new end result = thingy.do_something end assert(result.blahblah) end end def test_do_something_edgecase thingy = Thingy.new result = thingy.do_something assert(result.blahblah) end end end ZenTest-4.11.0/History.txt0000444000004100000410000007152712432322455015437 0ustar www-datawww-data=== 4.11.0 / 2014-09-26 * 1 minor enhancement: * Rearranged died hook so user can bypass default. (bhenderson) * 1 bug fix: * Fixed rubyforge urls. === 4.10.1 / 2014-07-07 * 2 bug fixes: * Change require to minitest/autorun for non-test/unit style * Change the way files are gathered to avoid StackOverflow exception if you have a TOOON of files. (joshwand) === 4.10.0 / 2014-04-23 * 2 minor enhancements: * Added test_mappings accessor methods (ivar already there). * Added test_prefix to allow you to run code ahead of test loading. (default: gem minitest) === 4.9.5 / 2013-11-01 * 1 bug fix: * Updated require_rubygems_version AGAIN... going too fast. (zzak) === 4.9.4 / 2013-09-20 * 2 bug fixes: * Expand required rubygems version to be < 2.2 * Fix parsing of minitest 5 output. === 4.9.3 / 2013-08-12 * 1 minor enhancement: * Added --debug option. Probably need to add more to help bug reports. * 2 bug fixes: * Fixed completed_re and failed_results_re to match minitest 5 (and still mt 4). * Fixed handle_results to deal with minitest 5 output (eg ClassName#method_name). === 4.9.2 / 2013-05-29 * 2 minor enhancements: * Added autotest-suffix description to readme. (blowmage) * zentest now outputs test classes for minitest 5 === 4.9.1 / 2013-04-18 * 2 minor enhancements: * Make banner more explicit about correct test file location. (rue) * Switched to #failed for calculating red/green hook. (bhenderson) === 4.9.0 / 2013-02-07 * 1 minor enhancement: * Allow multiruby installs to be done entirely by symlink, bypassing build * 1 bug fix: * Fixes for maglev. === 4.8.4 / 2013-01-22 * 2 minor enhancements: * Set required rubygems version to be >= 1.8 and < 2.1. (sanemat) * multiruby now just builds main, which skips rdoc and other stuff * 1 bug fix: * 1.9 proofed Module#focus === 4.8.3 / 2012-12-06 * 1 bug fix: * 2.0: Minor tweak to test to get it to pass on 2.0 === 4.8.2 / 2012-07-26 * 1 bug fix: * Fixed 1.9+ warnings in multiruby. (bhenderson) === 4.8.1 / 2012-06-01 * 1 bug fix: * Fixed 1.9 bug caused by differences between Hash#find_all and Hash#select. (semaperepelitsa) === 4.8.0 / 2012-05-04 * 1 minor enhancement: * Added Minitest generation to zentest (use -t to generate for test/unit) * 1 bug fix: * Fixes and clarifications to Autotest#find_file. (hugh sasse) === 4.7.0 / 2012-03-15 * 2 minor enhancements: * autotest/timestamp now uses ran_command hook. (bhenderson) * run_command hook is now passed cmd. (bhenderson) * 1 bug fix: * Fixed run_command hook to only trigger when there are test files to run. (bhenderson) === 4.6.2 / 2011-08-24 * 1 minor enhancement: * Added Autotest Tips section to Readme * 1 bug fix: * Fixed mri 1.9.3 change to Find.find with autotest/restart and missing files. === 4.6.1 / 2011-08-11 * 3 bug fixes: * Fix for option flags and unhandled error warning in autotest. (dbackeus) * Fix option w/ args handling and restart by storing ARGV in options[:args] * Fixed autotest --rc option handling. (simplybusiness) === 4.6.0 / 2011-07-22 * 6 minor enhancements: * Added -p (plain diff) and made -u (unified diff) the default for unit_diff. * Added ./tmp to default exclusions. * Autotest defaults unit_diff to nil now, to allow minitest's enhanced assert_equal to shine. * Autotest will raise if the :died handler doesn't handle the exception. (ralfebert) * Dropped 1.8.6 as a default tag/branch to build in multiruby. * autotest can now be automatically 'narrowed' on the command-line. * eg: `autotest lib test/test_blah.rb` * 7 bug fixes: * Believe it or not... but some ppl use zentest. Fixed nested class vs module bug * Fix to turn on jruby's support for ObjectSpace. (stepheneb) * Fixed a rubygems deprecation in autotest * Fixed unit_diff scanning for minitest output. * Normalized shebangs to fix problems on windows (luis) * autotest/isolate.rb sets GEM_HOME as well as GEM_PATH. * Fixed 1.9.3 warnings. === 4.5.0 / 2011-02-18 * 6 minor enhancements: * Added autotest -w flag to turn on warnings. Turned off warnings by default. * Added autotest/preload.rb to deal with rails being egregiously slow. * Added child process handling/cleanup on signals. * Added postinitialize hook. * Improved restart mechanism to include all flags. * Refactored restart plugin to Autotest#restart. * 5 bug fixes: * Added sigquit handler to restart app straight up. * Fixed autotest/isolate so it works * Fixed parse_options to take args array (default ARGV) and to be non-destructive. * Strip ascii color to avoid false positives. (graemeworthy) * Use RbConfig to remove warning === 4.4.2 / 2010-12-10 * 2 bug fixes: * Added a temporary hack to deal with rspec(2?) discovery hacks. * Fixed windoze detection for unit_diff (thyresias) === 4.4.1 / 2010-12-01 * 12 minor enhancements: * Merged in most things from the autotest gem: * Added --no-full-after-failed. (grosser) * Added --rc path-to-dot-autotest. (grosser) * Added --style autotest-style. (grosser) * Added clarification comments. (grosser) * Added rake task descriptions. (grosser) * Switched to optparse. (grosser) * Switched windoze detection. (grosser, tenderlove) * Did not merge test parallelization. It should be a plugin. Awaiting patch. * Added autotest/bundler plugin. * Added autotest/isolate plugin. * Added capture of skips (for minitest) from result line. * Added focus_re to focus.rb. * Added latest_results hash. * Cleaned up unit_diff matcher by using any? * Enhanced the help/usage for autotest and zentest. (hugh sasse) * Refactored autotest runner discovery. * Refactored ruby_cmd to allow plugins to affect ruby execution. * Removed befuddling override of Dir.[] from 2007. *shrug* * Removed deny method in favor of aliasing refute. * 2 bug fixes: * 1.9 shadowed variable fix * autotest/restart now passes ARGV back through to exec. yay! === 4.4.0 / 2010-09-01 * 1 major enhancement: * Removed git building. I'm dropping direct support for rubinius. * 3 minor enhancements: * Added multiruby mri:list:x.y.z command so you can see what's available. * Enabled installing specific patch versions of ruby. * multiruby rubygems:update now forces a build to be less confusing. * 1 bug fix: * Removed redundant test_to_normal, now in zentest_mappings === 4.3.3 / 2010-06-17 * 2 minor enhancements: * Added options and removed pattern from Autotest::RCov * update_rubygems now deletes cached rubygems installs === 4.3.2 / 2010-06-02 * 1 minor enhancement: * Removed support for rbx builds. * 2 bug fixes: * Removed 'preview' from version filter so I can test with 1.9.2 * Put PATH tweaks at front of PATH === 4.3.1 / 2010-03-30 * 1 bug fix: * Fixed autotest output on 1.8. That's what I get for not having tests for dots. === 4.3.0 / 2010-03-27 * 1 minor enhancement: * Added gemcutter rubyforge and hoe to the_usual setup * 4 bug fixes: * 1.9 compat: don't use putc anymore. (fistfvck (hah!)) * Added note that included articles are out of date * Fixed rcov plugin so multiple all_good hooks can coexist * Fixed typo in doco === 4.2.1 / 2009-12-09 * 1 minor enhancement: * Added GEM_HOME/GEM_PATH setting to multiruby. * 1 bug fix: * Fixed multiruby refactoring bug from previous release. === 4.2.0 / 2009-12-08 * 3 minor enhancements: * Added 'multiruby -1 $version' for easier execution (idea from flori) * Set up and tear down PATH in multiruby (luis) * died hook now gets passed the exception (amikula) * 3 bug fixes: * Deal with windoze getc returning nil (undees) * Fix unit_diff for multiline miniunit results. * Fix warning for 1.8.8+ === 4.1.4 / 2009-08-07 * 2 minor enhancements: * Added ability to prepend file mappings in autotest. (irohiroki) * Switched autodiscover to use Gem.find_files. * 2 bug fixes: * Updated doco for API changes. (David Ruan) * Updated git URL for Rubinius. jbarnette === 4.1.3 / 2009-06-23 * 1 bug fix: * Fixed rakefile to include seattlerb plugin. release was flubbed === 4.1.2 / 2009-06-23 * 1 minor enhancement: * multiruby configure now passes --enable-shared to support wilson and friends. * 2 bug fixes: * Delete RUBYOPT in multiruby_setup to avoid catastrophe. dbalatero * Fixed version number munging for tarballs. === 4.1.1 / 2009-06-03 * 1 bug fix: * some calls to Multiruby.run didn't have logging. fixed (jcoglan) === 4.1.0 / 2009-06-03 * 1 major enhancement: * Removed all plugins I don't want to maintain anymore. (gem inst autotest-rails) * 4 minor enhancements: * Added #blur to focus.rb to nuke all other test classes * Clear RUBYOPT before installs (balatero) * Removed test/unit include in zentest so we can focus on miniunit * sort versions for builds. (Jens Wille) * 6 bug fixes: * Fixed a stupid bug when running on some versions of bash >= 3.2.x and using '&>' in a system call. (Jens Wille) * Fixed inconsistent test commands in autotest. (jbarnette) * Fixed unit_diff's usage generation when installed as gem. (borior) * Fixed zentest to deal with unnamed classes. (Bill Dortch) * Removed buggy/unused -l support in unit_diff. (borior) * make twice to make it more resilient to makefile parallel bugs === 4.0.0 / 2009-03-02 * 2 minor enhancements: * Deleted autotest/screen - releasing as a separate gem soon. * Deleted test-rails and rails_test_audit. * 8 minor enhancements: * Added "tags" command to multiruby_setup. * Added "the_usual" as a recipe for multiruby_setup. Motivated by Dr. Nic. * Added :died hook to Autotest (yoshuki). * Added focus.rb, helping you ignore extra tests while you focus on something. * Added multigem command line tool! * Cleaned up multiruby to make it easier to tweak. * Parameterized testlib so you can override test/unit in autotest. Thanks JB! * Switched tests and rakefile to minitest. 20% faster! * 7 bug fixes: * Fix Autotest::Screen to distinguish between errors and failures. (khalsah) * Fixed some hook commands from overriding others. * Hopefully fixed growl support on 10.5.x? * Supposedly adding -w to growlnotify will fix autotest/growl. * Updated missing entries in Autotest::ALL_HOOKS. * Updated rubygems download location. (carletti) * Still not automated :( * ruby 1.9.1 fixes. === 3.11.1 / 2009-01-20 * 1 minor enhancement: * Parameterized test_lib so you can override test/unit. Thanks JB! * 1 bug fix: * Fixed growl autotest plugin hooks to not return true, preempting other plugins. === 3.11.0 / 2008-10-22 * 19 minor enhancements: * Added :updated hook, gets list of updated files before running tests. * Added autotest/restart.rb - restarts autotest if .autotest updated. * Added better help to multiruby. * Added dummy build command to multiruby_setup. * Added git support. * Added rbx:ln:$dir and rbx:git:current. * Added rubygems:merge as a nice little hack to share rubygems setups. * Added svn tag updating (eg will svn sw from mri 1.8.6 222 to 1.8.6 231). * Autotest hooks now take *args as well as instance of autotest. * Made it possible to have manually specified tags. * Made multiruby a little more self-repairing wrt symlinks and build dirs. * Refactored into mri_latest_tag(v). * Refactored unit_diff to make it a bit easier to use as a library. * Refactored zentest mapping main methods into munge/unmunge. * Removed rubinius specific symlink hacks, now fully supported. * mri:svn:releases figures out all the latest patch levels. * multiruby_setup clean now checks for rakefile first, since rbx has both. :( * multiruby_setup help now exits instead of building. * multiruby_setup list and clean now exit * 2 bug fixes: * ZenTestMapping converts operator prefixes to operators only when an _ follows. * Apparently Tempfile.open doesn't return it's last value. fixed. * 2 bug fixes: * Fixed bug in mri:svn:branch:xxx with svn dir name. * multiruby_setup rm now smarter about tarballs. === 3.10.0 / 2008-06-17 * 1 major enhancement: * Added multiruby_setup to help manage multiruby installed versions. * 3 minor enhancements: * Added autotest/once plugin to help plugin developers. * Heavily refactored multiruby. * Switched rubinius from shotgun/rubinius to bin/rbx, finally. * 2 bug fixes: * Refactored zentest_mapping test to avoid zentest altogether. * zentest tests bail gracefully for rubinius. === 3.9.3 / 2008-06-09 * 12 minor enhancements: * Added $RUBY env support to autotest so you can swap what ruby to run. * Added ALL_HOOKS array to autotest for hook devs. * Added EXCLUDED_VERSIONS to multiruby. Integrated with hoe. * Added miniunit compatibility to unit_diff's output. * Multiruby now determines the latest versions 1.8/1.9 automatically. * Removed deprecated :run hook. * Fixed zentest_assertions to be compatible with miniunit. Will phase out. * Minor autotest plugin cleanup / fixes. * Moved assert_callback to test/rails/test_case.rb * Reversed assert_includes' arguments. * Updated requirements info for other ruby impls. * util_capture now returns strings, not iostrings. * 1 bug fixes: * (add|remove)_(mappings|exceptions) now all return nil to help fix autotest hooks. === 3.9.2 / 2008-03-20 * 4 minor enhancements: * Added compatibility with miniunit differences. * Added email_notify, jabber_notify, and rcov autotest plugins. * Updated rakefile to include examples automatically in example_dot_autotest. * multiruby now outputs each command so you can grab it easily. * 5 bug fixes: * Ensure tests are run after reset. * Fixed all test/rails tests to run in any combo. * Fixed up growl.rb a bit... still buggy (growlnotify, not growl.rb). * Fixes for -f (fast start) and last_mtime in general. * Fixes for 1.9 and rubinius === 3.9.1 / 2008-01-31 * 1 bug fix: * OMG I'm so dumb... fixed memory leak. === 3.9.0 / 2008-01-30 * 15 minor enhancements: * Added Wilson's patch to allow unit_diff to work with mspec. Adding rspec next. * Minor overhaul for autotest: * Added -f flag to start up without testing. * Added -q flag to autotest to make it extra quiet. Patch by Aaron Patterson. * Added ability to set test execution order, defaults to :random. EVIL! * Added completed_re and failed_results_re to help subclasses like rspec. * Added deprecation warnings for hooks. Deprecated :run. * Added find_directories accessor, defaults to ['.'] * Added sleep accessor, defaults to 1 second. * Changed find_files to order files in the same order as find_directories. * Changed how autodiscover works with $:, added lib to the front. * Cleaned out nearly every @ and use accessor methods instead. You should too. * Made test_mappings ordered. * Removed @files, adding @find_order and @known_files. * Renamed tests_for_file to test_files_for. * test_files_for now only returns known files. === 3.8.0 / 2008-01-12 * 10 minor enhancements: * Added basic support for rubinius in multiruby. * Changed Dunno! message to only output on -v * Added Getting Started with Autotest by Philippe Hanrigou (with permission) * Updated example_dot_autotest.rb for newer plugins. * Cleaned up rdoc. * Worked with David Chelimsky to make Autotest more uber for subclasses. * Removed exceptions and test_mappings accessors and replaced with add/remove/clear methods. Updating .autotest should be very straightforward. * Moved :initialize hook to beginning of run method * Changed load/customization order to be: * Autotest * AutotestSubClass * ~/.autotest * ./.autotest (yes, both .autotest files). * Moved away from using instance variables to encourage subclasses to use accessors. === 3.7.2 / 2008-01-09 * 2 minor enhancements: * Extended file map for tests to include subdirs correctly. * Added debugging output on bad maps if -v set. === 3.7.1 / 2007-12-27 * 2 minor enhancements: * multiruby now downloads 1.8.6 and 1.9 on virgin run. * Improved output for the downloads. === 3.7.0 / 2007-12-21 * 8 minor enhancements: * Added add_mapping to make file mappings cleaner. * Added assert_callback thanks to Aaron Patterson. * Added autotest/cctray. * Added extra_files and extra_class_map, allowing .autotest files to be awesome. * Added url for lettuce principal thanks to Hugh Sasse. * Added zentest.rb refactorings thanks to Hugh Sasse. * Exceptions are now an array of regexps, built after :initialize hook. * Removed ruby_fork and ruby_fork_client. Eric got a faster laptop. :P * 6 bug fixes: * Fixed all my annoyances with @exceptions. * Fixed crasher in autotest/redgreen for non-matches. * Fixed everything to work with ruby 1.9. * Fixed rubygem requires causing strangeness in tests. * Fixed zentest mapping so ruby2ruby and test_ruby2ruby work. * Removed stupid YAML methods from TrueClass during testing. (Infected by Test::Rails' use of rubygems) === 3.6.1 / 2007-07-23 * 4 minor enhancements: * Test::Rails::ViewTestCase now uses assert_select. * assert_form and friends now work with blocks like assert_select does. * Allow path_parameters in view tests to be ammended, making working with routes easier. * New version of autotest/notify.rb uses notify-send. * Fixed rdoc formatting on autotest and a couple plugins. === 3.6.0 / 2007-05-25 * 4 major enhancements: * New auto-discovery mechanism to make rspec and friends work independently! * Moved and restructured camping and rails as plugins. * Removed rspec - now packaged with rspec and/or as plugin. * Changed the way FTM tests are named. Allows multiple matricies. * 3 minor enhancements: * Added :OK special result value to FTM. * Hugh Sasse is awesome. Rdoc happiness. * Parameterized emacs client command. * 3 bug fixes: * Dup load path because I'm dum. * Fixed a lame syntax error in emacs.rb. * autotest now builds command separator with '&' on windoze. ARGH! Why is this the first I've heard of this?!? === 3.5.2 / 2007-04-30 * 4 bug fixes: * Patch up Rails fixture defaults for Test::Rails::TestCase. * Session now properly hooked up to controllers. * ruby 1.8.6 has a bug on 'raise Interrupt' with no args. Fixed on both sides. * Fixed redgreen to work with new getc/putc-based output. (from Finn Smith) === 3.5.1 / 2007-04-17 * 4 bug fixes: * Fixed gem name to be camel-case again. Fixed on rubyforge too. * Fixed rdoc for hooks. * Fixed redgreen, results changed to an array. * Patch up Rails fixture defaults, since they're not inheriting properly. === 3.5.0 / 2007-04-12 * 4 major enhancements: * Now requires RubyGems 0.9.1 or newer. * Autotest and unit_diff are both unbuffered. Results are more live. * Refactored and redesigned how files map to test from Sean Carley. See fixtures plugin as an example. * Generalize how autotest handler is instantiated and invoked, allowing for many more autotest types, including combos. * 23 minor enhancements: * Added all_good hook if initial run was all_good as well. * Added assert_in_epsilon to ZentestAssertions. * Added autotest plugin to auto-update source ala tinderbox/cruisecontrol. * Added autotest plugin to update ichat/adium IM status with code stats. * Added autotest plugin to update the GNU screen statusbar from Yuichi Tateno. * Added autotest syntax error handling from Ryan Platte. * Added autotest/emacs emacs integration plugin!!! YAY! * Added autotest/migrate.rb. * Added camping support from Geoffrey Grossenbach. * Added changed file reporting to autotest via -v flag. * Added informative summary and filtering via ENV['VERSIONS'] to multiruby. * Added libnotify support from Kazuo Saito. * Added lots of rdoc patches from Hugh Sasse. * Added rjs files to view_test_case. * Added rspec_autotest "stolen" from caldersphere.net * Added run_command hook to trigger the start of a test run. * Added tmp to rails' exceptions list. * Added unit_diff command variable to autotest for customizing flags and such. * Added zentest_mapping.rb and test. * Allow session to work in Test::Rails view tests. * Improved autotest/growl.rb output from imajes. * Improved autotest/timestamp output from Josh Susser. * Test::Rails works with Rails 1.2. * 2 bug fixes: * Accelerated Test::Rails unit tests via sensible defaults. * Better assertion messages for ZentestAssertions. === 3.4.3 / 2006-12-19 * 2 minor enhancements: * Add assert_title and assert_h (for header). * 2 bug fixes: * Rereleased against latest version of hoe to fix load path problems. * Fix case ViewTestCase for case-sensitive file systems. === 3.4.2 / 2006-11-09 * 2 minor enhancements: * Add TextHelper for pluralize. * Add deny_nil to Test::Rails. * 7 bug fixes: * Fixed test_help's Flash. It's is a module. Oops... * Don't run util_audit_assert_assigned if tests didn't pass, results will be bogus. * Fixed AssertionsTest names to match what autotest expects. * Fixed bug where deny_includes failed for Symbol keys. * Switched autotest to use require instead of load... Why??? I don't know!! * Fixed a minor but annoying whitespace difference in unit_diff. * Switched argument order of assert_includes and deny_includes to match Test::Unit convention. === 3.4.1 / 2006-10-13 * 3 minor enhancements: * FUNDAMENTALLY changed the way failures map back to tests. This REQUIRES users of autotest to ensure that their tests and impls map 1:1 at every scoping level. I'll blog more details. * Hoe'd rakefile * Added support for render :collection to RenderTree. * 7 bug fixes: * Fixed autotest tests for custom ruby names. * Fixed some documentation errors in ControllerTestCase. * Fixed setup in FunctionalTestCase. * Allowed @assigns_ignored to contain either Symbols or Strings, bug 5233. * Using Object.path2class to look up classes in helper test cases, bug 5493. * Added assert_text_area, bug 5452. * Renamed assert_select to assert_select_tag. Stupid rails. We were here first. === 3.4.0 / 2006-09-12 * 13 minor enhancements: * Broke out example_dot_autotest into multiple files in lib. * Enhanced hook system so it can return true if event handled. * Sleep is now 1 second by default because life is too short. * Hooked interrupt with new hook system. First handler wins. * Hooked test results before output * Accurate test counts for Test::Rails. * Added snarl autotest plugin, thanks to Patrick Hurley. * Added timestamp autotest plugin, thanks to Joe Goldberg. * Added redgreen, thanks to Pat Eyler, Sean Carley, and Rob Sanheim. * Added kdenotify autotest plugin, thanks to Geir Freysson. * Added markaby support for Test::Rails. * Added hack to display a tree of render calls. * Added hook to perform extra setup for * 5 bug fixes: * Extended zentest to deal with rails a bit better... ugh. * Fixed @libs for windoze. * Fixed inner class/test identification in autotest. * Namespaced all plugins... eric is anal. * No longer freak out if rubygems tarball not in multiruby/versions. === 3.3.0 / 2006-07-28 * 1 major enhancement: * autotest has been rewritten to be much cleaner, now has a plugin system. * 5 minor enhancements: * test/rails adds helper tests, "stolen" from Geoff's work, (which was "stolen" from ryan's work. :P) * autotest turnaround is now faster. * Added more prune dirs to autotest. * test/rails rewinds IOs containing captured output. Added assert_empty. * Document that autotest doesn't run the db:test:prepare rake task when in Rails mode. * Added ruby_fork, but haven't fully plugged into autotest yet. * 7 bug fixes: * Add SIGINT handler to unit_diff to give a more graceful exit. * Don't strip <> from tempfiles, parse_diff does it for us. * Fixed autotest problems on windoze. Ugh. * Fixed broken pipe bug and newline bug in unit_diff. * Make request_method in ControllerTestCase a String. * multitest installs rubygems if tarball found in versions dir. * multitest only configures when makefile is missing. Rebuilds much faster now. * ruby_fork exits without backtrace and allows redirection of output. === 3.2.0 / 2006-04-10 * 1 major enhancement: * Added Test::Rails. * 1 minor enhancement: * Extended autotest for Test::Rails. * 4 bug fixes: * Autotest now detects changes in rhtml. * Improved autotest's file mapping and choice of ruby. * We've got RDoc, yes we do! * Removed redundancies in rakefile. Using gem spec for most stuff now. === 3.1.0 / 2006-03-29 * 2 major enhancements: * Added multiruby! YAY! * Massive improvements to autotest: speed, reliability, reporting, etc. * 10 minor enhancements: * multiruby builds in a centralized location. YAY! * multiruby now allows reinstalls quickly and easily (can even skip config). * multiruby exits with total sum of exit codes. * autotest file search is muuuuch faster. * autotest automatically detects rails mode. * autotest deals with rails dependencies much better. * autotest reruns a full suite after you go green to ensure full coverage. * autotest always runs with unit_diff -u. * autotest can now run cvs/svn/p4 up periodically to be a mini-tinderbox. * autotest now has real help. * 4 bug fixes: * ZenTest is now zentest. Yay for consistency! (do a rake uninstall to clean) * ZenTest excludes pretty_print methods. * Fixed unary operator issues (they were backwards... oops!) for ZenTest. * unit_diff now runs diff.exe on Windoze. dunno if that will work. === 3.0.0 / 2006-03-06 * 2 major enhancements: * Added autotest and rails_autotest. YAY for continous testing! * Repackaged and gemified. YAY for gemification! * 3 minor enhancements: * Added non-mappable tests starting with test_integration_. * Lots of code and test refactoring and cleanup. * Massive improvement on unit tests. * 3 bug fixes: * Cleaned up class method inheritence. Esp relevant for rails testing. * Finally fixed the unit_diff parse bug! * Fixed improper counting of errors if a class was missing, should be 1 + missing methods. === 2.4.0 / 2005-03-21 * 3 minor enhancements: * Able to audit standard class library (so now we can audit rubicon!). * Able to map against class methods (self.blah <=> test_class_blah). * Added -I=rubypath support * 4 bug fixes: * bug:1151 Fixed stupid problem w/ unit_diff. * bug:1454 code generation correctly matches class/module for nested classes. * bug:1455 Updated method mapping to work on all operators listed in my quickref. * Realized I'm a moron and did NOT release in March like I thought... === 2.3.0 / 2004-11-18 * 6 minor enhancements: * Massively expanded the method name mappings. * Added -r flag to reverse map names, for Rails style testing. * Added -e to auto eval tests generated. * Added -b & -c flags in unit_diff (passed to diff) * Added install and uninstall rules to Makefile. * Added some more doco to README.txt * 7 bug fixes: * Cleaned up and refactored tests. * Changed the way files are generated, to accomodate new flags. * Added some more tests. * Added $ZENTEST=true * Fixed the one-liner diff bug. * Cleaned up multi-line string diffs by unescaping \n * Cleaned result for flunks. === 2.2.0 / 2004-10-18 * 4 minor enhancements: * Added LinuxJournalArticle.txt! WOOT! * Added unit_diff.rb - a very cool filter for test output! * Extended ZenTest to work with standard input * Added "ZenTest FULL" to force ZenTest to analyze inherited methods, for subclasses of the standard library. * 3 bug fixes: * Extended makefile to be more dynamic and stop diffing versions. ugh. * Expanded the method rename map to handle <<, *, +, and ==. * Added more test cases. === 2.1.2 / 2004-03-08 * 4 bug fixes: * Fixed yet another 1.8ism, results will be the same in 1.8 and 1.6. * Fixed code responsible for method name conversion. * I am a moron... didn't run tests after updating version. * Need to convert my diff-based tests to unit tests. === 2.1.1 / 2004-03-06 * 3 bug fixes: * Fixed a 1.8ism. * Removed zentestrunner. Older ruby users will just have to suffer. * Updated history to ZenWeb format. === 2.1.0 / 2003-01-07 * 3 major enhancements: * Output is runnable as-is thanks to zentestrunner.rb. * Wrapped up all running functionality into ZenTest.fix * Added simple statistic output... Thanks Dave & Andy!!! * 2 minor enhancements: * Added zentestrunner.rb until Nathaniel accepts my changes! * Added a clean rule to Makefile * 3 bug fixes: * Removed at_exit override and avoided test/unit altogether. * Extended README.txt to include some of the rules. * Fixed several tests and added assertions for new stats === 2.0.0 / 2002-10-29 * 2 major enhancements: * Rewrite of ZenTest.rb into actual OO design. * Added unit tests, finally... === 1.0.1 / 2002-09-28 * 1 minor enhancement: * Only loads when a class is detected, allows some scripts to be skipped. * 3 bug fixes: * Cleaned up output. Verbose when $DEBUG is true. * Added an error count that is output at end. * Better filtering or conversion on some method names. === 1.0.0 / 2002-09-24 * 1 major enhancement: * Birthday! ZenTest-4.11.0/example1.rb0000444000004100000410000000012312432322455015256 0ustar www-datawww-datamodule Something class Thingy def do_something # ... end end end ZenTest-4.11.0/lib/0000755000004100000410000000000012432322455013771 5ustar www-datawww-dataZenTest-4.11.0/lib/multiruby.rb0000444000004100000410000002551612432322455016361 0ustar www-datawww-datarequire 'fileutils' require 'open-uri' ## # multiruby_setup is a script to help you manage multiruby. # # usage: multiruby_setup [-h|cmd|spec...] # # cmds: # # -h, --help, help = show this help. # build = build and install everything. used internally. # clean = clean scm build dirs and remove non-scm build dirs. # list = print installed versions. # rm:$version = remove a particular version. # rubygems:merge = symlink all rubygem dirs to one dir. # tags = list all tags from svn. # update = update svn builds. # update:rubygems = update rubygems and nuke install dirs. # # specs: # # the_usual = alias for latest versions from tar + rubygems # mri:svn:current = alias for mri:svn:releases and mri:svn:branches. # mri:svn:releases = alias for supported releases of mri ruby. # mri:svn:branches = alias for active branches of mri ruby. # mri:svn:branch:$branch = install a specific $branch of mri from svn. # mri:svn:tag:$tag = install a specific $tag of mri from svn. # mri:tar:$version = install a specific $version of mri from tarball. # # environment variables: # # GEM_URL = url for rubygems tarballs # MRI_SVN = url for MRI SVN # RUBY_URL = url for MRI tarballs # VERSIONS = what versions to install # # RUBYOPT is cleared on installs. # # NOTES: # # * you can add a symlink to your rubinius build into ~/.multiruby/install # * I need patches/maintainers for other implementations. # module Multiruby def self.env name, fallback; ENV[name] || fallback; end # :nodoc: TAGS = %w( 1_8_7 1_9_1 1_9_2) BRANCHES = %w(1_8 1_8_7 1_9 trunk) VERSIONS = env('VERSIONS', TAGS.join(":").gsub(/_/, '.')).split(/:/) MRI_SVN = env 'MRI_SVN', 'http://svn.ruby-lang.org/repos/ruby' RUBY_URL = env 'RUBY_URL', 'http://ftp.ruby-lang.org/pub/ruby' GEM_URL = env 'GEM_URL', 'http://files.rubyforge.vm.bytemark.co.uk/rubygems' HELP = [] File.readlines(__FILE__).each do |line| next unless line =~ /^#( |$)/ HELP << line.sub(/^# ?/, '') end def self.build_and_install ENV.delete 'RUBYOPT' root_dir = self.root_dir versions = [] Dir.chdir root_dir do self.setup_dirs rubygems = Dir["versions/rubygems*.tgz"] abort "You should delete all but one rubygem tarball" if rubygems.size > 1 rubygem_tarball = File.expand_path rubygems.last rescue nil Dir.chdir "build" do Dir["../versions/*"].sort.each do |tarball| next if tarball =~ /rubygems/ build_dir = File.basename tarball, ".tar.gz" version = build_dir.sub(/^ruby-?/, '') inst_dir = "#{root_dir}/install/#{version}" unless test ?d, inst_dir then unless test ?d, build_dir then if test ?d, tarball then dir = File.basename tarball FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}" else puts "creating #{inst_dir}" Dir.mkdir inst_dir run "tar zxf #{tarball}" end end Dir.chdir build_dir do puts "building and installing #{version}" if test ?f, "configure.in" then gnu_utils_build inst_dir elsif test ?f, "Rakefile" then rake_build inst_dir else raise "dunno how to build" end if rubygem_tarball and version !~ /1[._-]9|mri_trunk|rubinius/ then rubygems = File.basename rubygem_tarball, ".tgz" run "tar zxf #{rubygem_tarball}" unless test ?d, rubygems Dir.chdir rubygems do run "../ruby ./setup.rb --no-rdoc --no-ri", "../log.rubygems" end end end end end end versions = Dir["install/*"].map { |path| File.basename path } end versions end def self.clean self.each_scm_build_dir do |style| case style when :svn then if File.exist? "Rakefile" then run "rake clean" elsif File.exist? "Makefile" then run "make clean" end else FileUtils.rm_rf Dir.pwd end end end def self.each_scm_build_dir Multiruby.in_build_dir do Dir["*"].each do |dir| next unless File.directory? dir Dir.chdir dir do if File.exist?(".svn") then yield :svn else yield :none end end end end end def self.matching_versions url, matching=nil file = URI.parse(url).read map = { "preview" => "beta", "rc" => "beta2", "p" => "release", "tar" => "aargh", "gz" => "aargh", } versions = file.scan(/href="(ruby.*tar.gz)"/).flatten.sort_by { |s| s.scan(/\d+|[a-z]+/).map { |a| Integer(a) rescue map[a] || a } } versions = versions.grep(/#{Regexp.escape(matching)}/) if matching versions end def self.fetch_tar v in_versions_dir do warn " Determining latest version for #{v}" ver = v[/\d+\.\d+/] base = matching_versions("#{RUBY_URL}/#{ver}/", v).last abort "Could not determine release for #{v}" unless base url = File.join RUBY_URL, ver, base unless File.file? base then warn " Fetching #{base} via HTTP... this might take a while." open(url) do |f| File.open base, 'w' do |out| out.write f.read end end end end end def self.gnu_utils_build inst_dir run "autoconf" unless test ?f, "configure" run "./configure --enable-shared --prefix #{inst_dir}", "log.configure" unless test ?f, "Makefile" run "(nice make -j4 main; nice make main)", "log.build" run "make install-nodoc", "log.install" end def self.help puts HELP.join end def self.in_build_dir in_root_dir "build" do yield end end def self.in_install_dir in_root_dir "install" do yield end end def self.in_root_dir subdir = "" Dir.chdir File.join(self.root_dir, subdir) do yield end end def self.in_tmp_dir in_root_dir "tmp" do yield end end def self.in_versions_dir in_root_dir "versions" do yield end end def self.list puts "Known versions:" in_install_dir do Dir["*"].sort.each do |d| puts " #{d}" end end end def self.merge_rubygems in_install_dir do gems = Dir["*/lib/ruby/gems"] unless test ?d, "../gems" then FileUtils.mv gems.first, ".." end gems.each do |d| FileUtils.rm_rf d FileUtils.ln_sf "../../../../gems", d end end end def self.mri_latest_tag v Multiruby.tags.grep(/#{v}/).last end def self.rake_build inst_dir run "rake", "log.build" FileUtils.ln_sf "../build/#{File.basename Dir.pwd}", inst_dir end def self.rm name Multiruby.in_root_dir do FileUtils.rm_rf Dir["*/#{name}"] f = "versions/ruby-#{name}.tar.gz" File.unlink f if test ?f, f end end def self.root_dir root_dir = File.expand_path(ENV['MULTIRUBY'] || File.join(ENV['HOME'], ".multiruby")) unless test ?d, root_dir then puts "creating #{root_dir}" Dir.mkdir root_dir, 0700 end root_dir end def self.run base_cmd, log = nil cmd = base_cmd cmd += " > #{log} 2>&1" if log puts "Running command: #{cmd}" raise "ERROR: Command failed with exit code #{$?}" unless system cmd end def self.setup_dirs download = true %w(build install versions tmp).each do |dir| unless test ?d, dir then puts "creating #{dir}" Dir.mkdir dir if dir == "versions" && download then warn " Downloading initial ruby tarballs to ~/.multiruby/versions:" VERSIONS.each do |v| self.fetch_tar v end warn " ...done" warn " Put other ruby tarballs in ~/.multiruby/versions to use them." end end end end def self.svn_co url, dir Multiruby.in_versions_dir do Multiruby.run "svn co #{url} #{dir}" unless File.directory? dir FileUtils.ln_sf "../versions/#{dir}", "../build/#{dir}" end end def self.tags tags = nil Multiruby.in_tmp_dir do cache = "svn.tag.cache" File.unlink cache if Time.now - File.mtime(cache) > 3600 rescue nil File.open cache, "w" do |f| f.write `svn ls #{MRI_SVN}/tags/` end unless File.exist? cache tags = File.read(cache).split(/\n/).grep(/^v/).reject {|s| s =~ /preview/} end tags = tags.sort_by { |t| t.scan(/\d+/).map { |s| s.to_i } } end def self.update # TODO: # update will look at the dir name and act accordingly rel_.* will # figure out latest tag on that name and svn sw to it trunk and # others will just svn update clean = [] self.each_scm_build_dir do |style| dir = File.basename(Dir.pwd) warn dir case style when :svn then case dir when /mri_\d/ then system "svn cleanup" # just in case svn_up = `svn up` in_build_dir do if svn_up =~ /^[ADUCG] / then clean << dir else warn " no update" end FileUtils.ln_sf "../build/#{dir}", "../versions/#{dir}" end when /mri_rel_(.+)/ then ver = $1 url = `svn info`[/^URL: (.*)/, 1] latest = self.mri_latest_tag(ver).chomp('/') new_url = File.join(File.dirname(url), latest) if new_url != url then run "svn sw #{new_url}" clean << dir else warn " no update" end else warn " update in this svn dir not supported yet: #{dir}" end else warn " update in non-svn dir not supported yet: #{dir}" end end in_install_dir do clean.each do |dir| warn "removing install/#{dir}" FileUtils.rm_rf dir end end end def self.update_rubygems warn " Determining latest version for rubygems" html = URI.parse(GEM_URL).read versions = html.scan(/href="rubygems-update-(\d+(?:\.\d+)+).gem/i).flatten latest = versions.sort_by { |v| v.scan(/\d+/).map { |s| s.to_i } }.last Multiruby.in_versions_dir do file = "rubygems-#{latest}.tgz" unless File.file? file then warn " Fetching rubygems-#{latest}.tgz via HTTP." File.unlink(*Dir["rubygems*"]) File.open file, 'w' do |f| f.write URI.parse(GEM_URL+"/"+file).read end end end Multiruby.in_build_dir do FileUtils.rm_rf Dir["rubygems*"] end Multiruby.in_install_dir do FileUtils.rm_rf Dir["*"] end end end ZenTest-4.11.0/lib/zentest.rb0000444000004100000410000004410612432322455016015 0ustar www-datawww-dataif (defined? RUBY_ENGINE) && RUBY_ENGINE == 'jruby' require 'java' JRuby.objectspace=true end $stdlib = {} if ObjectSpace.respond_to?(:loaded_classes, true) then ObjectSpace.loaded_classes(true).each do |m| $stdlib[m.name] = true if m.respond_to? :name end else ObjectSpace.each_object(Module) do |m| $stdlib[m.name] = true if m.respond_to? :name end end require 'zentest_mapping' $:.unshift( *$I.split(/:/) ) if defined? $I and String === $I $r = false unless defined? $r # reverse mapping for testclass names $t ||= false # test/unit instead of minitest if $r then # all this is needed because rails is retarded $-w = false $: << 'test' $: << 'lib' require 'config/environment' f = './app/controllers/application.rb' require f if test ?f, f end $TESTING = true class Module def zentest at_exit { ZenTest.autotest(self) } end end ## # ZenTest scans your target and unit-test code and writes your missing # code based on simple naming rules, enabling XP at a much quicker # pace. ZenTest only works with Ruby and Minitest or Test::Unit. # # == RULES # # ZenTest uses the following rules to figure out what code should be # generated: # # * Definition: # * CUT = Class Under Test # * TC = Test Class (for CUT) # * TC's name is the same as CUT w/ "Test" prepended at every scope level. # * Example: TestA::TestB vs A::B. # * CUT method names are used in CT, with "test_" prependend and optional "_ext" extensions for differentiating test case edge boundaries. # * Example: # * A::B#blah # * TestA::TestB#test_blah_normal # * TestA::TestB#test_blah_missing_file # * All naming conventions are bidirectional with the exception of test extensions. # # See ZenTestMapping for documentation on method naming. class ZenTest VERSION = "4.11.0" include ZenTestMapping if $TESTING then attr_reader :missing_methods attr_accessor :test_klasses attr_accessor :klasses attr_accessor :inherited_methods else def missing_methods; raise "Something is wack"; end end def initialize @result = [] @test_klasses = {} @klasses = {} @error_count = 0 @inherited_methods = Hash.new { |h,k| h[k] = {} } # key = klassname, val = hash of methods => true @missing_methods = Hash.new { |h,k| h[k] = {} } end # load_file wraps require, skipping the loading of $0. def load_file(file) puts "# loading #{file} // #{$0}" if $DEBUG unless file == $0 then begin require file rescue LoadError => err puts "Could not load #{file}: #{err}" end else puts "# Skipping loading myself (#{file})" if $DEBUG end end # obtain the class klassname def get_class(klassname) klass = nil begin klass = klassname.split(/::/).inject(Object) { |k,n| k.const_get n } puts "# found class #{klass.name}" if $DEBUG rescue NameError end if klass.nil? and not $TESTING then puts "Could not figure out how to get #{klassname}..." puts "Report to support-zentest@zenspider.com w/ relevant source" end return klass end # Get the public instance, class and singleton methods for # class klass. If full is true, include the methods from # Kernel and other modules that get included. The methods # suite, new, pretty_print, pretty_print_cycle will not # be included in the resuting array. def get_methods_for(klass, full=false) klass = self.get_class(klass) if klass.kind_of? String # WTF? public_instance_methods: default vs true vs false = 3 answers # to_s on all results if ruby >= 1.9 public_methods = klass.public_instance_methods(false) public_methods -= Kernel.methods unless full public_methods.map! { |m| m.to_s } public_methods -= %w(pretty_print pretty_print_cycle) klass_methods = klass.singleton_methods(full) klass_methods -= Class.public_methods(true) klass_methods = klass_methods.map { |m| "self.#{m}" } klass_methods -= %w(self.suite new) result = {} (public_methods + klass_methods).each do |meth| puts "# found method #{meth}" if $DEBUG result[meth] = true end return result end # Return the methods for class klass, as a hash with the # method nemas as keys, and true as the value for all keys. # Unless full is true, leave out the methods for Object which # all classes get. def get_inherited_methods_for(klass, full) klass = self.get_class(klass) if klass.kind_of? String klassmethods = {} if (klass.class.method_defined?(:superclass)) then superklass = klass.superclass if superklass then the_methods = superklass.instance_methods(true) # generally we don't test Object's methods... unless full then the_methods -= Object.instance_methods(true) the_methods -= Kernel.methods # FIX (true) - check 1.6 vs 1.8 end the_methods.each do |meth| klassmethods[meth.to_s] = true end end end return klassmethods end # Check the class klass is a testing class # (by inspecting its name). def is_test_class(klass) klass = klass.to_s klasspath = klass.split(/::/) a_bad_classpath = klasspath.find do |s| s !~ ($r ? /Test$/ : /^Test/) end return a_bad_classpath.nil? end # Generate the name of a testclass from non-test class # so that Foo::Blah => TestFoo::TestBlah, etc. It the # name is already a test class, convert it the other way. def convert_class_name(name) name = name.to_s if self.is_test_class(name) then if $r then name = name.gsub(/Test($|::)/, '\1') # FooTest::BlahTest => Foo::Blah else name = name.gsub(/(^|::)Test/, '\1') # TestFoo::TestBlah => Foo::Blah end else if $r then name = name.gsub(/($|::)/, 'Test\1') # Foo::Blah => FooTest::BlahTest else name = name.gsub(/(^|::)/, '\1Test') # Foo::Blah => TestFoo::TestBlah end end return name end # Does all the work of finding a class by name, # obtaining its methods and those of its superclass. # The full parameter determines if all the methods # including those of Object and mixed in modules # are obtained (true if they are, false by default). def process_class(klassname, full=false) klass = self.get_class(klassname) raise "Couldn't get class for #{klassname}" if klass.nil? klassname = klass.name # refetch to get full name is_test_class = self.is_test_class(klassname) target = is_test_class ? @test_klasses : @klasses # record public instance methods JUST in this class target[klassname] = self.get_methods_for(klass, full) # record ALL instance methods including superclasses (minus Object) # Only minus Object if full is true. @inherited_methods[klassname] = self.get_inherited_methods_for(klass, full) return klassname end # Work through files, collecting class names, method names # and assertions. Detects ZenTest (SKIP|FULL) comments # in the bodies of classes. # For each class a count of methods and test methods is # kept, and the ratio noted. def scan_files(*files) assert_count = Hash.new(0) method_count = Hash.new(0) klassname = nil files.each do |path| is_loaded = false # if reading stdin, slurp the whole thing at once file = (path == "-" ? $stdin.read : File.new(path)) file.each_line do |line| if klassname then case line when /^\s*def/ then method_count[klassname] += 1 when /assert|flunk/ then assert_count[klassname] += 1 end end if line =~ /^\s*(?:class|module)\s+([\w:]+)/ then klassname = $1 if line =~ /\#\s*ZenTest SKIP/ then klassname = nil next end full = false if line =~ /\#\s*ZenTest FULL/ then full = true end unless is_loaded then unless path == "-" then self.load_file(path) else eval file, TOPLEVEL_BINDING end is_loaded = true end begin klassname = self.process_class(klassname, full) rescue puts "# Couldn't find class for name #{klassname}" next end # Special Case: ZenTest is already loaded since we are running it if klassname == "TestZenTest" then klassname = "ZenTest" self.process_class(klassname, false) end end # if /class/ end # IO.foreach end # files result = [] method_count.each_key do |classname| entry = {} next if is_test_class(classname) testclassname = convert_class_name(classname) a_count = assert_count[testclassname] m_count = method_count[classname] ratio = a_count.to_f / m_count.to_f * 100.0 entry['n'] = classname entry['r'] = ratio entry['a'] = a_count entry['m'] = m_count result.push entry end sorted_results = result.sort { |a,b| b['r'] <=> a['r'] } @result.push sprintf("# %25s: %4s / %4s = %6s%%", "classname", "asrt", "meth", "ratio") sorted_results.each do |e| @result.push sprintf("# %25s: %4d / %4d = %6.2f%%", e['n'], e['a'], e['m'], e['r']) end end # Adds a missing method to the collected results. def add_missing_method(klassname, methodname) @result.push "# ERROR method #{klassname}\##{methodname} does not exist (1)" if $DEBUG and not $TESTING @error_count += 1 @missing_methods[klassname][methodname] = true end # looks up the methods and the corresponding test methods # in the collection already built. To reduce duplication # and hide implementation details. def methods_and_tests(klassname, testklassname) return @klasses[klassname], @test_klasses[testklassname] end # Checks, for the given class klassname, that each method # has a corrsponding test method. If it doesn't this is # added to the information for that class def analyze_impl(klassname) testklassname = self.convert_class_name(klassname) if @test_klasses[testklassname] then _, testmethods = methods_and_tests(klassname, testklassname) # check that each method has a test method @klasses[klassname].each_key do | methodname | testmethodname = normal_to_test(methodname) unless testmethods[testmethodname] then begin unless testmethods.keys.find { |m| m =~ /#{testmethodname}(_\w+)+$/ } then self.add_missing_method(testklassname, testmethodname) end rescue RegexpError puts "# ERROR trying to use '#{testmethodname}' as a regex. Look at #{klassname}.#{methodname}" end end # testmethods[testmethodname] end # @klasses[klassname].each_key else # ! @test_klasses[testklassname] puts "# ERROR test class #{testklassname} does not exist" if $DEBUG @error_count += 1 @klasses[klassname].keys.each do | methodname | self.add_missing_method(testklassname, normal_to_test(methodname)) end end # @test_klasses[testklassname] end # For the given test class testklassname, ensure that all # the test methods have corresponding (normal) methods. # If not, add them to the information about that class. def analyze_test(testklassname) klassname = self.convert_class_name(testklassname) # CUT might be against a core class, if so, slurp it and analyze it if $stdlib[klassname] then self.process_class(klassname, true) self.analyze_impl(klassname) end if @klasses[klassname] then methods, testmethods = methods_and_tests(klassname,testklassname) # check that each test method has a method testmethods.each_key do | testmethodname | if testmethodname =~ /^test_(?!integration_)/ then # try the current name methodname = test_to_normal(testmethodname, klassname) orig_name = methodname.dup found = false until methodname == "" or methods[methodname] or @inherited_methods[klassname][methodname] do # try the name minus an option (ie mut_opt1 -> mut) if methodname.sub!(/_[^_]+$/, '') then if methods[methodname] or @inherited_methods[klassname][methodname] then found = true end else break # no more substitutions will take place end end # methodname == "" or ... unless found or methods[methodname] or methodname == "initialize" then self.add_missing_method(klassname, orig_name) end else # not a test_.* method unless testmethodname =~ /^util_/ then puts "# WARNING Skipping #{testklassname}\##{testmethodname}" if $DEBUG end end # testmethodname =~ ... end # testmethods.each_key else # ! @klasses[klassname] puts "# ERROR class #{klassname} does not exist" if $DEBUG @error_count += 1 @test_klasses[testklassname].keys.each do |testmethodname| @missing_methods[klassname][test_to_normal(testmethodname)] = true end end # @klasses[klassname] end # create a given method at a given # indentation. Returns an array containing # the lines of the method. def create_method(indentunit, indent, name) meth = [] meth.push indentunit*indent + "def #{name}" meth.last << "(*args)" unless name =~ /^test/ indent += 1 meth.push indentunit*indent + "raise NotImplementedError, 'Need to write #{name}'" indent -= 1 meth.push indentunit*indent + "end" return meth end # Walk each known class and test that each method has # a test method # Then do it in the other direction... def analyze # walk each known class and test that each method has a test method @klasses.each_key do |klassname| self.analyze_impl(klassname) end # now do it in the other direction... @test_klasses.each_key do |testklassname| self.analyze_test(testklassname) end end # Using the results gathered during analysis # generate skeletal code with methods raising # NotImplementedError, so that they can be filled # in later, and so the tests will fail to start with. def generate_code @result.unshift "# Code Generated by ZenTest v. #{VERSION}" if $DEBUG then @result.push "# found classes: #{@klasses.keys.join(', ')}" @result.push "# found test classes: #{@test_klasses.keys.join(', ')}" end if @missing_methods.size > 0 then @result.push "" if $t then @result.push "require 'test/unit/testcase'" @result.push "require 'test/unit' if $0 == __FILE__" else @result.push "require 'minitest/autorun'" end @result.push "" end indentunit = " " @missing_methods.keys.sort.each do |fullklasspath| methods = @missing_methods[fullklasspath] cls_methods = methods.keys.grep(/^(self\.|test_class_)/) methods.delete_if {|k,v| cls_methods.include? k } next if methods.empty? and cls_methods.empty? indent = 0 is_test_class = self.is_test_class(fullklasspath) clsname = $t ? "Test::Unit::TestCase" : "Minitest::Test" superclass = is_test_class ? " < #{clsname}" : '' @result.push indentunit*indent + "class #{fullklasspath}#{superclass}" indent += 1 meths = [] cls_methods.sort.each do |method| meth = create_method(indentunit, indent, method) meths.push meth.join("\n") end methods.keys.sort.each do |method| next if method =~ /pretty_print/ meth = create_method(indentunit, indent, method) meths.push meth.join("\n") end @result.push meths.join("\n\n") indent -= 1 @result.push indentunit*indent + "end" @result.push '' end @result.push "# Number of errors detected: #{@error_count}" @result.push '' end # presents results in a readable manner. def result return @result.join("\n") end # Provide a certain amount of help. def self.usage puts <<-EO_USAGE usage: #{File.basename $0} [options] test-and-implementation-files... ZenTest scans your target and unit-test code and writes your missing code based on simple naming rules, enabling XP at a much quicker pace. ZenTest only works with Ruby and Minitest or Test::Unit. ZenTest uses the following rules to figure out what code should be generated: * Definition: * CUT = Class Under Test * TC = Test Class (for CUT) * TC's name is the same as CUT w/ "Test" prepended at every scope level. * Example: TestA::TestB vs A::B. * CUT method names are used in CT, with "test_" prependend and optional "_ext" extensions for differentiating test case edge boundaries. * Example: * A::B#blah * TestA::TestB#test_blah_normal * TestA::TestB#test_blah_missing_file * All naming conventions are bidirectional with the exception of test extensions. options: -h display this information -v display version information -r Reverse mapping (ClassTest instead of TestClass) -e (Rapid XP) eval the code generated instead of printing it -t test/unit generation (default is minitest). EO_USAGE end # Give help, then quit. def self.usage_with_exit self.usage exit 0 end # Runs ZenTest over all the supplied files so that # they are analysed and the missing methods have # skeleton code written. # If no files are supplied, splutter out some help. def self.fix(*files) ZenTest.usage_with_exit if files.empty? zentest = ZenTest.new zentest.scan_files(*files) zentest.analyze zentest.generate_code return zentest.result end # Process all the supplied classes for methods etc, # and analyse the results. Generate the skeletal code # and eval it to put the methods into the runtime # environment. def self.autotest(*klasses) zentest = ZenTest.new klasses.each do |klass| zentest.process_class(klass) end zentest.analyze zentest.missing_methods.each do |klass,methods| methods.each do |method,x| warn "autotest generating #{klass}##{method}" end end zentest.generate_code code = zentest.result puts code if $DEBUG Object.class_eval code end end ZenTest-4.11.0/lib/autotest/0000755000004100000410000000000012432322455015641 5ustar www-datawww-dataZenTest-4.11.0/lib/autotest/preload.rb0000444000004100000410000000200512432322455017607 0ustar www-datawww-datamodule Autotest::Preload def self.glob @glob end def self.glob= o @glob = o end self.glob = "test/test_helper.rb" Autotest.add_hook :post_initialize do |at, *args| at.add_sigquit_handler warn "pre-loading initializers" t0 = Time.now Dir[self.glob].each do |path| require path end warn "done pre-loading initializers in %.2f seconds" % [Time.now - t0] false end end class Autotest alias :old_run_tests :run_tests def run_tests hook :run_command new_mtime = self.find_files_to_test return unless new_mtime self.last_mtime = new_mtime begin # TODO: deal with unit_diff and partial test runs later original_argv = ARGV.dup ARGV.clear @child = fork do trap "QUIT", "DEFAULT" trap "INT", "DEFAULT" files_to_test.keys.each do |file| load file end end Process.wait ensure @child = nil ARGV.replace original_argv end hook :ran_command end end ZenTest-4.11.0/lib/autotest/autoupdate.rb0000444000004100000410000000105512432322455020340 0ustar www-datawww-datamodule Autotest::AutoUpdate @@sleep_time, @@update_cmd, @@updater = 60, "svn up", nil def self.sleep_time= o @@sleep_time = o end def self.update_cmd= o @@update_cmd = o end Autotest.add_hook :run_command do |at| @@updater.kill if @@updater end Autotest.add_hook :ran_command do |at| @@updater = Thread.start do loop do puts "# Waiting for #{@@sleep_time} seconds before updating" sleep @@sleep_time puts "# Running #{@@update_cmd}" system @@update_cmd end end end end ZenTest-4.11.0/lib/autotest/bundler.rb0000444000004100000410000000031512432322455017616 0ustar www-datawww-data## # Prefix all test runs with `bundle exec` so the runs use the bundled # environment. module Autotest::Bundler Autotest.add_hook :initialize do |at| at.prefix = "bundle exec " false end end ZenTest-4.11.0/lib/autotest/isolate.rb0000444000004100000410000000055012432322455017624 0ustar www-datawww-data## # Run autotest with isolate support. module Autotest::Isolate @@dir = "tmp/isolate/#{Gem.ruby_engine}-#{RbConfig::CONFIG['ruby_version']}" def self.dir= o @@dir = o end Autotest.add_hook :initialize do |at| ENV["GEM_HOME"] = @@dir ENV["GEM_PATH"] = @@dir ENV["PATH"] += ":#{@@dir}/bin" Gem.clear_paths false end end ZenTest-4.11.0/lib/autotest/restart.rb0000444000004100000410000000063012432322455017647 0ustar www-datawww-datamodule Autotest::Restart Autotest.add_hook :initialize do |at| configs = [File.expand_path('~/.autotest'), './.autotest'].select { |f| File.exist? f } at.extra_files.concat configs false end Autotest.add_hook :updated do |at, found| unless found.flatten.grep(/\.autotest$/).empty? then warn "Detected change to .autotest, restarting" at.restart end end end ZenTest-4.11.0/lib/autotest/timestamp.rb0000444000004100000410000000025512432322455020171 0ustar www-datawww-data# -*- ruby -*- module Autotest::Timestamp Autotest.add_hook :ran_command do puts puts "# Finished at #{Time.now.strftime "%Y-%m-%d %H:%M:%S"}" puts end end ZenTest-4.11.0/lib/autotest/once.rb0000444000004100000410000000021212432322455017103 0ustar www-datawww-data## # this is for autotest plugin developers only... module Autotest::Once Autotest.add_hook :ran_command do |at| exit 0 end end ZenTest-4.11.0/lib/autotest/rcov.rb0000444000004100000410000000103512432322455017134 0ustar www-datawww-datamodule Autotest::RCov @@command, @@options = "rcov", nil def self.command= o @@command = o end def self.pattern= o warn "RCov.pattern= no longer has any functionality. please remove." end def self.options= o @@options = o end Autotest.add_hook :all_good do |at| options = @@options ? "RCOVOPTS=\"#{@@options}\"" : "" system "rake #{@@command} #{options}" false end Autotest.add_hook :initialize do |at| at.add_exception 'coverage' at.add_exception 'coverage.info' false end end ZenTest-4.11.0/lib/unit_diff.rb0000444000004100000410000001567012432322455016274 0ustar www-datawww-datarequire 'tempfile' require 'rbconfig' ## # UnitDiff makes reading Test::Unit output easy and fun. Instead of a # confusing jumble of text with nearly unnoticable changes like this: # # 1) Failure: # test_to_gpoints(RouteTest) [test/unit/route_test.rb:29]: # <"new GPolyline([\n new GPoint( 47.00000, -122.00000),\n new GPoint( 46.5000 # 0, -122.50000),\n new GPoint( 46.75000, -122.75000),\n new GPoint( 46.00000, # -123.00000)])"> expected but was # <"new Gpolyline([\n new GPoint( 47.00000, -122.00000),\n new GPoint( 46.5000 # 0, -122.50000),\n new GPoint( 46.75000, -122.75000),\n new GPoint( 46.00000, # -123.00000)])">. # # # You get an easy-to-read diff output like this: # # 1) Failure: # test_to_gpoints(RouteTest) [test/unit/route_test.rb:29]: # 1c1 # < new GPolyline([ # --- # > new Gpolyline([ # # == Usage # # test.rb | unit_diff [options] # options: # -b ignore whitespace differences # -c contextual diff # -h show usage # -k keep temp diff files around # -l prefix line numbers on the diffs # -u unified diff [default] # -p plain diff # -v display version class UnitDiff WINDOZE = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ DIFF = if WINDOZE 'diff.exe' else if system("gdiff", __FILE__, __FILE__) 'gdiff' # solaris and kin suck else 'diff' end end unless defined? DIFF ## # Handy wrapper for UnitDiff#unit_diff. def self.unit_diff trap 'INT' do exit 1 end puts UnitDiff.new.unit_diff end def parse_input(input, output) current = [] data = [] data << current print_lines = true term = "\nFinished".split(//).map { |c| c[0] } term_length = term.size old_sync = output.sync output.sync = true while line = input.gets case line when /^(Loaded suite|Started|# Running tests:)/ then print_lines = true output.puts line chars = [] while c = input.getc do output.putc c chars << c tail = chars[-term_length..-1] break if chars.size >= term_length and tail == term end output.puts input.gets # the rest of "Finished in..." output.puts next when /^\s*$/, /^\(?\s*\d+\) (Failure|Error):/, /^\d+\)/ then print_lines = false current = [] data << current when /^Finished in \d/ then print_lines = false end output.puts line if print_lines current << line end output.sync = old_sync data = data.reject { |o| o == ["\n"] or o.empty? } footer = data.pop data.map do |result| break if result.any? { |l| l =~ / expected( but was|, not)/ } header = result.find do |l| l =~ /^\(?\s*\d+\) (Failure|Error):/ end break unless header message_index = result.index(header) + 2 result[message_index..-1] = result[message_index..-1].join end return data, footer end # Parses a single diff recording the header and what # was expected, and what was actually obtained. def parse_diff(result) header = [] expect = [] butwas = [] footer = [] state = :header until result.empty? do case state when :header then header << result.shift state = :expect if result.first =~ /^<|^Expected/ when :expect then case result.first when /^Expected (.*?) to equal (.*?):$/ then expect << $1 butwas << $2 state = :footer result.shift when /^Expected (.*?), not (.*)$/m then expect << $1 butwas << $2 state = :footer result.shift when /^Expected (.*?)$/ then expect << "#{$1}\n" result.shift when /^to equal / then state = :spec_butwas bw = result.shift.sub(/^to equal (.*):?$/, '\1') butwas << bw else state = :butwas if result.first.sub!(/ expected( but was|, not)/, '') expect << result.shift end when :butwas then butwas = result[0..-1] result.clear when :spec_butwas then if result.first =~ /^\s+\S+ at |^:\s*$/ state = :footer else butwas << result.shift end when :footer then butwas.last.sub!(/:$/, '') footer = result.map {|l| l.chomp } result.clear else raise "unknown state #{state}" end end return header, expect, nil, footer if butwas.empty? expect.last.chomp! expect.first.sub!(/^<\"/, '') expect.last.sub!(/\">$/, '') butwas.last.chomp! butwas.last.chop! if butwas.last =~ /\.$/ butwas.first.sub!( /^<\"/, '') butwas.last.sub!(/\">$/, '') return header, expect, butwas, footer end ## # Scans Test::Unit output +input+ looking for comparison failures and makes # them easily readable by passing them through diff. def unit_diff(input=ARGF, output=$stdout) $b = false unless defined? $b $c = false unless defined? $c $k = false unless defined? $k $u = true unless defined? $u $p = false unless defined? $p data, footer = self.parse_input(input, output) output = [] # Output data.each do |result| if result.first =~ /Error/ then output.push result.join('') next end prefix, expect, butwas, result_footer = parse_diff(result) output.push prefix.compact.map {|line| line.strip}.join("\n") if butwas then output.push self.diff(expect, butwas) output.push result_footer output.push '' else output.push expect.join('') end end if footer then footer.shift if footer.first.strip.empty? output.push footer.compact.map {|line| line.strip}.join("\n") end return output.flatten.join("\n") end def diff expect, butwas output = nil Tempfile.open("expect") do |a| a.write(massage(expect)) a.rewind Tempfile.open("butwas") do |b| b.write(massage(butwas)) b.rewind diff_flags = $p ? "" : $c ? "-c" : "-u" diff_flags += " -b" if $b result = `#{DIFF} #{diff_flags} #{a.path} #{b.path}` result.sub!(/^\-\-\- .+/, "--- expected") result.sub!(/^\+\+\+ .+/, "+++ actual") output = if result.empty? then "[no difference--suspect ==]" else result.split(/\n/) end if $k then warn "moving #{a.path} to #{a.path}.keep" File.rename a.path, a.path + ".keep" warn "moving #{b.path} to #{b.path}.keep" File.rename b.path, b.path + ".keep" end end end output end def massage(data) # unescape newlines, strip <> from entire string data = data.join data = data.gsub(/\\n/, "\n").gsub(/0x[a-f0-9]+/m, '0xXXXXXX') + "\n" data += "\n" unless data[-1] == ?\n data end end ZenTest-4.11.0/lib/focus.rb0000444000004100000410000000105312432322455015432 0ustar www-datawww-dataclass Module def focus *wanteds wanteds.map! { |m| m.to_s } unwanteds = public_instance_methods(false).grep(/test_/).map(&:to_s) unwanteds -= wanteds unwanteds.each do |unwanted| remove_method unwanted end end def focus_re regexp focus(*public_instance_methods.grep(regexp)) end def blur parent = self.superclass ObjectSpace.each_object Class do |klass| next unless parent > klass next if klass == self klass.send :focus klass.send :undef_method, :default_test end end end ZenTest-4.11.0/lib/functional_test_matrix.rb0000444000004100000410000000634712432322455021113 0ustar www-datawww-data ######################################################################## # The Idea: # # This is supposed to get us thinking about the various dimensions our # testing should address. If there are states orthogonal to each other # (eg. readable vs unreadable, logged in vs not logged in) each of # those states should comprise a dimension in the matrix. By # addressing it this way, we should be able to minimize the amount of # setup/teardown code and get full coverage across our actions for all # these edge cases and as a result have extremely clear tests. # ######################################################################## # Example Test Matrix Specification: # # matrix :example, :edge1, :edge2, :edge3, ... # action :action1, :OK, :e_NF, :mod, ... # action :action2, :OK, :e_RO, :na, ... # action ... # ######################################################################## # Matrix: # # I envision the setups being a code that combines the different # dimensions of edge case state. # # Something for a CMS might look like: `[df]_[ugo]_[rRwW]` where: # # + `[df]` for dir/file. # + and the rest is in the style of symbolic args to chmod: # + u/g/o = user, group, or other # + lowercase `X` == `X`able, uppercase `X` == un`X`able, where `X` # is read/write. # ######################################################################## # Action: # # :new/:err/:del are just examples, they should have semantic info # attached to them. # # Use :na to specify an inapplicable edge case for that action. # # Use :OK to specify the standard positive state. It is equivalent to # a result with the same name as the action. (eg # matrix_test_index). This cleans up the matrix a lot and allows for # narrower and more readable columns. # # Edge cases specific to an action that fall outside the matrix are # regular tests. # ######################################################################## # Matrix Methods (the legos): # # Everything else basically equates to lego pieces: # # + There is one "init" method per matrix: matrix_init_#{descr}(setup_args) # + There is one "setup" method per action: matrix_setup_#{action}(setup, expect) # + There is one "test" method per result: matrix_test_#{result}(setup) # # Thus, for the matrix "example" above, the top left-most test will # end up calling: # # matrix_init_example(:edge1) # matrix_setup_action1(:edge1, :new) # matrix_test_new(:edge1) # # Read the action method for exact details. ######################################################################## module FunctionalTestMatrix def matrix(name, *setups) @@matrix, @@setups = name, setups end def action(action, *results) testcases = @@setups.zip(results).reject { |a,b| b == :na } testcases = Hash[*testcases.flatten] matrix = @@matrix # bind to local scope for define_method closure testcases.each do |setup, expected| expected_action = expected == :OK ? action : expected define_method "test_#{matrix}_#{action}_#{setup}" do @action = action send "matrix_init_#{matrix}", *setup.to_s.split(/_/).map {|c| c.intern } send "matrix_setup_#{action}", setup, expected send "matrix_test_#{expected_action}", setup end end end module_function :matrix, :action end ZenTest-4.11.0/lib/zentest_mapping.rb0000444000004100000410000000613312432322455017526 0ustar www-datawww-data## # ZenTestMapping - mapping method names from impl to test. # # Method names are mapped bidirectionally in the following way: # # method test_method # method? test_method_eh (too much exposure to Canadians :) # method! test_method_bang # method= test_method_equals # [] test_index # * test_times # == test_equals2 # === test_equals3 # # Further, any of the test methods should be able to have arbitrary # extensions put on the name to distinguish edge cases: # # method test_method # method test_method_simple # method test_method_no_network # # To allow for unmapped test methods (ie, non-unit tests), name them: # # test_integration_.* module ZenTestMapping @@orig_method_map = { '!' => 'bang', '%' => 'percent', '&' => 'and', '*' => 'times', '**' => 'times2', '+' => 'plus', '-' => 'minus', '/' => 'div', '<' => 'lt', '<=' => 'lte', '<=>' => 'spaceship', "<\<" => 'lt2', '==' => 'equals2', '===' => 'equals3', '=~' => 'equalstilde', '>' => 'gt', '>=' => 'ge', '>>' => 'gt2', '+@' => 'unary_plus', '-@' => 'unary_minus', '[]' => 'index', '[]=' => 'index_equals', '^' => 'carat', '|' => 'or', '~' => 'tilde', } @@method_map = @@orig_method_map.merge(@@orig_method_map.invert) @@mapped_re = @@orig_method_map.values.sort_by { |k| k.length }.map {|s| Regexp.escape(s) }.reverse.join("|") def munge name name = name.to_s.dup is_cls_method = name.sub!(/^self\./, '') name = @@method_map[name] if @@method_map.has_key? name name = name.sub(/=$/, '_equals') name = name.sub(/\?$/, '_eh') name = name.sub(/\!$/, '_bang') name = yield name if block_given? name = "class_" + name if is_cls_method name end # Generates a test method name from a normal method, # taking into account names composed of metacharacters # (used for arithmetic, etc def normal_to_test name "test_#{munge name}" end def unmunge name name = name.to_s.dup is_cls_method = name.sub!(/^class_/, '') name = name.sub(/_equals(_.*)?$/, '=') unless name =~ /index/ name = name.sub(/_bang(_.*)?$/, '!') name = name.sub(/_eh(_.*)?$/, '?') name = name.sub(/^(#{@@mapped_re})(_.*)?$/) {$1} name = yield name if block_given? name = @@method_map[name] if @@method_map.has_key? name name = 'self.' + name if is_cls_method name end # Converts a method name beginning with test to its # corresponding normal method name, taking into account # symbolic names which may have been anglicised by # #normal_to_test(). def test_to_normal(name, klassname=nil) unmunge(name.to_s.sub(/^test_/, '')) do |n| if defined? @inherited_methods then known_methods = (@inherited_methods[klassname] || {}).keys.sort.reverse known_methods_re = known_methods.map {|s| Regexp.escape(s) }.join("|") n = n.sub(/^(#{known_methods_re})(_.*)?$/) { $1 } unless known_methods_re.empty? n end end end end ZenTest-4.11.0/lib/autotest.rb0000555000004100000410000005527612432322455016206 0ustar www-datawww-datarequire "find" require "rbconfig" ## # Autotest continuously scans the files in your project for changes # and runs the appropriate tests. Test failures are run until they # have all passed. Then the full test suite is run to ensure that # nothing else was inadvertantly broken. # # If you want Autotest to start over from the top, hit ^C once. If # you want Autotest to quit, hit ^C twice. # # Rails: # # The autotest command will automatically discover a Rails directory # by looking for config/environment.rb. When Rails is discovered, # autotest uses RailsAutotest to perform file mappings and other work. # See RailsAutotest for details. # # Plugins: # # Plugins are available by creating a .autotest file either in your # project root or in your home directory. You can then write event # handlers in the form of: # # Autotest.add_hook hook_name { |autotest| ... } # # The available hooks are listed in +ALL_HOOKS+. # # See example_dot_autotest.rb for more details. # # If a hook returns a true value, it signals to autotest that the hook # was handled and should not continue executing hooks. # # Naming: # # Autotest uses a simple naming scheme to figure out how to map # implementation files to test files following the Test::Unit naming # scheme. # # * Test files must be stored in test/ # * Test files names must start with test_ # * Test class names must start with Test # * Implementation files must be stored in lib/ # * Implementation files must match up with a test file named # test_.*.rb # # Strategy: # # 1. Find all files and associate them from impl <-> test. # 2. Run all tests. # 3. Scan for failures. # 4. Detect changes in ANY (ruby?. file, rerun all failures + changed files. # 5. Until 0 defects, goto 3. # 6. When 0 defects, goto 2. class Autotest RUBY19 = defined? Encoding T0 = Time.at 0 ALL_HOOKS = [ :all_good, :died, :green, :initialize, :post_initialize, :interrupt, :quit, :ran_command, :red, :reset, :run_command, :updated, :waiting ] def self.options @@options ||= {} end def options self.class.options end HOOKS = Hash.new { |h,k| h[k] = [] } unless defined? WINDOZE then WINDOZE = /mswin|mingw/ =~ RbConfig::CONFIG['host_os'] SEP = WINDOZE ? '&' : ';' end @@discoveries = [] def self.parse_options args = ARGV require 'optparse' options = { :args => args.dup } OptionParser.new do |opts| opts.banner = <<-BANNER.gsub(/^ /, '') Continuous testing for your ruby app. Autotest automatically tests code that has changed. It assumes the code is in lib, and tests are in test/test_*.rb. Autotest uses plugins to control what happens. You configure plugins with require statements in the .autotest file in your project base directory, and a default configuration for all your projects in the .autotest file in your home directory. Usage: autotest [options] BANNER opts.on "-f", "--fast-start", "Do not run full tests at start" do options[:no_full_after_start] = true end opts.on("-c", "--no-full-after-failed", "Do not run all tests on red->green") do options[:no_full_after_failed] = true end opts.on "-d", "--debug", "Debug mode, for reporting bugs." do require "pp" options[:debug] = true end opts.on "-v", "--verbose", "Be annoyingly verbose (debugs .autotest)." do options[:verbose] = true end opts.on "-q", "--quiet", "Be quiet." do options[:quiet] = true end opts.on("-r", "--rc CONF", String, "Override path to config file") do |o| options[:rc] = Array(o) end opts.on("-s", "--style STYLE", String, "Manually specify test style. (default: autodiscover)") do |style| options[:style] = Array(style) end opts.on("-w", "--warnings", "Turn on ruby warnings") do $-w = true end opts.on "-h", "--help", "Show this." do puts opts exit 1 end end.parse! args Autotest.options.merge! options options end ## # Calculates the autotest runner to use to run the tests. # # Can be overridden with --style, otherwise uses ::autodiscover. def self.runner style = options[:style] || Autotest.autodiscover target = Autotest unless style.empty? then mod = "autotest/#{style.join "_"}" puts "loading #{mod}" begin require mod rescue LoadError abort "Autotest style #{mod} doesn't seem to exist. Aborting." end target = Autotest.const_get(style.map {|s| s.capitalize}.join) end target end ## # Add a proc to the collection of discovery procs. See # +autodiscover+. def self.add_discovery &proc @@discoveries << proc end ## # Automatically find all potential autotest runner styles by # searching your loadpath, vendor/plugins, and rubygems for # "autotest/discover.rb". If found, that file is loaded and it # should register discovery procs with autotest using # +add_discovery+. That proc should return one or more strings # describing the user's current environment. Those styles are then # combined to dynamically invoke an autotest plugin to suite your # environment. That plugin should define a subclass of Autotest with # a corresponding name. # # === Process: # # 1. All autotest/discover.rb files loaded. # 2. Those procs determine your styles (eg ["rails", "rspec"]). # 3. Require file by sorting styles and joining (eg 'autotest/rails_rspec'). # 4. Invoke run method on appropriate class (eg Autotest::RailsRspec.run). # # === Example autotest/discover.rb: # # Autotest.add_discovery do # "rails" if File.exist? 'config/environment.rb' # end # def self.autodiscover require 'rubygems' # *sigh* # # This is needed for rspec's hacky discovery mechanism. For some # reason rspec2 added generators that create # "autotest/discover.rb" right in the project directory instead of # keeping it in the rspec gem and properly deciding that the # project is an rspec based project or not. See the url for more # details: # # http://rubyforge.org/tracker/?func=detail&atid=1678&aid=28775&group_id=419 # # For the record, the sane way to do it is the bacon way: # # "Since version 1.0, there is autotest support. You need to tag # your test directories (test/ or spec/) by creating an .bacon # file there. Autotest then will find it." # # I'm submitting a counter-patch to rspec to fix stuff properly, # but for now I'm stuck with this because their brokenness is # documented in multiple books. # # I'm removing this code once a sane rspec goes out. hacky_discovery = Gem::Specification.any? { |s| s.name =~ /^rspec/ } $: << '.' if hacky_discovery Gem.find_files("autotest/discover").each do |f| load f end # call all discovery procs and determine the style to use @@discoveries.map{ |proc| proc.call }.flatten.compact.sort.uniq end ## # Initialize and run the system. def self.run new.run end attr_writer :known_files attr_accessor :completed_re attr_accessor :extra_class_map attr_accessor :extra_files attr_accessor :failed_results_re attr_accessor :files_to_test attr_accessor :find_directories attr_accessor :find_order attr_accessor :interrupted attr_accessor :last_mtime attr_accessor :latest_results attr_accessor :libs attr_accessor :order # TODO: deprecate and remove attr_accessor :output attr_accessor :prefix attr_accessor :results attr_accessor :sleep attr_accessor :tainted attr_accessor :test_mappings attr_accessor :testlib attr_accessor :testprefix attr_accessor :unit_diff attr_accessor :wants_to_quit alias tainted? tainted ## # Initialize the instance and then load the user's .autotest file, if any. def initialize # these two are set directly because they're wrapped with # add/remove/clear accessor methods @exception_list = [] @child = nil self.test_mappings = [] self.completed_re = /\d+ (tests|runs), \d+ assertions, \d+ failures, \d+ errors(, \d+ skips)?/ self.extra_class_map = {} self.extra_files = [] self.failed_results_re = /^\s*\d+\) (?:Failure|Error):\n(.*?)(?: [\(\[](.*?)[\)\]])?:$/ self.files_to_test = new_hash_of_arrays self.find_order = [] self.known_files = nil self.libs = %w[. lib test].join(File::PATH_SEPARATOR) self.order = :random self.output = $stderr self.prefix = nil self.sleep = 1 self.testlib = "minitest/autorun" # TODO: rename self.testprefix = "gem 'minitest'" # TODO: rename specified_directories = ARGV.reject { |arg| arg.start_with?("-") } # options are not directories self.find_directories = specified_directories.empty? ? ['.'] : specified_directories self.unit_diff = nil self.latest_results = nil # file in /lib -> run test in /test self.add_mapping(/^lib\/.*\.rb$/) do |filename, _| possible = File.basename(filename).gsub '_', '_?' files_matching %r%^test/.*#{possible}$% end # file in /test -> run it self.add_mapping(/^test.*\/test_.*rb$/) do |filename, _| filename end default_configs = [File.expand_path('~/.autotest'), './.autotest'] configs = options[:rc] || default_configs configs.each do |f| load f if File.exist? f end end def debug find_files_to_test puts "Known test files:" puts pp files_to_test.keys.sort class_map = self.class_map puts puts "Known class map:" puts pp class_map end def class_map class_map = Hash[*self.find_order.grep(/^test/).map { |f| # TODO: ugly [path_to_classname(f), f] }.flatten] class_map.merge! self.extra_class_map class_map end ## # Repeatedly run failed tests, then all tests, then wait for changes # and carry on until killed. def run hook :initialize hook :post_initialize reset add_sigint_handler self.last_mtime = Time.now if options[:no_full_after_start] self.debug if options[:debug] loop do begin # ^c handler get_to_green if tainted? and not options[:no_full_after_failed] then rerun_all_tests else hook :all_good end wait_for_changes rescue Interrupt break if wants_to_quit reset end end hook :quit puts rescue Exception => err hook(:died, err) or ( warn "Unhandled exception: #{err}" warn err.backtrace.join("\n ") warn "Quitting" ) end ## # Keep running the tests after a change, until all pass. def get_to_green begin run_tests wait_for_changes unless all_good end until all_good end ## # Look for files to test then run the tests and handle the results. def run_tests new_mtime = self.find_files_to_test return unless new_mtime self.last_mtime = new_mtime cmd = self.make_test_cmd self.files_to_test return if cmd.empty? hook :run_command, cmd puts cmd unless options[:quiet] old_sync = $stdout.sync $stdout.sync = true self.results = [] line = [] begin open "| #{cmd}", "r" do |f| until f.eof? do c = f.getc or break if RUBY19 then print c else putc c end line << c if c == ?\n then self.results << if RUBY19 then line.join else line.pack "c*" end line.clear end end end ensure $stdout.sync = old_sync end hook :ran_command self.results = self.results.join handle_results self.results end ############################################################ # Utility Methods, not essential to reading of logic ## # Installs a sigint handler. def add_sigint_handler trap 'INT' do Process.kill "KILL", @child if @child if self.interrupted then self.wants_to_quit = true else unless hook :interrupt then puts "Interrupt a second time to quit" self.interrupted = true Kernel.sleep 1.5 end raise Interrupt, nil # let the run loop catch it end end end ## # Installs a sigquit handler def add_sigquit_handler trap 'QUIT' do restart end end def restart Process.kill "KILL", @child if @child cmd = [$0, *options[:args]] index = $LOAD_PATH.index RbConfig::CONFIG["sitelibdir"] if index then extra = $LOAD_PATH[0...index] cmd = [Gem.ruby, "-I", extra.join(":")] + cmd end puts cmd.join(" ") if options[:verbose] exec(*cmd) end ## # If there are no files left to test (because they've all passed), # then all is good. def all_good files_to_test.empty? end ## # Convert a path in a string, s, into a class name, changing # underscores to CamelCase, etc. def path_to_classname s sep = File::SEPARATOR f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split sep f = f.map { |path| path.split(/_|(\d+)/).map { |seg| seg.capitalize }.join } f = f.map { |path| path =~ /^Test/ ? path : "Test#{path}" } f.join '::' end ## # Returns a hash mapping a file name to the known failures for that # file. def consolidate_failures failed filters = new_hash_of_arrays class_map = self.class_map failed.each do |method, klass| if class_map.has_key? klass then filters[class_map[klass]] << method else output.puts "Unable to map class #{klass} to a file" end end filters end ## # Find the files to process, ignoring temporary files, source # configuration management files, etc., and return a Hash mapping # filename to modification time. def find_files result = {} targets = self.find_directories + self.extra_files self.find_order.clear targets.each do |target| order = [] Find.find target do |f| Find.prune if f =~ self.exceptions Find.prune if f =~ /^\.\/tmp/ # temp dir, used by isolate next unless File.file? f next if f =~ /(swp|~|rej|orig)$/ # temporary/patch files next if f =~ /(,v)$/ # RCS files next if f =~ /\/\.?#/ # Emacs autosave/cvs merge files filename = f.sub(/^\.\//, '') result[filename] = File.stat(filename).mtime rescue next order << filename end self.find_order.push(*order.sort) end result end ## # Find the files which have been modified, update the recorded # timestamps, and use this to update the files to test. Returns # the latest mtime of the files modified or nil when nothing was # modified. def find_files_to_test files = find_files updated = files.select { |filename, mtime| self.last_mtime < mtime } # nothing to update or initially run unless updated.empty? || self.last_mtime.to_i == 0 then p updated if options[:verbose] hook :updated, updated end updated.map { |f,m| test_files_for f }.flatten.uniq.each do |filename| self.files_to_test[filename] # creates key with default value end if updated.empty? then nil else files.values.max end end ## # Check results for failures, set the "bar" to red or green, and if # there are failures record this. def handle_results results results = results.gsub(/\e\[\d+m/, '') # strip ascii color failed = results.scan(self.failed_results_re).map { |m, k| k, m = $1, $2 if m =~ /(\w+)\#(\w+)/ # minitest 5 output [m, k] } completed = results[self.completed_re] if completed then completed = completed.scan(/(\d+) (\w+)/).map { |v, k| [k, v.to_i] } self.latest_results = Hash[*completed.flatten] self.files_to_test = consolidate_failures failed color = failed.empty? ? :green : :red hook color else self.latest_results = nil end self.tainted = true unless self.files_to_test.empty? end ## # Lazy accessor for the known_files hash. def known_files unless @known_files then @known_files = {} find_order.each {|f| @known_files[f] = true } end @known_files end ## # Generate the commands to test the supplied files def make_test_cmd files_to_test if options[:debug] then puts "Files to test:" puts pp files_to_test puts end cmds = [] full, partial = reorder(files_to_test).partition { |k,v| v.empty? } diff = self.unit_diff diff = " | #{diff}" if diff and diff !~ /^\|/ unless full.empty? then classes = full.map {|k,v| k}.flatten.uniq classes.unshift testlib classes = classes.join " " cmds << "#{ruby_cmd} -e \"#{testprefix}; %w[#{classes}].each { |f| require f }\"#{diff}" end partial.each do |klass, methods| regexp = Regexp.union(*methods).source cmds << "#{ruby_cmd} #{klass} -n \"/^(#{regexp})$/\"#{diff}" end cmds.join "#{SEP} " end def new_hash_of_arrays Hash.new { |h,k| h[k] = [] } end def reorder files_to_test case self.order when :alpha then files_to_test.sort_by { |k,v| k } when :reverse then files_to_test.sort_by { |k,v| k }.reverse when :random then max = files_to_test.size files_to_test.sort_by { |k,v| rand max } when :natural then (self.find_order & files_to_test.keys).map { |f| [f, files_to_test[f]] } else raise "unknown order type: #{self.order.inspect}" end end ## # Rerun the tests from cold (reset state) def rerun_all_tests reset run_tests hook :all_good if all_good end ## # Clear all state information about test failures and whether # interrupts will kill autotest. def reset self.files_to_test.clear self.find_order.clear self.interrupted = false self.known_files = nil self.last_mtime = T0 self.tainted = false self.wants_to_quit = false hook :reset end ## # Determine and return the path of the ruby executable. def ruby ruby = ENV['RUBY'] ruby ||= File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) ruby.gsub! File::SEPARATOR, File::ALT_SEPARATOR if File::ALT_SEPARATOR return ruby end ## # Returns the base of the ruby command. def ruby_cmd "#{prefix}#{ruby} -I#{libs} -rubygems" end ## # Return the name of the file with the tests for filename by finding # a +test_mapping+ that matches the file and executing the mapping's # proc. def test_files_for filename result = [] self.test_mappings.each do |file_re, proc| if filename =~ file_re then result = [proc.call(filename, $~)]. flatten.sort.uniq.select { |f| known_files[f] } break unless result.empty? end end pp :test_file_for => [filename, result.first] if result and options[:debug] output.puts "No tests matched #{filename}" if options[:verbose] and result.empty? return result end ## # Sleep then look for files to test, until there are some. def wait_for_changes hook :waiting Kernel.sleep self.sleep until find_files_to_test end ############################################################ # File Mappings: ## # Returns all known files in the codebase matching +regexp+. def files_matching regexp self.find_order.select { |k| k =~ regexp } end ## # Adds a file mapping, optionally prepending the mapping to the # front of the list if +prepend+ is true. +regexp+ should match a # file path in the codebase. +proc+ is passed a matched filename and # Regexp.last_match. +proc+ should return an array of tests to run. # # For example, if test_helper.rb is modified, rerun all tests: # # at.add_mapping(/test_helper.rb/) do |f, _| # at.files_matching(/^test.*rb$/) # end def add_mapping regexp, prepend = false, &proc if prepend then @test_mappings.unshift [regexp, proc] else @test_mappings.push [regexp, proc] end nil end ## # Removed a file mapping matching +regexp+. def remove_mapping regexp @test_mappings.delete_if do |k,v| k == regexp end nil end ## # Clears all file mappings. This is DANGEROUS as it entirely # disables autotest. You must add at least one file mapping that # does a good job of rerunning appropriate tests. def clear_mappings @test_mappings.clear nil end ############################################################ # Exceptions: ## # Adds +regexp+ to the list of exceptions for find_file. This must # be called _before_ the exceptions are compiled. def add_exception regexp raise "exceptions already compiled" if defined? @exceptions @exception_list << regexp nil end ## # Removes +regexp+ to the list of exceptions for find_file. This # must be called _before_ the exceptions are compiled. def remove_exception regexp raise "exceptions already compiled" if defined? @exceptions @exception_list.delete regexp nil end ## # Clears the list of exceptions for find_file. This must be called # _before_ the exceptions are compiled. def clear_exceptions raise "exceptions already compiled" if defined? @exceptions @exception_list.clear nil end ## # Return a compiled regexp of exceptions for find_files or nil if no # filtering should take place. This regexp is generated from # +exception_list+. def exceptions unless defined? @exceptions then @exceptions = if @exception_list.empty? then nil else Regexp.union(*@exception_list) end end @exceptions end ############################################################ # Hooks: ## # Call the event hook named +name+, passing in optional args # depending on the hook itself. # # Returns false if no hook handled the event. # # === Hook Writers! # # This executes all registered hooks until one returns truthy. # Pay attention to the return value of your block! def hook name, *args deprecated = { # none currently } if deprecated[name] and not HOOKS[name].empty? then warn "hook #{name} has been deprecated, use #{deprecated[name]}" end HOOKS[name].any? { |plugin| plugin[self, *args] } end ## # Add the supplied block to the available hooks, with the given # name. def self.add_hook name, &block HOOKS[name] << block end end ZenTest-4.11.0/metadata.yml0000644000004100000410000001244212432322455015531 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: ZenTest version: !ruby/object:Gem::Version version: 4.11.0 platform: ruby authors: - Ryan Davis - Eric Hodel autorequire: bindir: bin cert_chain: - | -----BEGIN CERTIFICATE----- MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB GRYDY29tMB4XDTE0MDkxNzIzMDcwN1oXDTE1MDkxNzIzMDcwN1owRTETMBEGA1UE AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB AQAFoDJRokCQdxFfOrmsKX41KOFlU/zjrbDVM9hgB/Ur999M6OXGSi8FitXNtMwY FVjsiAPeU7HaWVVcZkj6IhINelTkXsxgGz/qCzjHy3iUMuZWw36cS0fiWJ5rvH+e hD7uXxJSFuyf1riDGI1aeWbQ74WMwvNstOxLUMiV5a1fzBhlxPqb537ubDjq/M/h zPUFPVYeL5KjDHLCqI2FwIk2sEMOQgjpXHzl+3NlD2LUgUhHDMevmgVua0e2GT1B xJcC6UN6NHMOVMyAXsr2HR0gRRx4ofN1LoP2KhXzSr8UMvQYlwPmE0N5GQv1b5AO VpzF30vNaJK6ZT7xlIsIlwmH -----END CERTIFICATE----- date: 2014-09-27 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: minitest requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '5.4' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '5.4' - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '4.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '4.0' - !ruby/object:Gem::Dependency name: hoe requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '3.13' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '3.13' description: |- ZenTest provides 4 different tools: zentest, unit_diff, autotest, and multiruby. zentest scans your target and unit-test code and writes your missing code based on simple naming rules, enabling XP at a much quicker pace. zentest only works with Ruby and Minitest or Test::Unit. There is enough evidence to show that this is still proving useful to users, so it stays. unit_diff is a command-line filter to diff expected results from actual results and allow you to quickly see exactly what is wrong. Do note that minitest 2.2+ provides an enhanced assert_equal obviating the need for unit_diff autotest is a continous testing facility meant to be used during development. As soon as you save a file, autotest will run the corresponding dependent tests. multiruby runs anything you want on multiple versions of ruby. Great for compatibility checking! Use multiruby_setup to manage your installed versions. email: - ryand-ruby@zenspider.com - drbrain@segment7.net executables: - autotest - multigem - multiruby - multiruby_setup - unit_diff - zentest extensions: [] extra_rdoc_files: - History.txt - Manifest.txt - README.txt - articles/how_to_use_zentest.txt - example.txt files: - .autotest - .gemtest - History.txt - Manifest.txt - README.txt - Rakefile - articles/Article.css - articles/getting_started_with_autotest.html - articles/how_to_use_zentest.txt - bin/autotest - bin/multigem - bin/multiruby - bin/multiruby_setup - bin/unit_diff - bin/zentest - example.txt - example1.rb - example2.rb - example_dot_autotest.rb - lib/autotest.rb - lib/autotest/autoupdate.rb - lib/autotest/bundler.rb - lib/autotest/isolate.rb - lib/autotest/once.rb - lib/autotest/preload.rb - lib/autotest/rcov.rb - lib/autotest/restart.rb - lib/autotest/timestamp.rb - lib/focus.rb - lib/functional_test_matrix.rb - lib/multiruby.rb - lib/unit_diff.rb - lib/zentest.rb - lib/zentest_mapping.rb - test/test_autotest.rb - test/test_focus.rb - test/test_unit_diff.rb - test/test_zentest.rb - test/test_zentest_mapping.rb homepage: https://github.com/seattlerb/zentest licenses: - MIT metadata: {} post_install_message: rdoc_options: - --main - README.txt require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.8' - - < - !ruby/object:Gem::Version version: '3.0' requirements: [] rubyforge_project: rubygems_version: 2.4.1 signing_key: specification_version: 4 summary: 'ZenTest provides 4 different tools: zentest, unit_diff, autotest, and multiruby' test_files: - test/test_autotest.rb - test/test_focus.rb - test/test_unit_diff.rb - test/test_zentest.rb - test/test_zentest_mapping.rb ZenTest-4.11.0/test/0000755000004100000410000000000012432322455014202 5ustar www-datawww-dataZenTest-4.11.0/test/test_zentest_mapping.rb0000444000004100000410000002176112432322455021002 0ustar www-datawww-data$TESTING = true require 'rubygems' require 'minitest/autorun' require 'zentest_mapping' unless defined? $ZENTEST class Dummy attr_accessor :inherited_methods include ZenTestMapping end class TestZentestMapping < Minitest::Test def setup @tester = Dummy.new end def util_simple_setup klasses = { "Something" => { "method1" => true, "method1!" => true, "method1=" => true, "method1?" => true, "attrib" => true, "attrib=" => true, "equal?" => true, "self.method3" => true, "self.[]" => true, }, } test_klasses = { "TestSomething" => { "test_class_method4" => true, "test_method2" => true, "setup" => true, "teardown" => true, "test_class_index" => true, }, } @tester.inherited_methods = test_klasses.merge(klasses) @generated_code = " require 'test/unit' unless defined? $ZENTEST and $ZENTEST class Something def self.method4(*args) raise NotImplementedError, 'Need to write self.method4' end def method2(*args) raise NotImplementedError, 'Need to write method2' end end class TestSomething < Test::Unit::TestCase def test_class_method3 raise NotImplementedError, 'Need to write test_class_method3' end def test_attrib raise NotImplementedError, 'Need to write test_attrib' end def test_attrib_equals raise NotImplementedError, 'Need to write test_attrib_equals' end def test_equal_eh raise NotImplementedError, 'Need to write test_equal_eh' end def test_method1 raise NotImplementedError, 'Need to write test_method1' end def test_method1_bang raise NotImplementedError, 'Need to write test_method1_bang' end def test_method1_eh raise NotImplementedError, 'Need to write test_method1_eh' end def test_method1_equals raise NotImplementedError, 'Need to write test_method1_equals' end end # Number of errors detected: 10 " end def test_normal_to_test self.util_simple_setup assert_equal("test_method1", @tester.normal_to_test("method1")) assert_equal("test_method1_bang", @tester.normal_to_test("method1!")) assert_equal("test_method1_eh", @tester.normal_to_test("method1?")) assert_equal("test_method1_equals", @tester.normal_to_test("method1=")) end def test_normal_to_test_cls self.util_simple_setup assert_equal("test_class_method1", @tester.normal_to_test("self.method1")) assert_equal("test_class_method1_bang", @tester.normal_to_test("self.method1!")) assert_equal("test_class_method1_eh", @tester.normal_to_test("self.method1?")) assert_equal("test_class_method1_equals", @tester.normal_to_test("self.method1=")) end def test_normal_to_test_operators self.util_simple_setup assert_equal("test_and", @tester.normal_to_test("&")) assert_equal("test_bang", @tester.normal_to_test("!")) assert_equal("test_carat", @tester.normal_to_test("^")) assert_equal("test_div", @tester.normal_to_test("/")) assert_equal("test_equalstilde", @tester.normal_to_test("=~")) assert_equal("test_minus", @tester.normal_to_test("-")) assert_equal("test_or", @tester.normal_to_test("|")) assert_equal("test_percent", @tester.normal_to_test("%")) assert_equal("test_plus", @tester.normal_to_test("+")) assert_equal("test_tilde", @tester.normal_to_test("~")) end def test_normal_to_test_overlap self.util_simple_setup assert_equal("test_equals2", @tester.normal_to_test("==")) assert_equal("test_equals3", @tester.normal_to_test("===")) assert_equal("test_ge", @tester.normal_to_test(">=")) assert_equal("test_gt", @tester.normal_to_test(">")) assert_equal("test_gt2", @tester.normal_to_test(">>")) assert_equal("test_index", @tester.normal_to_test("[]")) assert_equal("test_index_equals", @tester.normal_to_test("[]=")) assert_equal("test_lt", @tester.normal_to_test("<")) assert_equal("test_lt2", @tester.normal_to_test("<\<")) assert_equal("test_lte", @tester.normal_to_test("<=")) assert_equal("test_method", @tester.normal_to_test("method")) assert_equal("test_method_equals", @tester.normal_to_test("method=")) assert_equal("test_spaceship", @tester.normal_to_test("<=>")) assert_equal("test_times", @tester.normal_to_test("*")) assert_equal("test_times2", @tester.normal_to_test("**")) assert_equal("test_unary_minus", @tester.normal_to_test("-@")) assert_equal("test_unary_plus", @tester.normal_to_test("+@")) assert_equal("test_class_index", @tester.normal_to_test("self.[]")) end def test_test_to_normal self.util_simple_setup assert_equal("method1!", @tester.test_to_normal("test_method1_bang", "Something")) assert_equal("method1", @tester.test_to_normal("test_method1", "Something")) assert_equal("method1=", @tester.test_to_normal("test_method1_equals", "Something")) assert_equal("method1?", @tester.test_to_normal("test_method1_eh", "Something")) end def test_test_to_normal_cls self.util_simple_setup assert_equal("self.method1", @tester.test_to_normal("test_class_method1")) assert_equal("self.method1!", @tester.test_to_normal("test_class_method1_bang")) assert_equal("self.method1?", @tester.test_to_normal("test_class_method1_eh")) assert_equal("self.method1=", @tester.test_to_normal("test_class_method1_equals")) assert_equal("self.[]", @tester.test_to_normal("test_class_index")) end def test_test_to_normal_extended self.util_simple_setup assert_equal("equal?", @tester.test_to_normal("test_equal_eh_extension", "Something")) assert_equal("equal?", @tester.test_to_normal("test_equal_eh_extension_again", "Something")) assert_equal("method1", @tester.test_to_normal("test_method1_extension", "Something")) assert_equal("method1", @tester.test_to_normal("test_method1_extension_again", "Something")) end def test_test_to_normal_mapped self.util_simple_setup assert_equal("*", @tester.test_to_normal("test_times")) assert_equal("*", @tester.test_to_normal("test_times_ext")) assert_equal("==", @tester.test_to_normal("test_equals2")) assert_equal("==", @tester.test_to_normal("test_equals2_ext")) assert_equal("===", @tester.test_to_normal("test_equals3")) assert_equal("===", @tester.test_to_normal("test_equals3_ext")) assert_equal("[]", @tester.test_to_normal("test_index")) assert_equal("[]", @tester.test_to_normal("test_index_ext")) assert_equal("[]=", @tester.test_to_normal("test_index_equals")) assert_equal("[]=", @tester.test_to_normal("test_index_equals_ext")) end def test_test_to_normal_operators self.util_simple_setup assert_equal("&", @tester.test_to_normal("test_and")) assert_equal("!", @tester.test_to_normal("test_bang")) assert_equal("^", @tester.test_to_normal("test_carat")) assert_equal("/", @tester.test_to_normal("test_div")) assert_equal("=~", @tester.test_to_normal("test_equalstilde")) assert_equal("-", @tester.test_to_normal("test_minus")) assert_equal("|", @tester.test_to_normal("test_or")) assert_equal("%", @tester.test_to_normal("test_percent")) assert_equal("+", @tester.test_to_normal("test_plus")) assert_equal("~", @tester.test_to_normal("test_tilde")) end def test_test_to_normal_overlap self.util_simple_setup assert_equal("==", @tester.test_to_normal("test_equals2")) assert_equal("===", @tester.test_to_normal("test_equals3")) assert_equal(">=", @tester.test_to_normal("test_ge")) assert_equal(">", @tester.test_to_normal("test_gt")) assert_equal(">>", @tester.test_to_normal("test_gt2")) assert_equal("[]", @tester.test_to_normal("test_index")) assert_equal("[]=", @tester.test_to_normal("test_index_equals")) assert_equal("<", @tester.test_to_normal("test_lt")) assert_equal("<\<", @tester.test_to_normal("test_lt2")) assert_equal("<=", @tester.test_to_normal("test_lte")) assert_equal("<=>", @tester.test_to_normal("test_spaceship")) assert_equal("*", @tester.test_to_normal("test_times")) assert_equal("**", @tester.test_to_normal("test_times2")) assert_equal("-@", @tester.test_to_normal("test_unary_minus")) assert_equal("+@", @tester.test_to_normal("test_unary_plus")) end def test_to_normal_subset self.util_simple_setup assert_equal("get_foo", @tester.test_to_normal("test_get_foo")) end end ZenTest-4.11.0/test/test_zentest.rb0000555000004100000410000004102512432322455017265 0ustar www-datawww-data#!/usr/local/bin/ruby -w abort "rubinius does not support features required by zentest" if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/ $TESTING = true require 'rubygems' require 'minitest/autorun' # I do this so I can still run ZenTest against the tests and itself... require 'zentest' unless defined? $ZENTEST # These are just classes set up for quick testing. # TODO: need to test a compound class name Mod::Cls class Cls1 # ZenTest SKIP def meth1; end def self.meth2; end end class TestCls1 # ZenTest SKIP def setup; end def teardown; end def test_meth1; end def test_meth2; assert(true, "something"); end end class SuperDuper # ZenTest SKIP def self.cls_inherited; end def inherited; end def overridden; end end class LowlyOne < SuperDuper # ZenTest SKIP def self.cls_xtended; end def overridden; end def xtended; end # renamed because maglev defines it globally :/ def pretty_print; end def pretty_print_cycle; end end # This is the good case where there are no missing methods on either side. class Blah0 def missingtest; end def notmissing1; end def notmissing2; end # found by zentest on testcase1.rb def missingimpl; end end class TestBlah0 def setup; end def teardown; end def test_notmissing1 assert(true, "a test") end def test_notmissing2_ext1 assert(true, "a test") end def test_notmissing2_ext2 flunk("a failed test") end def test_missingimpl; end def test_missingtest; end end class Blah1 def missingtest; end def notmissing1; end def notmissing2; end end class TestBlah1 def test_notmissing1; end def test_notmissing2_ext1; end def test_notmissing2_ext2; end def test_missingimpl; Blah1.new.missingimpl; end def test_integration_blah1; end def test_integration_blah2; end def test_integration_blah3; end end module Something2 class Blah2 def missingtest; end def notmissing1; end def notmissing2; end end end module TestSomething2 class TestBlah2 def test_notmissing1; end def test_notmissing2_ext1; end def test_notmissing2_ext2; end def test_missingimpl; end end end # only test classes class TestBlah3 def test_missingimpl; end end # only regular classes class Blah4 def missingtest1; end def missingtest2; end end # subclassing a builtin class class MyHash5 < Hash def []; end def missingtest1; end end # nested class module MyModule6 class MyClass6 def []; end def missingtest1; end end end # nested class module MyModule7; end # in 1.9+ you'll not need this class MyModule7::MyClass7 def []; end def missingtest1; end end class MyClass8 def self.foobar; end def MyClass8.foobaz; end end class TestTrueClass; end class TestZenTest < Minitest::Test def setup @tester = ZenTest.new() end ############################################################ # Utility Methods def util_simple_setup @tester.klasses = { "Something" => { "method1" => true, "method1!" => true, "method1=" => true, "method1?" => true, "attrib" => true, "attrib=" => true, "equal?" => true, "self.method3" => true, "self.[]" => true, }, } @tester.test_klasses = { "TestSomething" => { "test_class_method4" => true, "test_method2" => true, "setup" => true, "teardown" => true, "test_class_index" => true, }, } @tester.inherited_methods = @tester.test_klasses.merge(@tester.klasses) @generated_code = " require 'minitest/autorun' class Something def self.method4(*args) raise NotImplementedError, 'Need to write self.method4' end def method2(*args) raise NotImplementedError, 'Need to write method2' end end class TestSomething < Minitest::Test def test_class_method3 raise NotImplementedError, 'Need to write test_class_method3' end def test_attrib raise NotImplementedError, 'Need to write test_attrib' end def test_attrib_equals raise NotImplementedError, 'Need to write test_attrib_equals' end def test_equal_eh raise NotImplementedError, 'Need to write test_equal_eh' end def test_method1 raise NotImplementedError, 'Need to write test_method1' end def test_method1_bang raise NotImplementedError, 'Need to write test_method1_bang' end def test_method1_eh raise NotImplementedError, 'Need to write test_method1_eh' end def test_method1_equals raise NotImplementedError, 'Need to write test_method1_equals' end end # Number of errors detected: 10 " end ############################################################ # Accessors & Adders: def test_initialize refute_nil(@tester, "Tester must be initialized") # TODO: should do more at this stage end ############################################################ # Converters and Testers: def test_is_test_class # classes assert(@tester.is_test_class(TestCls1), "All test classes must start with Test") assert(!@tester.is_test_class(Cls1), "Classes not starting with Test must not be test classes") # strings assert(@tester.is_test_class("TestCls1"), "All test classes must start with Test") assert(@tester.is_test_class("TestMod::TestCls1"), "All test modules must start with test as well") assert(!@tester.is_test_class("Cls1"), "Classes not starting with Test must not be test classes") assert(!@tester.is_test_class("NotTestMod::TestCls1"), "Modules not starting with Test must not be test classes") assert(!@tester.is_test_class("NotTestMod::NotTestCls1"), "All names must start with Test to be test classes") end def test_is_test_class_reversed old = $r $r = true assert(@tester.is_test_class("Cls1Test"), "Reversed: All test classes must end with Test") assert(@tester.is_test_class("ModTest::Cls1Test"), "Reversed: All test classes must end with Test") assert(!@tester.is_test_class("TestMod::TestCls1"), "Reversed: All test classes must end with Test") $r = old end def test_convert_class_name assert_equal('Cls1', @tester.convert_class_name(TestCls1)) assert_equal('TestCls1', @tester.convert_class_name(Cls1)) assert_equal('Cls1', @tester.convert_class_name('TestCls1')) assert_equal('TestCls1', @tester.convert_class_name('Cls1')) assert_equal('TestModule::TestCls1', @tester.convert_class_name('Module::Cls1')) assert_equal('Module::Cls1', @tester.convert_class_name('TestModule::TestCls1')) end def test_convert_class_name_reversed old = $r $r = true assert_equal('Cls1', @tester.convert_class_name("Cls1Test")) assert_equal('Cls1Test', @tester.convert_class_name(Cls1)) assert_equal('Cls1', @tester.convert_class_name('Cls1Test')) assert_equal('Cls1Test', @tester.convert_class_name('Cls1')) assert_equal('ModuleTest::Cls1Test', @tester.convert_class_name('Module::Cls1')) assert_equal('Module::Cls1', @tester.convert_class_name('ModuleTest::Cls1Test')) $r = old end ############################################################ # Missing Classes and Methods: def test_missing_methods_empty missing = @tester.missing_methods assert_equal({}, missing) end def test_add_missing_method_normal @tester.add_missing_method("SomeClass", "some_method") missing = @tester.missing_methods assert_equal({"SomeClass" => { "some_method" => true } }, missing) end def test_add_missing_method_duplicates @tester.add_missing_method("SomeClass", "some_method") @tester.add_missing_method("SomeClass", "some_method") @tester.add_missing_method("SomeClass", "some_method") missing = @tester.missing_methods assert_equal({"SomeClass" => { "some_method" => true } }, missing) end def test_analyze_simple self.util_simple_setup @tester.analyze missing = @tester.missing_methods expected = { "Something" => { "method2" => true, "self.method4" => true, }, "TestSomething" => { "test_class_method3" => true, "test_attrib" => true, "test_attrib_equals" => true, "test_equal_eh" => true, "test_method1" => true, "test_method1_eh"=>true, "test_method1_bang"=>true, "test_method1_equals"=>true, } } assert_equal(expected, missing) end def test_create_method list = @tester.create_method(" ", 1, "wobble") assert_equal([" def wobble(*args)", " raise NotImplementedError, 'Need to write wobble'", " end"],list) end def test_methods_and_tests @tester.process_class("ZenTest") @tester.process_class("TestZenTest") m,t = @tester.methods_and_tests("ZenTest", "TestZenTest") assert(m.include?("methods_and_tests")) assert(t.include?("test_methods_and_tests")) end def test_generate_code_simple self.util_simple_setup @tester.analyze str = @tester.generate_code[1..-1].join("\n") exp = @generated_code assert_equal(exp, str) end def test_get_class_good assert_equal(Object, @tester.get_class("Object")) end def test_get_class_bad assert_nil(@tester.get_class("ZZZObject")) end def test_get_inherited_methods_for_subclass expect = { "inherited" => true, "overridden" => true } result = @tester.get_inherited_methods_for("LowlyOne", false) assert_equal(expect, result) end def test_get_inherited_methods_for_subclass_full expect = Object.instance_methods + %w( inherited overridden ) expect.map! { |m| m.to_s } result = @tester.get_inherited_methods_for("LowlyOne", true) assert_equal(expect.sort, result.keys.sort) end def test_get_inherited_methods_for_superclass expect = { } result = @tester.get_inherited_methods_for("SuperDuper", false) assert_equal(expect.keys.sort, result.keys.sort) end def test_get_inherited_methods_for_superclass_full expect = Object.instance_methods.map { |m| m.to_s } result = @tester.get_inherited_methods_for("SuperDuper", true) assert_equal(expect.sort, result.keys.sort) end def test_get_methods_for_subclass expect = { "self.cls_xtended" => true, "overridden" => true, "xtended" => true } result = @tester.get_methods_for("LowlyOne") assert_equal(expect, result) end def test_get_methods_for_subclass_full expect = { "self.cls_inherited" => true, "self.cls_xtended" => true, "overridden" => true, "xtended" => true } result = @tester.get_methods_for("LowlyOne", true) assert_equal(expect, result) end def test_get_methods_for_superclass expect = { "self.cls_inherited" => true, "overridden" => true, "inherited" => true } result = @tester.get_methods_for("SuperDuper") assert_equal(expect, result) end def test_result self.util_simple_setup @tester.analyze @tester.generate_code str = @tester.result.split($/, 2).last exp = @generated_code assert_equal(exp, str) end def test_load_file skip 'Need to write test_load_file' end def test_scan_files skip 'Need to write test_scan_files' end def test_process_class assert_equal({}, @tester.klasses) assert_equal({}, @tester.test_klasses) assert_equal({}, @tester.inherited_methods["SuperDuper"]) @tester.process_class("SuperDuper") assert_equal({"SuperDuper"=> { "self.cls_inherited"=>true, "inherited"=>true, "overridden"=>true}}, @tester.klasses) assert_equal({}, @tester.test_klasses) assert_equal({}, @tester.inherited_methods["SuperDuper"]) end def test_klasses_equals self.util_simple_setup assert_equal({"Something"=> { "self.method3"=>true, "equal?"=>true, "attrib="=>true, "self.[]"=>true, "method1"=>true, "method1="=>true, "method1?"=>true, "method1!"=>true, "method1"=>true, "attrib"=>true}}, @tester.klasses) @tester.klasses= {"whoopie" => {}} assert_equal({"whoopie"=> {}}, @tester.klasses) end # REFACTOR: this should probably be cleaned up and on ZenTest side def util_testcase(*klasses) zentest = ZenTest.new klasses.each do |klass| zentest.process_class(klass) end zentest.analyze zentest.generate_code return zentest.result.split("\n")[1..-1].join("\n") end def test_testcase0 expected = '# Number of errors detected: 0' assert_equal expected, util_testcase("Blah0", "TestBlah0") end HEADER = "\nrequire 'minitest/autorun'\n\n" def test_testcase1 expected = "#{HEADER}class Blah1\n def missingimpl(*args)\n raise NotImplementedError, 'Need to write missingimpl'\n end\nend\n\nclass TestBlah1 < Minitest::Test\n def test_missingtest\n raise NotImplementedError, 'Need to write test_missingtest'\n end\nend\n\n# Number of errors detected: 2" assert_equal expected, util_testcase("Blah1", "TestBlah1") end def test_testcase2 expected = "#{HEADER}class Something2::Blah2\n def missingimpl(*args)\n raise NotImplementedError, 'Need to write missingimpl'\n end\nend\n\nclass TestSomething2::TestBlah2 < Minitest::Test\n def test_missingtest\n raise NotImplementedError, 'Need to write test_missingtest'\n end\nend\n\n# Number of errors detected: 2" assert_equal expected, util_testcase("Something2::Blah2", "TestSomething2::TestBlah2") end def test_testcase3 expected = "#{HEADER}class Blah3\n def missingimpl(*args)\n raise NotImplementedError, 'Need to write missingimpl'\n end\nend\n\n# Number of errors detected: 1" assert_equal expected, util_testcase("TestBlah3") end def test_testcase4 expected = "#{HEADER}class TestBlah4 < Minitest::Test\n def test_missingtest1\n raise NotImplementedError, 'Need to write test_missingtest1'\n end\n\n def test_missingtest2\n raise NotImplementedError, 'Need to write test_missingtest2'\n end\nend\n\n# Number of errors detected: 3" assert_equal expected, util_testcase("Blah4") end def test_testcase5 expected = "#{HEADER}class TestMyHash5 < Minitest::Test\n def test_index\n raise NotImplementedError, 'Need to write test_index'\n end\n\n def test_missingtest1\n raise NotImplementedError, 'Need to write test_missingtest1'\n end\nend\n\n# Number of errors detected: 3" assert_equal expected, util_testcase("MyHash5") end def test_testcase6 expected = "#{HEADER}class TestMyModule6::TestMyClass6 < Minitest::Test\n def test_index\n raise NotImplementedError, 'Need to write test_index'\n end\n\n def test_missingtest1\n raise NotImplementedError, 'Need to write test_missingtest1'\n end\nend\n\n# Number of errors detected: 3" assert_equal expected, util_testcase("MyModule6::MyClass6") end def test_testcase7 expected = "#{HEADER}class TestMyModule7::TestMyClass7 < Minitest::Test\n def test_index\n raise NotImplementedError, 'Need to write test_index'\n end\n\n def test_missingtest1\n raise NotImplementedError, 'Need to write test_missingtest1'\n end\nend\n\n# Number of errors detected: 3" assert_equal expected, util_testcase("MyModule7::MyClass7") end def test_testcase8 expected = "#{HEADER}class TestMyClass8 < Minitest::Test\n def test_class_foobar\n raise NotImplementedError, 'Need to write test_class_foobar'\n end\n\n def test_class_foobaz\n raise NotImplementedError, 'Need to write test_class_foobaz'\n end\nend\n\n# Number of errors detected: 3" assert_equal expected, util_testcase("MyClass8") end def test_testcase9 skip "doesn't define to_s on TrueClass?!?" if maglev? # stupid YAML is breaking my tests. Enters via Test::Rails. order dependent. if defined? YAML then TrueClass.send :remove_method, :taguri, :taguri=, :to_yaml rescue nil end pims = TrueClass.public_instance_methods(false) TrueClass.send :remove_method, :inspect if pims.include? :inspect # 2.0 only expected = "#{HEADER}class TestTrueClass < Minitest::Test\n def test_and\n raise NotImplementedError, 'Need to write test_and'\n end\n\n def test_carat\n raise NotImplementedError, 'Need to write test_carat'\n end\n\n def test_or\n raise NotImplementedError, 'Need to write test_or'\n end\n\n def test_to_s\n raise NotImplementedError, 'Need to write test_to_s'\n end\nend\n\n# Number of errors detected: 4" assert_equal expected, util_testcase("TestTrueClass") end end ZenTest-4.11.0/test/test_unit_diff.rb0000555000004100000410000003370612432322455017547 0ustar www-datawww-data#!/usr/local/bin/ruby -w require 'rubygems' require 'minitest/autorun' require 'stringio' $TESTING = true require 'unit_diff' class TestUnitDiff < Minitest::Test def setup @diff = UnitDiff.new end def test_input header = "Loaded suite ./blah\nStarted\nFF\nFinished in 0.035332 seconds.\n\n" input = "#{header} 1) Failure:\ntest_test1(TestBlah) [./blah.rb:25]:\n<\"line1\\nline2\\nline3\\n\"> expected but was\n<\"line4\\nline5\\nline6\\n\">.\n\n 2) Failure:\ntest_test2(TestBlah) [./blah.rb:29]:\n<\"line1\"> expected but was\n<\"line2\\nline3\\n\\n\">.\n\n2 tests, 2 assertions, 2 failures, 0 errors\n" # TODO: I think I'd like a separate footer array as well expected = [[[" 1) Failure:\n", "test_test1(TestBlah) [./blah.rb:25]:\n", "<\"line1\\nline2\\nline3\\n\"> expected but was\n", "<\"line4\\nline5\\nline6\\n\">.\n"], [" 2) Failure:\n", "test_test2(TestBlah) [./blah.rb:29]:\n", "<\"line1\"> expected but was\n", "<\"line2\\nline3\\n\\n\">.\n"]], ["\n", "2 tests, 2 assertions, 2 failures, 0 errors\n"]] util_unit_diff(header, input, expected, :parse_input) end def test_input_miniunit header = "Loaded suite -e\nStarted\nF\nFinished in 0.035332 seconds.\n\n" input = "#{header} 1) Failure: test_blah(TestBlah) [./blah.rb:25]: Expected ['a', 'b', 'c'], not ['a', 'c', 'b']. 1 tests, 1 assertions, 1 failures, 0 errors " expected = [[[" 1) Failure:\n", "test_blah(TestBlah) [./blah.rb:25]:\n", "Expected ['a', 'b', 'c'], not ['a', 'c', 'b'].\n"]], ["\n", "1 tests, 1 assertions, 1 failures, 0 errors\n"]] util_unit_diff(header, input, expected, :parse_input) end def test_input_miniunit_multiline header = "Loaded suite -e\nStarted\nF\nFinished in 0.035332 seconds.\n\n" input = "#{header} 1) Failure: test_blah(TestBlah) [./blah.rb:25]: Expected ['a', 'b', 'c'], not ['a', 'c', 'b']. 1 tests, 1 assertions, 1 failures, 0 errors " expected = [[[" 1) Failure:\n", "test_blah(TestBlah) [./blah.rb:25]:\n", "Expected ['a',\n 'b',\n 'c'], not ['a',\n 'c',\n 'b'].\n"]], ["\n", "1 tests, 1 assertions, 1 failures, 0 errors\n"]] util_unit_diff(header, input, expected, :parse_input) end def test_input_mspec header = <<-HEADER Started .......F Finished in 0.1 seconds HEADER failure = <<-FAILURE 1) The unless expression should fail FAILED Expected nil to equal "baz": FAILURE backtrace = <<-BACKTRACE PositiveExpectation#== at spec/mspec.rb:217 main.__script__ {} at spec/language/unless_spec.rb:49 Proc#call at kernel/core/proc.rb:127 SpecRunner#it at spec/mspec.rb:368 main.it at spec/mspec.rb:412 main.__script__ {} at spec/language/unless_spec.rb:48 Proc#call at kernel/core/proc.rb:127 SpecRunner#describe at spec/mspec.rb:378 main.describe at spec/mspec.rb:408 main.__script__ at spec/language/unless_spec.rb:3 CompiledMethod#as_script at kernel/bootstrap/primitives.rb:41 main.load at kernel/core/compile.rb:150 main.__script__ {} at last_mspec.rb:11 Array#each {} at kernel/core/array.rb:545 Integer(Fixnum)#times at kernel/core/integer.rb:15 Array#each at kernel/core/array.rb:545 main.__script__ at last_mspec.rb:16 CompiledMethod#as_script at kernel/bootstrap/primitives.rb:41 main.load at kernel/core/compile.rb:150 main.__script__ at kernel/loader.rb:145 BACKTRACE footer = "\n8 examples, 1 failures\n" input = header + failure + backtrace + footer expected_backtrace = backtrace.split("\n").map {|l| "#{l}\n"} expected = [[["1)\n", "The unless expression should fail FAILED\n", "Expected nil to equal \"baz\":\n", *expected_backtrace]], ["\n", "8 examples, 1 failures\n"]] util_unit_diff(header, input, expected, :parse_input) end def test_input_mspec_multiline header = <<-HEADER Started .......F Finished in 0.1 seconds HEADER failure = <<-FAILURE 1) Compiler compiles a case without an argument FAILED Expected #], [:push_literal, "foo"], [:string_dup], [:goto, #