mutant 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. data/.gitignore +5 -11
  2. data/.rspec +0 -1
  3. data/.travis.yml +14 -3
  4. data/Changelog.md +3 -0
  5. data/Gemfile +5 -1
  6. data/Gemfile.devtools +49 -0
  7. data/Guardfile +18 -0
  8. data/README.md +67 -0
  9. data/Rakefile +4 -1
  10. data/TODO +13 -0
  11. data/bin/mutant +14 -0
  12. data/bin/zombie +14 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/roodi.yml +26 -0
  16. data/config/site.reek +93 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/inflector.rb +7 -0
  19. data/lib/inflector/defaults.rb +62 -0
  20. data/lib/inflector/inflections.rb +209 -0
  21. data/lib/inflector/methods.rb +149 -0
  22. data/lib/inflector/version.rb +3 -0
  23. data/lib/mutant.rb +96 -21
  24. data/lib/mutant/cli.rb +309 -0
  25. data/lib/mutant/color.rb +61 -0
  26. data/lib/mutant/context.rb +36 -0
  27. data/lib/mutant/context/scope.rb +138 -0
  28. data/lib/mutant/differ.rb +100 -0
  29. data/lib/mutant/helper.rb +38 -0
  30. data/lib/mutant/killer.rb +136 -0
  31. data/lib/mutant/killer/forking.rb +41 -0
  32. data/lib/mutant/killer/rspec.rb +49 -0
  33. data/lib/mutant/killer/static.rb +19 -0
  34. data/lib/mutant/loader.rb +129 -0
  35. data/lib/mutant/matcher.rb +55 -0
  36. data/lib/mutant/matcher/chain.rb +66 -0
  37. data/lib/mutant/matcher/method.rb +173 -0
  38. data/lib/mutant/matcher/method/classifier.rb +126 -0
  39. data/lib/mutant/matcher/method/instance.rb +67 -0
  40. data/lib/mutant/matcher/method/singleton.rb +141 -0
  41. data/lib/mutant/matcher/object_space.rb +114 -0
  42. data/lib/mutant/matcher/scope_methods.rb +127 -0
  43. data/lib/mutant/mutation.rb +101 -12
  44. data/lib/mutant/mutation/filter.rb +75 -0
  45. data/lib/mutant/mutation/filter/code.rb +68 -0
  46. data/lib/mutant/mutation/filter/regexp.rb +39 -0
  47. data/lib/mutant/mutation/filter/whitelist.rb +47 -0
  48. data/lib/mutant/mutator.rb +134 -30
  49. data/lib/mutant/mutator/node.rb +163 -0
  50. data/lib/mutant/mutator/node/arguments.rb +24 -0
  51. data/lib/mutant/mutator/node/block.rb +24 -0
  52. data/lib/mutant/mutator/node/define.rb +24 -0
  53. data/lib/mutant/mutator/node/if_statement.rb +93 -0
  54. data/lib/mutant/mutator/node/literal.rb +54 -0
  55. data/lib/mutant/mutator/node/literal/array.rb +28 -0
  56. data/lib/mutant/mutator/node/literal/boolean.rb +49 -0
  57. data/lib/mutant/mutator/node/literal/dynamic.rb +24 -0
  58. data/lib/mutant/mutator/node/literal/empty_array.rb +26 -0
  59. data/lib/mutant/mutator/node/literal/fixnum.rb +37 -0
  60. data/lib/mutant/mutator/node/literal/float.rb +48 -0
  61. data/lib/mutant/mutator/node/literal/hash.rb +89 -0
  62. data/lib/mutant/mutator/node/literal/nil.rb +25 -0
  63. data/lib/mutant/mutator/node/literal/range.rb +94 -0
  64. data/lib/mutant/mutator/node/literal/regex.rb +43 -0
  65. data/lib/mutant/mutator/node/literal/string.rb +26 -0
  66. data/lib/mutant/mutator/node/literal/symbol.rb +26 -0
  67. data/lib/mutant/mutator/node/noop.rb +55 -0
  68. data/lib/mutant/mutator/node/receiver_case.rb +140 -0
  69. data/lib/mutant/mutator/node/return.rb +31 -0
  70. data/lib/mutant/mutator/node/send.rb +112 -0
  71. data/lib/mutant/mutator/registry.rb +48 -0
  72. data/lib/mutant/mutator/util.rb +87 -0
  73. data/lib/mutant/random.rb +24 -27
  74. data/lib/mutant/reporter.rb +48 -30
  75. data/lib/mutant/reporter/cli.rb +221 -0
  76. data/lib/mutant/reporter/null.rb +42 -0
  77. data/lib/mutant/reporter/stats.rb +64 -0
  78. data/lib/mutant/runner.rb +112 -0
  79. data/lib/mutant/strategy.rb +42 -0
  80. data/lib/mutant/strategy/rspec.rb +59 -0
  81. data/lib/mutant/strategy/rspec/example_lookup.rb +122 -0
  82. data/lib/mutant/subject.rb +115 -0
  83. data/lib/mutant/support/method_object.rb +31 -0
  84. data/locator.rb +87 -0
  85. data/mutant.gemspec +21 -21
  86. data/spec/integration/mutant/differ_spec.rb +15 -0
  87. data/spec/integration/mutant/loader_spec.rb +21 -0
  88. data/spec/integration/mutant/method_matching_spec.rb +269 -0
  89. data/spec/integration/mutant/rspec_killer_spec.rb +24 -0
  90. data/spec/integration/mutant/runner_spec.rb +26 -0
  91. data/spec/integration/mutant/zombie_spec.rb +8 -0
  92. data/spec/rcov.opts +7 -0
  93. data/spec/shared/command_method_behavior.rb +7 -0
  94. data/spec/shared/each_method_behaviour.rb +15 -0
  95. data/spec/shared/hash_method_behavior.rb +17 -0
  96. data/spec/shared/idempotent_method_behavior.rb +7 -0
  97. data/spec/shared/invertible_method_behaviour.rb +9 -0
  98. data/spec/shared/method_filter_parse_behavior.rb +16 -0
  99. data/spec/shared/method_match_behavior.rb +39 -0
  100. data/spec/shared/mutator_behavior.rb +46 -0
  101. data/spec/spec_helper.rb +11 -14
  102. data/spec/support/compress_helper.rb +10 -0
  103. data/spec/support/rspec.rb +22 -0
  104. data/spec/support/test_app.rb +5 -0
  105. data/spec/support/zombie.rb +141 -0
  106. data/spec/unit/mutant/cli/class_methods/new_spec.rb +87 -0
  107. data/spec/unit/mutant/cli/class_methods/run_spec.rb +38 -0
  108. data/spec/unit/mutant/context/root_spec.rb +11 -0
  109. data/spec/unit/mutant/context/scope/class_methods/build_spec.rb +29 -0
  110. data/spec/unit/mutant/context/scope/root_spec.rb +22 -0
  111. data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +27 -0
  112. data/spec/unit/mutant/killer/fail_ques_spec.rb +39 -0
  113. data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +32 -0
  114. data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +33 -0
  115. data/spec/unit/mutant/loader/rubinius/class_methods/run_spec.rb +42 -0
  116. data/spec/unit/mutant/matcher/chain/each_spec.rb +37 -0
  117. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +12 -0
  118. data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +49 -0
  119. data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +12 -0
  120. data/spec/unit/mutant/matcher/each_spec.rb +14 -0
  121. data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +21 -0
  122. data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +34 -0
  123. data/spec/unit/mutant/matcher/method/method_spec.rb +11 -0
  124. data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +24 -0
  125. data/spec/unit/mutant/matcher/object_space/each_spec.rb +31 -0
  126. data/spec/unit/mutant/mutator/each_spec.rb +25 -0
  127. data/spec/unit/mutant/mutator/emit_new_spec.rb +51 -0
  128. data/spec/unit/mutant/mutator/emit_spec.rb +52 -0
  129. data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +36 -0
  130. data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +47 -0
  131. data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +30 -0
  132. data/spec/unit/mutant/mutator/node/literal/array_spec.rb +30 -0
  133. data/spec/unit/mutant/mutator/node/literal/boolean/mutation_spec.rb +23 -0
  134. data/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb +17 -0
  135. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +17 -0
  136. data/spec/unit/mutant/mutator/node/literal/float_spec.rb +25 -0
  137. data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +34 -0
  138. data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +13 -0
  139. data/spec/unit/mutant/mutator/node/literal/range_spec.rb +35 -0
  140. data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +23 -0
  141. data/spec/unit/mutant/mutator/node/literal/string_spec.rb +17 -0
  142. data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +17 -0
  143. data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +27 -0
  144. data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +21 -0
  145. data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +78 -0
  146. data/spec/unit/mutant/mutator/self_spec.rb +7 -0
  147. data/spec/unit/mutant/subject/class_methods/new_spec.rb +13 -0
  148. data/spec/unit/mutant/subject/context_spec.rb +14 -0
  149. data/spec/unit/mutant/subject/each_spec.rb +35 -0
  150. data/spec/unit/mutant/subject/node_spec.rb +13 -0
  151. data/tasks/metrics/ci.rake +7 -0
  152. data/tasks/metrics/flay.rake +41 -0
  153. data/tasks/metrics/flog.rake +43 -0
  154. data/tasks/metrics/heckle.rake +216 -0
  155. data/tasks/metrics/metric_fu.rake +31 -0
  156. data/tasks/metrics/reek.rake +15 -0
  157. data/tasks/metrics/roodi.rake +15 -0
  158. data/tasks/metrics/yardstick.rake +23 -0
  159. data/tasks/spec.rake +45 -0
  160. data/tasks/yard.rake +9 -0
  161. data/test_app/.rspec +1 -0
  162. data/test_app/lib/test_app.rb +5 -0
  163. data/test_app/lib/test_app/literal.rb +32 -0
  164. data/test_app/spec/shared/command_method_behavior.rb +7 -0
  165. data/test_app/spec/shared/each_method_behaviour.rb +15 -0
  166. data/test_app/spec/shared/hash_method_behavior.rb +17 -0
  167. data/test_app/spec/shared/idempotent_method_behavior.rb +7 -0
  168. data/test_app/spec/shared/invertible_method_behaviour.rb +9 -0
  169. data/test_app/spec/shared/method_filter_parse_behavior.rb +16 -0
  170. data/test_app/spec/shared/method_match_behavior.rb +39 -0
  171. data/test_app/spec/shared/mutator_behavior.rb +44 -0
  172. data/test_app/spec/spec_helper.rb +7 -0
  173. data/test_app/spec/unit/test_app/literal/command_spec.rb +9 -0
  174. data/test_app/spec/unit/test_app/literal/string_spec.rb +9 -0
  175. metadata +346 -124
  176. data/.rvmrc +0 -1
  177. data/Readme.md +0 -13
  178. data/exe/mutate +0 -6
  179. data/lib/mutant/extensions.rb +0 -8
  180. data/lib/mutant/formatter.rb +0 -19
  181. data/lib/mutant/implementation.rb +0 -70
  182. data/lib/mutant/literal.rb +0 -147
  183. data/lib/mutant/method.rb +0 -31
  184. data/lib/mutant/mutatee.rb +0 -61
  185. data/lib/mutant/node.rb +0 -26
  186. data/lib/mutant/runners/rspec.rb +0 -34
  187. data/lib/mutant/version.rb +0 -3
  188. data/spec/functional/class_spec.rb +0 -46
  189. data/spec/functional/instance_method/array_spec.rb +0 -53
  190. data/spec/functional/instance_method/boolean_spec.rb +0 -101
  191. data/spec/functional/instance_method/call_spec.rb +0 -161
  192. data/spec/functional/instance_method/fixnum_spec.rb +0 -53
  193. data/spec/functional/instance_method/float_spec.rb +0 -53
  194. data/spec/functional/instance_method/hash_spec.rb +0 -53
  195. data/spec/functional/instance_method/if_spec.rb +0 -57
  196. data/spec/functional/instance_method/ivar_assign_spec.rb +0 -62
  197. data/spec/functional/instance_method/range_spec.rb +0 -53
  198. data/spec/functional/instance_method/regex_spec.rb +0 -55
  199. data/spec/functional/instance_method/string_spec.rb +0 -53
  200. data/spec/functional/instance_method/symbol_spec.rb +0 -53
  201. data/spec/functional/reporter/method_loaded_spec.rb +0 -62
  202. data/spec/functional/reporter/running_mutations_spec.rb +0 -60
  203. data/spec/functional/runners/rspec_spec.rb +0 -26
  204. data/spec/functional/singleton_method/array_spec.rb +0 -53
  205. data/spec/functional/singleton_method/boolean_spec.rb +0 -101
  206. data/spec/functional/singleton_method/call_spec.rb +0 -161
  207. data/spec/functional/singleton_method/fixnum_spec.rb +0 -53
  208. data/spec/functional/singleton_method/float_spec.rb +0 -53
  209. data/spec/functional/singleton_method/hash_spec.rb +0 -53
  210. data/spec/functional/singleton_method/if_spec.rb +0 -57
  211. data/spec/functional/singleton_method/ivar_assign_spec.rb +0 -60
  212. data/spec/functional/singleton_method/range_spec.rb +0 -53
  213. data/spec/functional/singleton_method/regex_spec.rb +0 -55
  214. data/spec/functional/singleton_method/string_spec.rb +0 -53
  215. data/spec/functional/singleton_method/symbol_spec.rb +0 -53
  216. data/spec/mutant/extensions_spec.rb +0 -13
  217. data/spec/mutant/implementation_spec.rb +0 -223
  218. data/spec/mutant/literal_spec.rb +0 -129
  219. data/spec/mutant/mutatee_spec.rb +0 -28
  220. data/spec/mutant/node_spec.rb +0 -41
  221. data/spec/mutant/random_spec.rb +0 -33
  222. data/spec/mutant/reporter_spec.rb +0 -17
  223. data/spec/mutant_spec.rb +0 -28
  224. data/spec/support/example_group_helpers.rb +0 -11
  225. data/spec/support/example_helpers.rb +0 -5
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use rbx-head@mutant --create
data/Readme.md DELETED
@@ -1,13 +0,0 @@
1
- # mutant [![Build Status](https://secure.travis-ci.org/txus/mutant.png)](http://travis-ci.org/txus/mutant) [![Dependency Status](https://gemnasium.com/txus/mutant.png)](https://gemnasium.com/txus/mutant)
2
-
3
- Mutant is a mutation tester. It modifies your code and runs your tests to make sure they fail. The idea is that if code can be changed and your tests don't notice, either that code isn't being covered or it doesn't do anything.
4
-
5
- Largely based on [heckle](https://github.com/seattlerb/heckle), this is a rewrite on top of [Rubinius](http://rubini.us).
6
-
7
- ## Development roadmap
8
-
9
- As an experiment, I've set up a [public Trello board](https://trello.com/board/mutant/4f452510101d860b203b542d) with the development roadmap up to the 1.0 release. You can vote and comment cards to give constructive feedback to the project. Just have a look and leave a comment! :)
10
-
11
- ## Who's this
12
-
13
- This project was originally created by [@justinko](http://twitter.com/justinko) and is released under the MIT license. I am pleased to be the current maintainer :) I'm [@txustice](http://twitter.com/txustice) on twitter (where you should probably follow me!).
data/exe/mutate DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $:.unshift(File.dirname(__FILE__) + '/../lib')
3
-
4
- require 'mutant'
5
-
6
- Mutant.run(ARGV)
@@ -1,8 +0,0 @@
1
- module ClassExtensions
2
- def basename
3
- name.split('::').last
4
- end
5
- end
6
-
7
- Class.send :include, ClassExtensions
8
- Rubinius::AST::Node.send :include, ClassExtensions
@@ -1,19 +0,0 @@
1
- require 'to_source'
2
-
3
- module Mutant
4
- class Formatter
5
- attr_reader :item
6
-
7
- def initialize(item)
8
- @item = item
9
- end
10
-
11
- def nested?
12
- false
13
- end
14
-
15
- def to_s
16
- item.to_source
17
- end
18
- end
19
- end
@@ -1,70 +0,0 @@
1
- module Mutant
2
- class Implementation
3
- SINGLETON_SCOPE = '.'
4
- INSTANCE_SCOPE = '#'
5
- SCOPE_REGEXP = Regexp.union(SINGLETON_SCOPE, INSTANCE_SCOPE)
6
-
7
- def initialize(str)
8
- @str = str
9
- end
10
-
11
- def scope_type
12
- { SINGLETON_SCOPE => :singleton, INSTANCE_SCOPE => :instance
13
- }[method_scope]
14
- end
15
-
16
- def class_name
17
- @str.split(SCOPE_REGEXP)[0]
18
- end
19
-
20
- def method_scope
21
- @str[SCOPE_REGEXP]
22
- end
23
-
24
- def method_name
25
- @str.split(SCOPE_REGEXP)[1] if method_scope
26
- end
27
-
28
- def constant
29
- class_name.split(/::/).inject(Object) do |context, name|
30
- context.const_get name
31
- end
32
- end
33
-
34
- def all_implementations
35
- all_methods.map {|formatted_method| self.class.new(formatted_method)}
36
- end
37
-
38
- def all_methods
39
- all_singleton_methods + all_instance_methods
40
- end
41
-
42
- def all_singleton_methods
43
- constant.singleton_methods(false).delete_if {|meth_name|
44
- meth_name.to_s == '__class_init__' }.map {|meth_name|
45
- format_method(meth_name, SINGLETON_SCOPE)}
46
- end
47
-
48
- def all_instance_methods
49
- constant.instance_methods(false).map do |meth_name|
50
- format_method(meth_name, INSTANCE_SCOPE)
51
- end
52
- end
53
-
54
- def mutatees
55
- Array(method_scope ? self : all_implementations).map do |impl|
56
- Mutatee.new(impl)
57
- end
58
- end
59
-
60
- def to_s
61
- @str
62
- end
63
-
64
- private
65
-
66
- def format_method(meth_name, method_scope_type)
67
- class_name + method_scope_type + meth_name.to_s
68
- end
69
- end
70
- end
@@ -1,147 +0,0 @@
1
- module Mutant
2
- class Literal
3
- def self.literal_class(node)
4
- const_get(node.class.basename)
5
- end
6
-
7
- def initialize(node)
8
- @node = node
9
- @class = self.class.literal_class(node)
10
- end
11
-
12
- def swap
13
- @class.new(@node).swap
14
- end
15
-
16
- class BaseLiteral
17
- def initialize(node)
18
- @node = node
19
- end
20
- end
21
-
22
- class FalseLiteral < BaseLiteral
23
- def swap
24
- Rubinius::AST::TrueLiteral.new(@node.line)
25
- end
26
- end
27
-
28
- class TrueLiteral < BaseLiteral
29
- def swap
30
- Rubinius::AST::FalseLiteral.new(@node.line)
31
- end
32
- end
33
-
34
- class SymbolLiteral < BaseLiteral
35
- def swap
36
- @node.value = Random.symbol
37
- @node
38
- end
39
- end
40
-
41
- class StringLiteral < BaseLiteral
42
- def swap
43
- @node.string = Random.string
44
- @node
45
- end
46
- end
47
-
48
- class FixnumLiteral < BaseLiteral
49
- def swap
50
- @node.value = Random.fixnum
51
- @node
52
- end
53
- end
54
-
55
- class FloatLiteral < BaseLiteral
56
- def swap
57
- @node.value = Random.float
58
- @node
59
- end
60
- end
61
-
62
- class Range < BaseLiteral
63
- def swap
64
- range = Random.range
65
- @node.start = Rubinius::AST::FixnumLiteral.new(@node.line, range.min)
66
- @node.finish = Rubinius::AST::FixnumLiteral.new(@node.line, range.max)
67
- @node
68
- end
69
- end
70
-
71
- class RegexLiteral < BaseLiteral
72
- def swap
73
- @node.source = Regexp.escape(Random.string)
74
- @node
75
- end
76
- end
77
-
78
- class ArrayLiteral < BaseLiteral
79
- def swap
80
- @node.body = @node.body.reverse[1..-1]
81
- @node
82
- end
83
- end
84
-
85
- class HashLiteral < BaseLiteral
86
- def swap
87
- new_body = @node.array.each_slice(2).inject([]) do |body, (key, value)|
88
- new_value = literal_class(value).new(value.clone).swap
89
-
90
- body << key << new_value
91
- end
92
-
93
- @node.array = new_body
94
- @node
95
- end
96
-
97
- private
98
-
99
- def literal_class(value)
100
- Module.nesting[1].literal_class(value)
101
- end
102
- end
103
-
104
- class LocalVariableAssignment < BaseLiteral
105
- def swap
106
- @node.value = literal_class.new(@node.value.clone).swap
107
- @node
108
- end
109
-
110
- private
111
-
112
- def literal_class
113
- Module.nesting[1].literal_class(@node.value)
114
- end
115
- end
116
-
117
- class InstanceVariableAssignment < BaseLiteral
118
- def swap
119
- @node.value = literal_class.new(@node.value.clone).swap
120
- @node
121
- end
122
-
123
- private
124
-
125
- def literal_class
126
- Module.nesting[1].literal_class(@node.value)
127
- end
128
- end
129
-
130
- class If < BaseLiteral
131
- def swap
132
- @node.body, @node.else = @node.else, @node.body
133
- @node
134
- end
135
- end
136
-
137
- class Send < BaseLiteral
138
- def swap
139
- line = @node.line
140
- @node = Rubinius::AST::NilLiteral.new(line)
141
- @node
142
- end
143
- end
144
-
145
- SendWithArguments = Send
146
- end
147
- end
@@ -1,31 +0,0 @@
1
- module Mutant
2
- class Method < Rubinius::Melbourne
3
- attr_reader :ast, :source_name, :source_file, :source_line
4
-
5
- DEFAULT_LINE = 1
6
-
7
- def initialize(method)
8
- @ast = nil
9
- @source_name = method.name.to_sym
10
- @source_file, @source_line = method.source_location
11
- super(source_file, DEFAULT_LINE)
12
- end
13
-
14
- # TODO: Check for edge cases where just the line won't work.
15
- def match?(ast)
16
- source_line == ast.line
17
- end
18
- end
19
-
20
- class InstanceMethod < Method
21
- def process_defn(*)
22
- super.tap { |ast| @ast = ast if match?(ast) }
23
- end
24
- end
25
-
26
- class SingletonMethod < Method
27
- def process_defs(*)
28
- super.tap { |ast| @ast = ast if match?(ast.body) }
29
- end
30
- end
31
- end
@@ -1,61 +0,0 @@
1
- require 'forwardable'
2
-
3
- module Mutant
4
- class Mutatee
5
- extend Forwardable
6
-
7
- attr_reader :implementation, :mutations
8
-
9
- def initialize(implementation)
10
- @implementation = implementation
11
- @mutations = []
12
- end
13
-
14
- def_delegators :@implementation, :class_name, :method_name, :to_s
15
-
16
- def clean
17
- body.array.delete_if do |literal|
18
- not Mutant::Literal.constants.map(&:to_sym).include?(literal.class.basename.to_sym)
19
- end
20
- end
21
-
22
- def set_mutations
23
- nodes.each do |node|
24
- @mutations << Mutation.new(node, body.array)
25
- end
26
- end
27
-
28
- def nodes
29
- body.array.map {|item| Node.new(item) }
30
- end
31
-
32
- def mutations_remaining
33
- @mutations.reject(&:mutated?)
34
- end
35
-
36
- def ast
37
- @ast ||= rbx_method.parse_file && rbx_method.ast
38
- end
39
-
40
- def body
41
- @body ||= rbx_method.is_a?(SingletonMethod) ? ast.body.body : ast.body
42
-
43
- end
44
-
45
- def rbx_method
46
- @rbx_method ||=
47
- case implementation.scope_type
48
- when :singleton then SingletonMethod.new \
49
- implementation.constant.method(method_name)
50
- when :instance then InstanceMethod.new \
51
- implementation.constant.instance_method(method_name)
52
- end
53
- end
54
-
55
- private
56
-
57
- def marshal(data)
58
- Marshal.load(Marshal.dump(data))
59
- end
60
- end
61
- end
@@ -1,26 +0,0 @@
1
- module Mutant
2
- class Node
3
- attr_reader :item, :copy
4
-
5
- def initialize(item)
6
- @item = item
7
- @copy = item.clone
8
- end
9
-
10
- def line
11
- item.line
12
- end
13
-
14
- def from
15
- @from ||= Formatter.new(item)
16
- end
17
-
18
- def to
19
- @to ||= Formatter.new(copy)
20
- end
21
-
22
- def swap
23
- @copy = Literal.new(copy).swap
24
- end
25
- end
26
- end
@@ -1,34 +0,0 @@
1
- require 'rspec/core'
2
-
3
- module Mutant
4
- module Runners
5
- class RSpec
6
- ABORT_MESSAGE = 'Initial run of specs failed... fix and run mutant again'
7
-
8
- def self.run(args)
9
- runner = new(args)
10
- runner.initial_run
11
- runner.mutate
12
- puts runner.run.zero? ? 'failed' : 'passed'
13
- end
14
-
15
- def initialize(args)
16
- @implementation = Implementation.new(args.shift)
17
- @args = args
18
- end
19
-
20
- def initial_run
21
- abort ABORT_MESSAGE unless run.zero?
22
- end
23
-
24
- def run
25
- ::RSpec::Core::Runner.run(@args)
26
- end
27
-
28
- def mutate
29
- Mutant.mutate(@implementation)
30
- end
31
- end
32
- end
33
- end
34
-
@@ -1,3 +0,0 @@
1
- module Mutant
2
- VERSION = "0.1.1"
3
- end
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Mutating a class' do
4
- before do
5
- write_file 'thing.rb', """
6
- class Thing
7
- def alive?; true end
8
- def dead?; false end
9
- def mood; :happy end
10
- def gender; 'male' end
11
- def alphabet_range; 'a'..'k' end
12
- end
13
- """
14
- write_file 'spec/thing_spec.rb', """
15
- $: << '.'
16
- require 'thing'
17
-
18
- describe Thing do
19
- describe '#alive?' do
20
- specify { Thing.new.should be_alive }
21
- end
22
-
23
- describe '#dead?' do
24
- specify { Thing.new.should_not be_dead }
25
- end
26
-
27
- describe '#mood' do
28
- specify { Thing.new.mood.should eq(:happy) }
29
- end
30
-
31
- describe '#gender' do
32
- specify { Thing.new.gender.should eq('male') }
33
- end
34
-
35
- describe '#alphabet_range' do
36
- specify { Thing.new.alphabet_range.should eq('a'..'k') }
37
- end
38
- end
39
- """
40
- mutate 'Thing spec/thing_spec.rb'
41
- end
42
-
43
- it 'runs all possible mutations' do
44
- all_output.should include('passed')
45
- end
46
- end