chaser 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{chaser}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrew Grimm", "Ryan Davis", "Eric Hodel", "Kevin Clark"]
12
- s.date = %q{2009-11-14}
12
+ s.date = %q{2009-11-15}
13
13
  s.default_executable = %q{chaser}
14
14
  s.description = %q{Lightweight mutation testing in any flavor of ruby}
15
15
  s.email = %q{andrew.j.grimm@gmail.com}
@@ -17,7 +17,7 @@ class Chaser
17
17
  ##
18
18
  # The version of Chaser you are using.
19
19
 
20
- VERSION = '0.0.2'
20
+ VERSION = '0.0.3'
21
21
 
22
22
  ##
23
23
  # Is this platform MS Windows-like?
@@ -142,25 +142,43 @@ class Chaser
142
142
  def unmodify_instance_method
143
143
  chaser = self
144
144
  @mutated = false
145
- @klass.send(:define_method, @method_name) do |*args|
146
- chaser.old_method.bind(self).call(*args)
145
+ chaser_proxy_method_name = "__chaser_proxy__#{@method_name}"
146
+ @klass.send(:define_method, chaser_proxy_method_name) do |block, *args|
147
+ chaser.old_method.bind(self).call(*args) {|*yielded_values| block.call(*yielded_values)}
147
148
  end
148
149
  end
149
150
 
150
151
  def unmodify_class_method
151
152
  chaser = self
152
153
  @mutated = false
153
- aliasing_class(@method_name).send(:define_method, clean_method_name) do |*args|
154
- chaser.old_method.bind(self).call(*args)
154
+ chaser_proxy_method_name = "__chaser_proxy__#{clean_method_name}"
155
+ aliasing_class(@method_name).send(:define_method, chaser_proxy_method_name) do |block, *args|
156
+ chaser.old_method.bind(self).call(*args) {|*yielded_values| block.call(*yielded_values)}
155
157
  end
156
158
  end
157
159
 
160
+ # Ruby 1.8 doesn't allow define_method to handle blocks.
161
+ # The blog post http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/
162
+ # show that define_method has problems, and showed how to do workaround_method_code_string
158
163
  def modify_instance_method
159
164
  chaser = self
160
165
  @mutated = true
161
166
  @old_method = @klass.instance_method(@method_name)
162
- @klass.send(:define_method, @method_name) do |*args|
163
- chaser.mutate_value(chaser.old_method.bind(self).call(*args))
167
+ chaser_proxy_method_name = "__chaser_proxy__#{@method_name}"
168
+ workaround_method_code_string = <<-EOM
169
+ def #{@method_name}(*args, &block)
170
+ #{chaser_proxy_method_name}(block, *args)
171
+ end
172
+ EOM
173
+ @klass.class_eval do
174
+ eval(workaround_method_code_string)
175
+ end
176
+ @klass.send(:define_method, chaser_proxy_method_name) do |block, *args|
177
+ original_value = chaser.old_method.bind(self).call(*args) do |*yielded_values|
178
+ mutated_yielded_values = yielded_values.map{|value| chaser.mutate_value(value)}
179
+ block.call(*mutated_yielded_values)
180
+ end
181
+ chaser.mutate_value(original_value)
164
182
  end
165
183
  end
166
184
 
@@ -168,8 +186,21 @@ class Chaser
168
186
  chaser = self
169
187
  @mutated = true
170
188
  @old_method = aliasing_class(@method_name).instance_method(clean_method_name)
171
- aliasing_class(@method_name).send(:define_method, clean_method_name) do |*args|
172
- chaser.mutate_value(chaser.old_method.bind(self).call(*args))
189
+ chaser_proxy_method_name = "__chaser_proxy__#{clean_method_name}"
190
+ workaround_method_code_string = <<-EOM
191
+ def #{@method_name}(*args, &block)
192
+ #{chaser_proxy_method_name}(block, *args)
193
+ end
194
+ EOM
195
+ @klass.class_eval do
196
+ eval(workaround_method_code_string)
197
+ end
198
+ aliasing_class(@method_name).send(:define_method, chaser_proxy_method_name) do |block, *args|
199
+ original_value = chaser.old_method.bind(self).call(*args) do |*yielded_values|
200
+ mutated_yielded_values = yielded_values.map{|value| chaser.mutate_value(value)}
201
+ block.call(*mutated_yielded_values)
202
+ end
203
+ chaser.mutate_value(original_value)
173
204
  end
174
205
  end
175
206
 
@@ -10,4 +10,31 @@ class Chased
10
10
  def self.static_method
11
11
  "Zap!"
12
12
  end
13
+
14
+ def block_using_instance_method
15
+ result = []
16
+ block_yielding_instance_method do |i|
17
+ result << i * 2
18
+ end
19
+ result
20
+ end
21
+
22
+ def block_yielding_instance_method
23
+ yield 1
24
+ yield 2
25
+ yield 3
26
+ end
27
+
28
+ def self.block_using_class_method
29
+ result = []
30
+ block_yielding_class_method do |i|
31
+ result << i * 2
32
+ end
33
+ result
34
+ end
35
+
36
+ def self.block_yielding_class_method
37
+ yield 1
38
+ yield 2
39
+ end
13
40
  end
@@ -71,6 +71,26 @@ class ChaserTestCase < Test::Unit::TestCase
71
71
  assert_equal "Zap!", Chased.static_method, "class method should be back to normal, but it isn't"
72
72
  end
73
73
 
74
+ def test_pass_blocks_on_in_instance_methods
75
+ @chaser = TestChaser.new("Chased", "block_yielding_instance_method")
76
+ chased = Chased.new
77
+ assert_equal [2,4,6], chased.block_using_instance_method, "block yielding instance method has been modified before it should have been"
78
+ @chaser.modify_method
79
+ assert_equal [12, 14, 16], chased.block_using_instance_method, "yielded values haven't been modified"
80
+ @chaser.unmodify_method
81
+ assert_equal [2,4,6], chased.block_using_instance_method, "block yielding instance method has been modified before it should have been"
82
+ end
83
+
84
+ def test_pass_blocks_on_in_class_methods
85
+ @chaser = TestChaser.new("Chased", "self.block_yielding_class_method")
86
+ assert_equal [2,4], Chased.block_using_class_method, "block yielding class method has been modified before it should have been"
87
+ @chaser.modify_method
88
+ assert_equal [12, 14], Chased.block_using_class_method, "yielded values haven't been modified"
89
+ @chaser.unmodify_method
90
+ assert_equal [2,4], Chased.block_using_class_method, "block yielding class method has been modified before it should have been"
91
+ end
92
+
93
+
74
94
  end
75
95
 
76
96
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chaser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Grimm
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2009-11-14 00:00:00 +11:00
15
+ date: 2009-11-15 00:00:00 +11:00
16
16
  default_executable: chaser
17
17
  dependencies: []
18
18