From 273e59bf9f2518407a8983b3d5c85b4e6f077aca Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Sun, 14 Jan 2007 08:52:44 -0800 Subject: [PATCH] Class method support [git-p4: depot-paths = "//src/heckle/dev/": change = 2904] --- History.txt | 5 +++- lib/heckle.rb | 57 +++++++++++++++++++++++-------------- lib/test_unit_heckler.rb | 13 ++++++--- sample/lib/heckled.rb | 4 +++ sample/test/test_heckled.rb | 4 +++ test/fixtures/heckled.rb | 4 +++ test/test_heckle.rb | 34 ++++++++++++++++++++++ 7 files changed, 94 insertions(+), 27 deletions(-) diff --git a/History.txt b/History.txt index 422109c..1627c1d 100644 --- a/History.txt +++ b/History.txt @@ -1,7 +1,10 @@ == svn * 1 minor enhancement * -b allows heckling of branches only - +* 2 major enhancement + * Timeout for tests set dynamically and overridable with -T + * Class method support with "self.method_name" + == 1.1.1 / 2006-12-20 * 3 bug fixes: diff --git a/lib/heckle.rb b/lib/heckle.rb index c77010a..19f9064 100644 --- a/lib/heckle.rb +++ b/lib/heckle.rb @@ -10,7 +10,7 @@ def to_class end class Heckle < SexpProcessor - VERSION = '1.1.1' + VERSION = '1.1.2' MUTATABLE_NODES = [:if, :lit, :str, :true, :false, :while, :until] WINDOZE = RUBY_PLATFORM =~ /mswin/ NULL_PATH = WINDOZE ? 'NUL:' : '/dev/null' @@ -38,28 +38,32 @@ def self.guess_timeout? def initialize(klass_name=nil, method_name=nil, reporter = Reporter.new) super() - - @klass_name, @method_name = klass_name, method_name.intern - @klass = @method = nil + + @klass_name = klass_name + @method_name = method_name.intern if method_name + + @klass = klass_name.to_class + + @method = nil @reporter = reporter - + self.strict = false self.auto_shift_type = true self.expected = Array - + @mutatees = Hash.new @mutation_count = Hash.new @node_count = Hash.new @count = 0 - + MUTATABLE_NODES.each {|type| @mutatees[type] = [] } - + @failures = [] - + @mutated = false - + grab_mutatees - + @original_tree = current_tree.deep_clone @original_mutatees = mutatees.deep_clone end @@ -127,13 +131,19 @@ def heckle(exp) raise e end @reporter.replacing(klass_name, method_name, src) if @@debug - klass = klass_name.to_class + + clean_name = method_name.to_s.gsub(/self\./, '') + self.count += 1 - new_name = "#{method_name}_#{count}" - klass.send :undef_method, new_name rescue nil - klass.send :alias_method, new_name, method_name - klass.class_eval(src) + new_name = "#{clean_name}_#{count}" + + aliasing_class = (method_name.to_s =~ /self\./) ? (class << @klass; self end) : @klass + + aliasing_class.send :undef_method, new_name rescue nil + aliasing_class.send :alias_method, new_name, clean_name + + @klass.class_eval(src) end ############################################################ @@ -259,13 +269,16 @@ def reset_tree return unless original_tree != current_tree @mutated = false - klass = klass_name.to_class - self.count += 1 - new_name = "#{method_name}_#{count}" - klass.send :undef_method, new_name rescue nil - klass.send :alias_method, new_name, method_name - klass.send :alias_method, method_name, "#{method_name}_1" + + clean_name = method_name.to_s.gsub(/self\./, '') + new_name = "#{clean_name}_#{count}" + + aliasing_class = (method_name.to_s =~ /self\./) ? (class << @klass; self end) : @klass + + aliasing_class.send :undef_method, new_name rescue nil + aliasing_class.send :alias_method, new_name, clean_name + aliasing_class.send :alias_method, clean_name, "#{clean_name}_1" end def reset_mutatees diff --git a/lib/test_unit_heckler.rb b/lib/test_unit_heckler.rb index 4023238..c20dfea 100644 --- a/lib/test_unit_heckler.rb +++ b/lib/test_unit_heckler.rb @@ -20,8 +20,9 @@ def self.load_test_files def self.validate(klass_name, method_name = nil) load_test_files klass = klass_name.to_class - + initial_time = Time.now + unless self.new(klass_name).tests_pass? then abort "Initial run of tests failed... fix and run heckle again" end @@ -35,9 +36,13 @@ def self.validate(klass_name, method_name = nil) end puts "Initial tests pass. Let's rumble." - - methods = method_name ? Array(method_name) : klass.instance_methods(false) - + self.timeout = adjusted_timeout + + puts "Initial tests pass. Let's rumble." + + klass_methods = klass.singleton_methods(false).collect {|meth| "self.#{meth}"} + methods = method_name ? Array(method_name) : klass.instance_methods(false) + klass_methods + methods.each do |method_name| self.new(klass_name, method_name).validate end diff --git a/sample/lib/heckled.rb b/sample/lib/heckled.rb index ce4c8e2..025248c 100644 --- a/sample/lib/heckled.rb +++ b/sample/lib/heckled.rb @@ -5,6 +5,10 @@ def initialize @names = [] end + def self.is_a_klass_method? + true + end + def uses_while i = 1 while i < 10 diff --git a/sample/test/test_heckled.rb b/sample/test/test_heckled.rb index c375731..60b081e 100644 --- a/sample/test/test_heckled.rb +++ b/sample/test/test_heckled.rb @@ -20,4 +20,8 @@ def test_uses_strings def test_uses_infinite_loop @heckled.uses_infinite_loop? end + + def test_is_a_klass_method + assert_equal true, Heckled.is_a_klass_method? + end end \ No newline at end of file diff --git a/test/fixtures/heckled.rb b/test/fixtures/heckled.rb index cf46d95..d72e461 100644 --- a/test/fixtures/heckled.rb +++ b/test/fixtures/heckled.rb @@ -95,6 +95,10 @@ def uses_ranges def uses_nothing end + + def self.is_a_klass_method? + true + end private diff --git a/test/test_heckle.rb b/test/test_heckle.rb index 5ba8913..6a9bdcc 100644 --- a/test/test_heckle.rb +++ b/test/test_heckle.rb @@ -385,3 +385,37 @@ def test_flips_until_to_while assert_equal expected, @heckler.current_tree end end + +class TestHeckleClassMethod < Test::Unit::TestCase + def setup + @heckler = TestHeckler.new("Heckled", "self.is_a_klass_method?") + end + + def teardown + @heckler.reset + end + + def test_default_structure + expected = [:defn, :"self.is_a_klass_method?", + [:scope, + [:block, + [:args], + [:true]]]] + assert_equal expected, @heckler.current_tree + end + + def test_heckle_class_methods + expected = [:defn, :"self.is_a_klass_method?", + [:scope, + [:block, + [:args], + [:false]]]] + @heckler.process(@heckler.current_tree) + assert_equal expected, @heckler.current_tree + end +end + + + + + \ No newline at end of file