heckle 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ module Heckle
2
+ class Reporter
3
+ def no_mutations(method_name)
4
+ puts
5
+ puts "!"*70
6
+ puts "!!! #{method_name} has a thick skin. There's nothing to heckle."
7
+ puts "!"*70
8
+ puts
9
+ end
10
+
11
+ def method_loaded(klass_name, method_name, mutations_left)
12
+ puts
13
+ puts "*"*70
14
+ puts "*** #{klass_name}\##{method_name} loaded with #{mutations_left} possible mutations"
15
+ puts "*"*70
16
+ puts
17
+ end
18
+
19
+ def remaining_mutations(mutations_left)
20
+ puts "#{mutations_left} mutations remaining..."
21
+ end
22
+
23
+ def no_failures
24
+ puts "\nThe following mutations didn't cause test failures:\n"
25
+ end
26
+
27
+ def failure(failure)
28
+ puts "\n#{failure}\n"
29
+ end
30
+
31
+ def no_surviving_mutants
32
+ puts "No mutants survived. Cool!\n\n"
33
+ end
34
+
35
+ def replacing(klass_name, method_name, src)
36
+ puts "Replacing #{klass_name}##{method_name} with:\n\n#{src}\n"
37
+ end
38
+
39
+ def report_test_failures
40
+ puts "Tests failed -- this is good"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit/autorunner'
4
+ require 'heckle'
5
+
6
+ class TestUnitHeckler < Heckle::Base
7
+ @@test_pattern = 'test/test_*.rb'
8
+ @@tests_loaded = false;
9
+
10
+ def self.test_pattern=(value)
11
+ @@test_pattern = value
12
+ end
13
+
14
+ def self.load_test_files
15
+ @@tests_loaded = true
16
+ Dir.glob(@@test_pattern).each {|test| require test}
17
+ end
18
+
19
+ def self.validate(klass_name)
20
+ load_test_files
21
+ klass = klass_name.to_class
22
+ klass.instance_methods(false).each do |method_name|
23
+ heckler = self.new(klass_name, method_name)
24
+ heckler.test_and_validate
25
+ end
26
+ end
27
+
28
+ def initialize(klass_name=nil, method_name=nil)
29
+ super(klass_name, method_name)
30
+ self.class.load_test_files unless @@tests_loaded
31
+ end
32
+
33
+ def test_and_validate
34
+ if silence_stream(STDOUT) { tests_pass? } then
35
+ puts "Initial tests pass. Let's rumble."
36
+ validate
37
+ else
38
+ puts "Tests failed... fix and run heckle again"
39
+ end
40
+ end
41
+
42
+ def tests_pass?
43
+ Test::Unit::AutoRunner.run
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ # -*- ruby -*-
2
+ require 'rubygems'
3
+ require 'rake/testtask'
4
+
5
+ task :default => :test
6
+
7
+ desc "Run basic tests"
8
+ Rake::TestTask.new { |t|
9
+ t.pattern = 'test/test_*.rb'
10
+ t.verbose = true
11
+ t.warning = true
12
+ }
13
+
14
+
15
+
16
+ # vim: syntax=Ruby
@@ -0,0 +1,91 @@
1
+ # Logfile created on Fri Nov 10 22:52:10 PST 2006 by logger.rb/1.5.2.7
2
+ I, [2006-11-10T22:52:10.310486 #498] INFO -- : Validating
3
+ I, [2006-11-10T22:52:10.326577 #498] INFO -- : Heckling Heckled#uses_strings
4
+ I, [2006-11-10T22:52:10.328115 #498] INFO -- : Replacing #uses_strings with:
5
+ def uses_strings
6
+ (@names << "I\rmeo&+eIZ{bD2dj1Z_e\001{Y!](CbI'!`@\020Wlg4,w\t\02181/4J\t\v@][ L!Xy[\r\\MJ[0.+gh}\001ks\026_-BK")
7
+ (@names << "Hello, Jeff")
8
+ (@names << "Hi, Frank")
9
+ end
10
+ I, [2006-11-10T22:52:10.344547 #498] INFO -- : Heckling Heckled#uses_strings
11
+ I, [2006-11-10T22:52:10.346021 #498] INFO -- : Replacing #uses_strings with:
12
+ def uses_strings
13
+ (@names << "Hello, Robert")
14
+ (@names << "\030ym+3\f:\031\023`\r:O\a")
15
+ (@names << "Hi, Frank")
16
+ end
17
+ I, [2006-11-10T22:52:10.356743 #498] INFO -- : Heckling Heckled#uses_strings
18
+ I, [2006-11-10T22:52:10.358234 #498] INFO -- : Replacing #uses_strings with:
19
+ def uses_strings
20
+ (@names << "Hello, Robert")
21
+ (@names << "Hello, Jeff")
22
+ (@names << "o,NY\020\027V0v\032dEw\010<*4\026uh$\026\010vhl(A\"ybX$sd\"M\006qbH\032TAV/")
23
+ end
24
+ I, [2006-11-10T22:52:10.369174 #498] INFO -- : Heckling Heckled#uses_strings
25
+ I, [2006-11-10T22:52:10.370636 #498] INFO -- : Replacing #uses_strings with:
26
+ def uses_strings
27
+ (@names << "Hello, Robert")
28
+ (@names << "Hello, Jeff")
29
+ (@names << "Hi, Frank")
30
+ end
31
+ I, [2006-11-10T23:17:54.953429 #569] INFO -- : Validating
32
+ I, [2006-11-10T23:19:05.369315 #570] INFO -- : Validating
33
+ I, [2006-11-10T23:20:01.512545 #571] INFO -- : Validating
34
+ I, [2006-11-10T23:20:08.080030 #572] INFO -- : Validating
35
+ I, [2006-11-10T23:20:08.100363 #572] INFO -- : Heckling Heckled#uses_strings
36
+ I, [2006-11-10T23:20:08.101943 #572] INFO -- : Replacing #uses_strings with:
37
+ def uses_strings
38
+ (@names << "\034\000\021[\r\aM!L=qfU'#")
39
+ (@names << "Hello, Jeff")
40
+ (@names << "Hi, Frank")
41
+ end
42
+ I, [2006-11-10T23:20:08.120455 #572] INFO -- : Heckling Heckled#uses_strings
43
+ I, [2006-11-10T23:20:08.122176 #572] INFO -- : Replacing #uses_strings with:
44
+ def uses_strings
45
+ (@names << "Hello, Robert")
46
+ (@names << "\r\025 $\n<z\037Z5<VSsja\026/\t>(&6P^X<\000\t..[<QGM\036\ei$\010RL\030J.vEsJ,")
47
+ (@names << "Hi, Frank")
48
+ end
49
+ I, [2006-11-10T23:20:08.141360 #572] INFO -- : Heckling Heckled#uses_strings
50
+ I, [2006-11-10T23:20:08.143164 #572] INFO -- : Replacing #uses_strings with:
51
+ def uses_strings
52
+ (@names << "Hello, Robert")
53
+ (@names << "Hello, Jeff")
54
+ (@names << ":\032lTh\031\037sw8\004!d\021\017n8\"\f8ucDs:.H\026n\010Bb|Is?p\027XR<4+%qfQ|^(\022\aN\024<e)\023P_a.j\000(\037bRe\"&xIO\001\f5\021o?\005\a\034)V@WmAb|\001(Z\020\032")
55
+ end
56
+ I, [2006-11-10T23:20:08.162167 #572] INFO -- : Heckling Heckled#uses_strings
57
+ I, [2006-11-10T23:20:08.163769 #572] INFO -- : Replacing #uses_strings with:
58
+ def uses_strings
59
+ (@names << "Hello, Robert")
60
+ (@names << "Hello, Jeff")
61
+ (@names << "Hi, Frank")
62
+ end
63
+ I, [2006-11-10T23:20:30.047573 #574] INFO -- : Validating
64
+ I, [2006-11-10T23:20:30.064031 #574] INFO -- : Heckling Heckled#uses_strings
65
+ I, [2006-11-10T23:20:30.065826 #574] INFO -- : Replacing #uses_strings with:
66
+ def uses_strings
67
+ (@names << "B]ms\026*\025\034\035%\026d_!\023\017c8\f\v\003G\fSAdh\025kC8&!,1sc\032htACl6\023rgq[j\016J>\003$I\025\037\001\027E$/P\025<Uu+#MCN%.mGFw\005qje 1D\037{wQL")
68
+ (@names << "Hello, Jeff")
69
+ (@names << "Hi, Frank")
70
+ end
71
+ I, [2006-11-10T23:20:30.076369 #574] INFO -- : Heckling Heckled#uses_strings
72
+ I, [2006-11-10T23:20:30.078079 #574] INFO -- : Replacing #uses_strings with:
73
+ def uses_strings
74
+ (@names << "Hello, Robert")
75
+ (@names << "A\002\tu<:r\021L\n`yArP\010\032]n\n\036+@?sh\e\020\023{\027I<t+QbD\000\006:3{w\f\\XCH\032\026xSogO\036)*B_E\034;\016\\Mj")
76
+ (@names << "Hi, Frank")
77
+ end
78
+ I, [2006-11-10T23:20:30.089013 #574] INFO -- : Heckling Heckled#uses_strings
79
+ I, [2006-11-10T23:20:30.090484 #574] INFO -- : Replacing #uses_strings with:
80
+ def uses_strings
81
+ (@names << "Hello, Robert")
82
+ (@names << "Hello, Jeff")
83
+ (@names << "Z\023C#\025qg{Cb++W\r\\dtEbq4P2c")
84
+ end
85
+ I, [2006-11-10T23:20:30.101238 #574] INFO -- : Heckling Heckled#uses_strings
86
+ I, [2006-11-10T23:20:30.102788 #574] INFO -- : Replacing #uses_strings with:
87
+ def uses_strings
88
+ (@names << "Hello, Robert")
89
+ (@names << "Hello, Jeff")
90
+ (@names << "Hi, Frank")
91
+ end
@@ -0,0 +1,63 @@
1
+ class Heckled
2
+ attr_accessor :names
3
+
4
+ def initialize
5
+ @names = []
6
+ end
7
+
8
+ def uses_while
9
+ i = 1
10
+ while i < 10
11
+ i += 1
12
+ end
13
+ i
14
+ end
15
+
16
+ def uses_until
17
+ i = 1
18
+ until i >= 10
19
+ i += 1
20
+ end
21
+ i
22
+ end
23
+
24
+ def uses_numeric_literals
25
+ i = 1
26
+ i += 10
27
+ i -= 3.5
28
+ end
29
+
30
+ def uses_strings
31
+ @names << "Hello, Robert"
32
+ @names << "Hello, Jeff"
33
+ @names << "Hi, Frank"
34
+ end
35
+
36
+ def uses_different_types
37
+ i = 1
38
+ b = "Hello, Joe"
39
+ c = 3.3
40
+ end
41
+
42
+ def uses_the_same_literal
43
+ i = 1
44
+ i = 1
45
+ i = 1
46
+ end
47
+
48
+ def uses_if
49
+ if true
50
+ if false
51
+ return
52
+ end
53
+ end
54
+ end
55
+
56
+ def uses_unless
57
+ unless true
58
+ if false
59
+ return
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Kevin Clark on 2006-11-10.
4
+ # Copyright (c) 2006. All rights reserved.
5
+
6
+ require "test/unit"
7
+
8
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
9
+ require "heckled"
10
+
11
+ class TestHeckled < Test::Unit::TestCase
12
+ def setup
13
+ @heckled = Heckled.new
14
+ end
15
+ def test_uses_strings
16
+ @heckled.uses_strings
17
+ assert_equal ["Hello, Robert", "Hello, Jeff", "Hi, Frank"], @heckled.names
18
+ end
19
+ end
@@ -0,0 +1,103 @@
1
+ class Heckled
2
+ attr_accessor :names
3
+
4
+ def initialize
5
+ @names = []
6
+ end
7
+
8
+ def uses_many_things
9
+ i = 1
10
+ while i < 10
11
+ i += 1
12
+ until some_func
13
+ some_other_func
14
+ end
15
+ return true if "hi there" == "changeling"
16
+ return false
17
+ end
18
+ i
19
+ end
20
+
21
+ def uses_while
22
+ while some_func
23
+ some_other_func
24
+ end
25
+ end
26
+
27
+ def uses_until
28
+ until some_func
29
+ some_other_func
30
+ end
31
+ end
32
+
33
+ def uses_numeric_literals
34
+ i = 1
35
+ i += 2147483648
36
+ i -= 3.5
37
+ end
38
+
39
+ def uses_strings
40
+ @names << "Hello, Robert"
41
+ @names << "Hello, Jeff"
42
+ @names << "Hi, Frank"
43
+ end
44
+
45
+ def uses_different_types
46
+ i = 1
47
+ b = "Hello, Joe"
48
+ c = 3.3
49
+ end
50
+
51
+ def uses_the_same_literal
52
+ i = 1
53
+ i = 1
54
+ i = 1
55
+ end
56
+
57
+ def uses_if
58
+ if some_func
59
+ if some_other_func
60
+ return
61
+ end
62
+ end
63
+ end
64
+
65
+ def uses_boolean
66
+ true
67
+ false
68
+ end
69
+
70
+ def uses_unless
71
+ unless true
72
+ if false
73
+ return
74
+ end
75
+ end
76
+ end
77
+
78
+ def uses_symbols
79
+ i = :blah
80
+ i = :blah
81
+ i = :and_blah
82
+ end
83
+
84
+ def uses_regexes
85
+ i = /a.*/
86
+ i = /c{2,4}+/
87
+ i = /123/
88
+ end
89
+
90
+ def uses_ranges
91
+ i = 6..100
92
+ i = -1..9
93
+ i = 1..4
94
+ end
95
+
96
+ def uses_nothing
97
+ end
98
+
99
+ private
100
+
101
+ def some_func; end
102
+ def some_other_func; end
103
+ end
@@ -1,33 +1,658 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/fixtures')
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
1
3
 
2
4
  require 'test/unit/testcase'
3
5
  require 'test/unit' if $0 == __FILE__
6
+ require 'test_unit_heckler'
7
+ require 'heckled'
4
8
 
5
9
  class TestHeckle < Test::Unit::TestCase
10
+ def setup
11
+ @heckler = Heckle::Base.new("Heckled", "uses_many_things")
12
+ end
13
+
14
+ def test_should_set_original_tree
15
+ expected = [:defn,
16
+ :uses_many_things,
17
+ [:fbody, [:scope,
18
+ [:block,
19
+ [:args],
20
+ [:lasgn, :i, [:lit, 1]],
21
+ [:while,
22
+ [:call, [:lvar, :i], :<, [:array, [:lit, 10]]],
23
+ [:block,
24
+ [:lasgn, :i, [:call, [:lvar, :i], :+, [:array, [:lit, 1]]]],
25
+ [:until, [:vcall, :some_func], [:vcall, :some_other_func], true],
26
+ [:if,
27
+ [:call, [:str, "hi there"], :==, [:array, [:str, "changeling"]]],
28
+ [:return, [:true]],
29
+ nil],
30
+ [:return, [:false]]],
31
+ true],
32
+ [:lvar, :i]]]]]
33
+
34
+ assert_equal expected, @heckler.original_tree
35
+ end
36
+
37
+ def test_should_grab_mutatees_from_method
38
+ # expected is from tree of uses_while
39
+ expected = {
40
+ :lit=>[[:lit, 1], [:lit, 10], [:lit, 1]],
41
+ :if=>[[:if,
42
+ [:call, [:str, "hi there"], :==, [:array, [:str, "changeling"]]],
43
+ [:return, [:true]],
44
+ nil]],
45
+ :str => [[:str, "hi there"], [:str, "changeling"]],
46
+ :true => [[:true]],
47
+ :false => [[:false]],
48
+ :while=>
49
+ [[:while,
50
+ [:call, [:lvar, :i], :<, [:array, [:lit, 10]]],
51
+ [:block,
52
+ [:lasgn, :i, [:call, [:lvar, :i], :+, [:array, [:lit, 1]]]],
53
+ [:until, [:vcall, :some_func], [:vcall, :some_other_func], true],
54
+ [:if,
55
+ [:call, [:str, "hi there"], :==, [:array, [:str, "changeling"]]],
56
+ [:return, [:true]],
57
+ nil],
58
+ [:return, [:false]]],
59
+ true]],
60
+ :until => [[:until, [:vcall, :some_func], [:vcall, :some_other_func], true]]
61
+ }
62
+
63
+ assert_equal expected, @heckler.mutatees
64
+ end
65
+
66
+ def test_should_count_mutatees_left
67
+ assert_equal 10, @heckler.mutations_left
68
+ end
6
69
 
7
- ############################################################
8
- # Our method under test - in here just for demo...
70
+ def test_reset
71
+ original_tree = @heckler.current_tree.deep_clone
72
+ original_mutatees = @heckler.mutatees.deep_clone
73
+
74
+ 3.times { @heckler.process(@heckler.current_tree) }
75
+
76
+ assert_not_equal original_tree, @heckler.current_tree
77
+ assert_not_equal original_mutatees, @heckler.mutatees
78
+
79
+ @heckler.reset
80
+ assert_equal original_tree[2], @heckler.current_tree[2][1]
81
+ assert_equal original_mutatees, @heckler.mutatees
82
+ end
83
+
84
+ def test_reset_tree
85
+ original_tree = @heckler.current_tree.deep_clone
86
+
87
+ @heckler.process(@heckler.current_tree)
88
+ assert_not_equal original_tree, @heckler.current_tree
89
+
90
+ @heckler.reset_tree
91
+ assert_equal original_tree, @heckler.current_tree
92
+ end
93
+
94
+ def test_reset_should_work_over_several_process_calls
95
+ original_tree = @heckler.current_tree.deep_clone
96
+ original_mutatees = @heckler.mutatees.deep_clone
97
+
98
+ @heckler.process(@heckler.current_tree)
99
+ assert_not_equal original_tree, @heckler.current_tree
100
+ assert_not_equal original_mutatees, @heckler.mutatees
101
+
102
+ @heckler.reset
103
+ assert_equal original_tree, @heckler.current_tree
104
+ assert_equal original_mutatees, @heckler.mutatees
105
+
106
+ 3.times { @heckler.process(@heckler.current_tree) }
107
+ assert_not_equal original_tree, @heckler.current_tree
108
+ assert_not_equal original_mutatees, @heckler.mutatees
109
+
110
+ @heckler.reset
111
+ assert_equal original_tree, @heckler.current_tree
112
+ assert_equal original_mutatees, @heckler.mutatees
113
+ end
114
+
115
+ def test_reset_mutatees
116
+ original_mutatees = @heckler.mutatees.deep_clone
117
+
118
+ @heckler.process(@heckler.current_tree)
119
+ assert_not_equal original_mutatees, @heckler.mutatees
120
+
121
+ @heckler.reset_mutatees
122
+ assert_equal original_mutatees, @heckler.mutatees
123
+ end
124
+
125
+ def teardown
126
+ @heckler.reset
127
+ end
128
+ end
9
129
 
10
- def many? n
11
- if n >= 3 then
12
- true
13
- else
14
- false
130
+ module Heckle
131
+ class Base
132
+ def rand(*args)
133
+ 5
134
+ end
135
+
136
+ def rand_number(*args)
137
+ 5
15
138
  end
16
139
  end
140
+ end
17
141
 
18
- ############################################################
142
+ class TestHeckleNumbers < Test::Unit::TestCase
143
+ def setup
144
+ @heckler = Heckle::Base.new("Heckled", "uses_numeric_literals")
145
+ end
146
+
147
+ def test_literals_should_flip_one_at_a_time
148
+ assert_equal 3, @heckler.mutations_left
149
+ expected = [:defn,
150
+ :uses_numeric_literals,
151
+ [:scope,
152
+ [:block,
153
+ [:args],
154
+ [:lasgn, :i, [:lit, 6]],
155
+ [:lasgn, :i, [:call, [:lvar, :i], :+, [:array, [:lit, 2147483648]]]],
156
+ [:lasgn, :i, [:call, [:lvar, :i], :-, [:array, [:lit, 3.5]]]]]]]
157
+
158
+ @heckler.process(@heckler.current_tree)
159
+ assert_equal expected, @heckler.current_tree
160
+
161
+ @heckler.reset_tree
162
+
163
+ expected = [:defn,
164
+ :uses_numeric_literals,
165
+ [:scope,
166
+ [:block,
167
+ [:args],
168
+ [:lasgn, :i, [:lit, 1]],
169
+ [:lasgn, :i, [:call, [:lvar, :i], :+, [:array, [:lit, 2147483653]]]],
170
+ [:lasgn, :i, [:call, [:lvar, :i], :-, [:array, [:lit, 3.5]]]]]]]
171
+
172
+ @heckler.process(@heckler.current_tree)
173
+ assert_equal expected, @heckler.current_tree
174
+
175
+ @heckler.reset_tree
176
+
177
+ expected = [:defn,
178
+ :uses_numeric_literals,
179
+ [:scope,
180
+ [:block,
181
+ [:args],
182
+ [:lasgn, :i, [:lit, 1]],
183
+ [:lasgn, :i, [:call, [:lvar, :i], :+, [:array, [:lit, 2147483648]]]],
184
+ [:lasgn, :i, [:call, [:lvar, :i], :-, [:array, [:lit, 8.5]]]]]]]
185
+
186
+ @heckler.process(@heckler.current_tree)
187
+ assert_equal expected, @heckler.current_tree
188
+ end
19
189
 
20
- if false then
21
- def test_many_eh_good
22
- assert ! many?(0)
23
- assert ! many?(1)
24
- assert many?(3)
190
+ def teardown
191
+ @heckler.reset
192
+ end
193
+ end
194
+
195
+ module Heckle
196
+ class Base
197
+ def rand_symbol
198
+ :"l33t h4x0r"
25
199
  end
26
- else
27
- def test_many_eh_bad
28
- # obviously bad - need a better example for my demo
200
+ end
201
+ end
202
+
203
+ class TestHeckleSymbols < Test::Unit::TestCase
204
+ def setup
205
+ @heckler = Heckle::Base.new("Heckled", "uses_symbols")
206
+ end
207
+
208
+ def test_default_structure
209
+ expected = [:defn,
210
+ :uses_symbols,
211
+ [:scope,
212
+ [:block,
213
+ [:args],
214
+ [:lasgn, :i, [:lit, :blah]],
215
+ [:lasgn, :i, [:lit, :blah]],
216
+ [:lasgn, :i, [:lit, :and_blah]]]]]
217
+ assert_equal expected, @heckler.current_tree
218
+ end
219
+
220
+
221
+ def test_should_randomize_symbol
222
+ expected = [:defn,
223
+ :uses_symbols,
224
+ [:scope,
225
+ [:block,
226
+ [:args],
227
+ [:lasgn, :i, [:lit, :"l33t h4x0r"]],
228
+ [:lasgn, :i, [:lit, :blah]],
229
+ [:lasgn, :i, [:lit, :and_blah]]]]]
230
+ @heckler.process(@heckler.current_tree)
231
+ assert_equal expected, @heckler.current_tree
232
+
233
+ @heckler.reset_tree
234
+
235
+ expected = [:defn,
236
+ :uses_symbols,
237
+ [:scope,
238
+ [:block,
239
+ [:args],
240
+ [:lasgn, :i, [:lit, :blah]],
241
+ [:lasgn, :i, [:lit, :"l33t h4x0r"]],
242
+ [:lasgn, :i, [:lit, :and_blah]]]]]
243
+ @heckler.process(@heckler.current_tree)
244
+ assert_equal expected, @heckler.current_tree
245
+
246
+ @heckler.reset_tree
247
+
248
+ expected = [:defn,
249
+ :uses_symbols,
250
+ [:scope,
251
+ [:block,
252
+ [:args],
253
+ [:lasgn, :i, [:lit, :blah]],
254
+ [:lasgn, :i, [:lit, :blah]],
255
+ [:lasgn, :i, [:lit, :"l33t h4x0r"]]]]]
256
+ @heckler.process(@heckler.current_tree)
257
+ assert_equal expected, @heckler.current_tree
258
+ end
259
+ end
260
+
261
+ class TestHeckleRegexes < Test::Unit::TestCase
262
+ def setup
263
+ @heckler = Heckle::Base.new("Heckled", "uses_regexes")
264
+ end
265
+
266
+ def test_default_structure
267
+ expected = [:defn,
268
+ :uses_regexes,
269
+ [:scope,
270
+ [:block,
271
+ [:args],
272
+ [:lasgn, :i, [:lit, /a.*/]],
273
+ [:lasgn, :i, [:lit, /c{2,4}+/]],
274
+ [:lasgn, :i, [:lit, /123/]]]]]
275
+ assert_equal expected, @heckler.current_tree
276
+ end
277
+
278
+
279
+ def test_should_randomize_symbol
280
+ expected = [:defn,
281
+ :uses_regexes,
282
+ [:scope,
283
+ [:block,
284
+ [:args],
285
+ [:lasgn, :i, [:lit, /l33t\ h4x0r/]],
286
+ [:lasgn, :i, [:lit, /c{2,4}+/]],
287
+ [:lasgn, :i, [:lit, /123/]]]]]
288
+ @heckler.process(@heckler.current_tree)
289
+ assert_equal expected, @heckler.current_tree
290
+
291
+ @heckler.reset_tree
292
+
293
+ expected = [:defn,
294
+ :uses_regexes,
295
+ [:scope,
296
+ [:block,
297
+ [:args],
298
+ [:lasgn, :i, [:lit, /a.*/]],
299
+ [:lasgn, :i, [:lit, /l33t\ h4x0r/]],
300
+ [:lasgn, :i, [:lit, /123/]]]]]
301
+ @heckler.process(@heckler.current_tree)
302
+ assert_equal expected, @heckler.current_tree
303
+
304
+ @heckler.reset_tree
305
+
306
+ expected = [:defn,
307
+ :uses_regexes,
308
+ [:scope,
309
+ [:block,
310
+ [:args],
311
+ [:lasgn, :i, [:lit, /a.*/]],
312
+ [:lasgn, :i, [:lit, /c{2,4}+/]],
313
+ [:lasgn, :i, [:lit, /l33t\ h4x0r/]]]]]
314
+ @heckler.process(@heckler.current_tree)
315
+ assert_equal expected, @heckler.current_tree
316
+ end
317
+ end
318
+
319
+ class TestHeckleRanges < Test::Unit::TestCase
320
+ def setup
321
+ @heckler = Heckle::Base.new("Heckled", "uses_ranges")
322
+ end
323
+
324
+ def test_default_structure
325
+ expected = [:defn,
326
+ :uses_ranges,
327
+ [:scope,
328
+ [:block,
329
+ [:args],
330
+ [:lasgn, :i, [:lit, 6..100]],
331
+ [:lasgn, :i, [:lit, -1..9]],
332
+ [:lasgn, :i, [:lit, 1..4]]]]]
333
+ assert_equal expected, @heckler.current_tree
334
+ end
335
+
336
+ def test_should_randomize_symbol
337
+ expected = [:defn,
338
+ :uses_ranges,
339
+ [:scope,
340
+ [:block,
341
+ [:args],
342
+ [:lasgn, :i, [:lit, 5..10]],
343
+ [:lasgn, :i, [:lit, -1..9]],
344
+ [:lasgn, :i, [:lit, 1..4]]]]]
345
+ @heckler.process(@heckler.current_tree)
346
+ assert_equal expected, @heckler.current_tree
347
+
348
+ @heckler.reset_tree
349
+
350
+ expected = [:defn,
351
+ :uses_ranges,
352
+ [:scope,
353
+ [:block,
354
+ [:args],
355
+ [:lasgn, :i, [:lit, 6..100]],
356
+ [:lasgn, :i, [:lit, 5..10]],
357
+ [:lasgn, :i, [:lit, 1..4]]]]]
358
+ @heckler.process(@heckler.current_tree)
359
+ assert_equal expected, @heckler.current_tree
360
+
361
+ @heckler.reset_tree
362
+
363
+ expected = [:defn,
364
+ :uses_ranges,
365
+ [:scope,
366
+ [:block,
367
+ [:args],
368
+ [:lasgn, :i, [:lit, 6..100]],
369
+ [:lasgn, :i, [:lit, -1..9]],
370
+ [:lasgn, :i, [:lit, 5..10]]]]]
371
+ @heckler.process(@heckler.current_tree)
372
+ assert_equal expected, @heckler.current_tree
373
+ end
374
+ end
375
+
376
+
377
+ class TestHeckleSameLiteral < Test::Unit::TestCase
378
+ def setup
379
+ @heckler = Heckle::Base.new("Heckled", "uses_the_same_literal")
380
+ end
381
+
382
+ def teardown
383
+ @heckler.reset
384
+ end
385
+
386
+ def test_original_tree
387
+ expected = [:defn,
388
+ :uses_the_same_literal,
389
+ [:fbody, [:scope,
390
+ [:block,
391
+ [:args],
392
+ [:lasgn, :i, [:lit, 1]],
393
+ [:lasgn, :i, [:lit, 1]],
394
+ [:lasgn, :i, [:lit, 1]]]]]]
395
+
396
+ assert_equal expected, @heckler.current_tree
397
+ end
398
+
399
+ def test_literals_should_flip_one_at_a_time
400
+ # structure of uses_numeric_literals with first literal +5 (from stubbed rand)
401
+ expected = [:defn,
402
+ :uses_the_same_literal,
403
+ [:scope,
404
+ [:block,
405
+ [:args],
406
+ [:lasgn, :i, [:lit, 6]],
407
+ [:lasgn, :i, [:lit, 1]],
408
+ [:lasgn, :i, [:lit, 1]]]]]
409
+
410
+ @heckler.process(@heckler.current_tree)
411
+ assert_equal expected, @heckler.current_tree
412
+
413
+ @heckler.reset_tree
414
+
415
+ expected = [:defn,
416
+ :uses_the_same_literal,
417
+ [:scope,
418
+ [:block,
419
+ [:args],
420
+ [:lasgn, :i, [:lit, 1]],
421
+ [:lasgn, :i, [:lit, 6]],
422
+ [:lasgn, :i, [:lit, 1]]]]]
423
+
424
+ @heckler.process(@heckler.current_tree)
425
+ assert_equal expected, @heckler.current_tree
426
+
427
+ @heckler.reset_tree
428
+
429
+ expected = [:defn,
430
+ :uses_the_same_literal,
431
+ [:scope,
432
+ [:block,
433
+ [:args],
434
+ [:lasgn, :i, [:lit, 1]],
435
+ [:lasgn, :i, [:lit, 1]],
436
+ [:lasgn, :i, [:lit, 6]]]]]
437
+
438
+ @heckler.process(@heckler.current_tree)
439
+ assert_equal expected, @heckler.current_tree
440
+ end
441
+ end
442
+
443
+ module Heckle
444
+ class Base
445
+ def rand_string
446
+ "l33t h4x0r"
29
447
  end
30
448
  end
31
449
  end
32
450
 
33
- puts 'loaded'
451
+ class TestHeckleStrings < Test::Unit::TestCase
452
+ def setup
453
+ @heckler = Heckle::Base.new("Heckled", "uses_strings")
454
+ end
455
+
456
+ def teardown
457
+ @heckler.reset
458
+ end
459
+
460
+ def test_default_structure
461
+ expected = [:defn,
462
+ :uses_strings,
463
+ [:scope,
464
+ [:block,
465
+ [:args],
466
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Robert"]]],
467
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Jeff"]]],
468
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hi, Frank"]]]]]]
469
+ assert_equal expected, @heckler.current_tree
470
+ end
471
+
472
+ def test_should_heckle_string_literals
473
+ expected = [:defn,
474
+ :uses_strings,
475
+ [:scope,
476
+ [:block,
477
+ [:args],
478
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "l33t h4x0r"]]],
479
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Jeff"]]],
480
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hi, Frank"]]]]]]
481
+ @heckler.process(@heckler.current_tree)
482
+ assert_equal expected, @heckler.current_tree
483
+
484
+ @heckler.reset_tree
485
+
486
+ expected = [:defn,
487
+ :uses_strings,
488
+ [:scope,
489
+ [:block,
490
+ [:args],
491
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Robert"]]],
492
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "l33t h4x0r"]]],
493
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hi, Frank"]]]]]]
494
+
495
+ @heckler.process(@heckler.current_tree)
496
+ assert_equal expected, @heckler.current_tree
497
+
498
+ @heckler.reset_tree
499
+
500
+ expected = [:defn,
501
+ :uses_strings,
502
+ [:scope,
503
+ [:block,
504
+ [:args],
505
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Robert"]]],
506
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "Hello, Jeff"]]],
507
+ [:call, [:ivar, :@names], :<<, [:array, [:str, "l33t h4x0r"]]]]]]
508
+
509
+ @heckler.process(@heckler.current_tree)
510
+ assert_equal expected, @heckler.current_tree
511
+ end
512
+ end
513
+
514
+ class TestHeckleIfs < Test::Unit::TestCase
515
+ def setup
516
+ @heckler = Heckle::Base.new("Heckled", "uses_if")
517
+ end
518
+
519
+ def teardown
520
+ @heckler.reset
521
+ end
522
+
523
+ def test_default_structure
524
+ expected = [:defn,
525
+ :uses_if,
526
+ [:scope,
527
+ [:block,
528
+ [:args],
529
+ [:if,
530
+ [:vcall, :some_func],
531
+ [:if, [:vcall, :some_other_func], [:return], nil],
532
+ nil]]]]
533
+
534
+
535
+ assert_equal expected, @heckler.current_tree
536
+ end
537
+
538
+ def test_should_flip_if_to_unless
539
+ expected = [:defn,
540
+ :uses_if,
541
+ [:scope,
542
+ [:block,
543
+ [:args],
544
+ [:if,
545
+ [:vcall, :some_func],
546
+ [:if, [:vcall, :some_other_func], nil, [:return]],
547
+ nil]]]]
548
+
549
+ @heckler.process(@heckler.current_tree)
550
+ assert_equal expected, @heckler.current_tree
551
+
552
+ @heckler.reset_tree
553
+
554
+ expected = [:defn,
555
+ :uses_if,
556
+ [:scope,
557
+ [:block,
558
+ [:args],
559
+ [:if,
560
+ [:vcall, :some_func],
561
+ nil,
562
+ [:if, [:vcall, :some_other_func], [:return], nil]]]]]
563
+
564
+ @heckler.process(@heckler.current_tree)
565
+ assert_equal expected, @heckler.current_tree
566
+ end
567
+ end
568
+
569
+ class TestHeckleBooleans < Test::Unit::TestCase
570
+ def setup
571
+ @heckler = Heckle::Base.new("Heckled", "uses_boolean")
572
+ end
573
+
574
+ def teardown
575
+ @heckler.reset
576
+ end
577
+
578
+ def test_default_structure
579
+ expected = [:defn, :uses_boolean, [:scope, [:block, [:args], [:true], [:false]]]]
580
+ assert_equal expected, @heckler.current_tree
581
+ end
582
+
583
+
584
+ def test_should_flip_true_to_false_and_false_to_true
585
+ expected = [:defn, :uses_boolean, [:scope, [:block, [:args], [:false], [:false]]]]
586
+
587
+ @heckler.process(@heckler.current_tree)
588
+ assert_equal expected, @heckler.current_tree
589
+
590
+ @heckler.reset_tree
591
+
592
+ expected = [:defn, :uses_boolean, [:scope, [:block, [:args], [:true], [:true]]]]
593
+ @heckler.process(@heckler.current_tree)
594
+ assert_equal expected, @heckler.current_tree
595
+ end
596
+ end
597
+
598
+ class TestHeckleWhile < Test::Unit::TestCase
599
+ def setup
600
+ @heckler = Heckle::Base.new("Heckled", "uses_while")
601
+ end
602
+
603
+ def teardown
604
+ @heckler.reset
605
+ end
606
+
607
+ def test_default_structure
608
+ expected = [:defn,
609
+ :uses_while,
610
+ [:scope,
611
+ [:block,
612
+ [:args],
613
+ [:while, [:vcall, :some_func], [:vcall, :some_other_func], true]]]]
614
+ assert_equal expected, @heckler.current_tree
615
+ end
616
+
617
+ def test_flips_while_to_until
618
+ expected = [:defn,
619
+ :uses_while,
620
+ [:scope,
621
+ [:block,
622
+ [:args],
623
+ [:until, [:vcall, :some_func], [:vcall, :some_other_func], true]]]]
624
+ @heckler.process(@heckler.current_tree)
625
+ assert_equal expected, @heckler.current_tree
626
+ end
627
+ end
628
+
629
+ class TestHeckleUntil < Test::Unit::TestCase
630
+ def setup
631
+ @heckler = Heckle::Base.new("Heckled", "uses_until")
632
+ end
633
+
634
+ def teardown
635
+ @heckler.reset
636
+ end
637
+
638
+ def test_default_structure
639
+ expected = [:defn,
640
+ :uses_until,
641
+ [:scope,
642
+ [:block,
643
+ [:args],
644
+ [:until, [:vcall, :some_func], [:vcall, :some_other_func], true]]]]
645
+ assert_equal expected, @heckler.current_tree
646
+ end
647
+
648
+ def test_flips_until_to_while
649
+ expected = [:defn,
650
+ :uses_until,
651
+ [:scope,
652
+ [:block,
653
+ [:args],
654
+ [:while, [:vcall, :some_func], [:vcall, :some_other_func], true]]]]
655
+ @heckler.process(@heckler.current_tree)
656
+ assert_equal expected, @heckler.current_tree
657
+ end
658
+ end