mutant 0.3.0.beta21 → 0.3.0.beta22

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 (223) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +37 -6
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +13 -7
  6. data/Gemfile +8 -3
  7. data/Gemfile.devtools +2 -6
  8. data/Guardfile +22 -8
  9. data/README.md +3 -1
  10. data/Rakefile +3 -0
  11. data/bin/mutant +4 -3
  12. data/config/devtools.yml +1 -1
  13. data/config/flay.yml +1 -1
  14. data/config/flog.yml +1 -1
  15. data/config/reek.yml +7 -6
  16. data/config/rubocop.yml +55 -0
  17. data/lib/mutant.rb +3 -1
  18. data/lib/mutant/cache.rb +2 -0
  19. data/lib/mutant/cli.rb +14 -10
  20. data/lib/mutant/cli/classifier.rb +22 -10
  21. data/lib/mutant/cli/classifier/method.rb +14 -15
  22. data/lib/mutant/cli/classifier/namespace.rb +6 -2
  23. data/lib/mutant/cli/classifier/scope.rb +3 -1
  24. data/lib/mutant/color.rb +7 -3
  25. data/lib/mutant/config.rb +2 -0
  26. data/lib/mutant/constants.rb +5 -4
  27. data/lib/mutant/context.rb +2 -0
  28. data/lib/mutant/context/scope.rb +3 -1
  29. data/lib/mutant/differ.rb +10 -2
  30. data/lib/mutant/killer.rb +4 -1
  31. data/lib/mutant/killer/forked.rb +2 -0
  32. data/lib/mutant/killer/forking.rb +2 -0
  33. data/lib/mutant/killer/rspec.rb +19 -3
  34. data/lib/mutant/killer/static.rb +2 -0
  35. data/lib/mutant/loader.rb +8 -1
  36. data/lib/mutant/matcher.rb +2 -0
  37. data/lib/mutant/matcher/chain.rb +2 -0
  38. data/lib/mutant/matcher/method.rb +15 -3
  39. data/lib/mutant/matcher/method/finder.rb +2 -0
  40. data/lib/mutant/matcher/method/instance.rb +4 -1
  41. data/lib/mutant/matcher/method/singleton.rb +7 -1
  42. data/lib/mutant/matcher/methods.rb +3 -1
  43. data/lib/mutant/matcher/namespace.rb +4 -2
  44. data/lib/mutant/matcher/scope.rb +2 -0
  45. data/lib/mutant/mutation.rb +19 -5
  46. data/lib/mutant/mutation/evil.rb +12 -0
  47. data/lib/mutant/mutation/filter.rb +2 -0
  48. data/lib/mutant/mutation/filter/code.rb +3 -1
  49. data/lib/mutant/mutation/filter/regexp.rb +2 -0
  50. data/lib/mutant/mutation/filter/whitelist.rb +2 -0
  51. data/lib/mutant/mutation/neutral.rb +25 -0
  52. data/lib/mutant/mutator.rb +4 -6
  53. data/lib/mutant/mutator/node.rb +5 -1
  54. data/lib/mutant/mutator/node/argument.rb +2 -0
  55. data/lib/mutant/mutator/node/arguments.rb +2 -0
  56. data/lib/mutant/mutator/node/begin.rb +2 -0
  57. data/lib/mutant/mutator/node/block.rb +2 -0
  58. data/lib/mutant/mutator/node/case.rb +3 -1
  59. data/lib/mutant/mutator/node/connective/binary.rb +3 -1
  60. data/lib/mutant/mutator/node/const.rb +2 -0
  61. data/lib/mutant/mutator/node/define.rb +2 -0
  62. data/lib/mutant/mutator/node/generic.rb +4 -3
  63. data/lib/mutant/mutator/node/if.rb +2 -0
  64. data/lib/mutant/mutator/node/literal.rb +2 -0
  65. data/lib/mutant/mutator/node/literal/array.rb +2 -0
  66. data/lib/mutant/mutator/node/literal/boolean.rb +2 -0
  67. data/lib/mutant/mutator/node/literal/dynamic.rb +2 -0
  68. data/lib/mutant/mutator/node/literal/fixnum.rb +3 -1
  69. data/lib/mutant/mutator/node/literal/float.rb +2 -0
  70. data/lib/mutant/mutator/node/literal/hash.rb +2 -0
  71. data/lib/mutant/mutator/node/literal/nil.rb +2 -0
  72. data/lib/mutant/mutator/node/literal/range.rb +2 -1
  73. data/lib/mutant/mutator/node/literal/regex.rb +2 -0
  74. data/lib/mutant/mutator/node/literal/string.rb +2 -0
  75. data/lib/mutant/mutator/node/literal/symbol.rb +5 -1
  76. data/lib/mutant/mutator/node/masgn.rb +2 -0
  77. data/lib/mutant/mutator/node/mlhs.rb +2 -0
  78. data/lib/mutant/mutator/node/named_value/access.rb +2 -0
  79. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +2 -0
  80. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +3 -1
  81. data/lib/mutant/mutator/node/{cbase.rb → noop.rb} +7 -5
  82. data/lib/mutant/mutator/node/return.rb +2 -0
  83. data/lib/mutant/mutator/node/send.rb +2 -0
  84. data/lib/mutant/mutator/node/send/binary.rb +2 -0
  85. data/lib/mutant/mutator/node/splat.rb +2 -0
  86. data/lib/mutant/mutator/node/super.rb +2 -0
  87. data/lib/mutant/mutator/node/when.rb +3 -1
  88. data/lib/mutant/mutator/node/while.rb +2 -0
  89. data/lib/mutant/mutator/node/zsuper.rb +2 -0
  90. data/lib/mutant/mutator/registry.rb +55 -13
  91. data/lib/mutant/mutator/util.rb +2 -0
  92. data/lib/mutant/mutator/util/array.rb +3 -1
  93. data/lib/mutant/mutator/util/symbol.rb +2 -0
  94. data/lib/mutant/node_helpers.rb +10 -4
  95. data/lib/mutant/random.rb +2 -0
  96. data/lib/mutant/reporter.rb +2 -0
  97. data/lib/mutant/reporter/cli.rb +2 -0
  98. data/lib/mutant/reporter/cli/printer.rb +2 -0
  99. data/lib/mutant/reporter/cli/printer/config.rb +5 -2
  100. data/lib/mutant/reporter/cli/printer/killer.rb +2 -0
  101. data/lib/mutant/reporter/cli/printer/mutation.rb +13 -6
  102. data/lib/mutant/reporter/cli/printer/subject.rb +5 -1
  103. data/lib/mutant/reporter/null.rb +2 -0
  104. data/lib/mutant/runner.rb +2 -0
  105. data/lib/mutant/runner/config.rb +2 -0
  106. data/lib/mutant/runner/mutation.rb +2 -0
  107. data/lib/mutant/runner/subject.rb +2 -0
  108. data/lib/mutant/singleton_methods.rb +5 -3
  109. data/lib/mutant/strategy.rb +2 -0
  110. data/lib/mutant/strategy/method_expansion.rb +2 -0
  111. data/lib/mutant/strategy/rspec.rb +2 -0
  112. data/lib/mutant/strategy/rspec/dm2.rb +2 -0
  113. data/lib/mutant/strategy/rspec/dm2/lookup.rb +4 -2
  114. data/lib/mutant/strategy/rspec/dm2/lookup/method.rb +2 -0
  115. data/lib/mutant/strategy/static.rb +2 -0
  116. data/lib/mutant/subject.rb +4 -1
  117. data/lib/mutant/subject/method.rb +2 -0
  118. data/lib/mutant/subject/method/instance.rb +2 -0
  119. data/lib/mutant/subject/method/singleton.rb +2 -0
  120. data/lib/mutant/support/method_object.rb +2 -0
  121. data/lib/mutant/zombifier.rb +10 -6
  122. data/mutant.gemspec +11 -10
  123. data/spec/integration/mutant/rspec_killer_spec.rb +9 -4
  124. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +3 -1
  125. data/spec/integration/mutant/zombie_spec.rb +2 -0
  126. data/spec/shared/method_matcher_behavior.rb +2 -0
  127. data/spec/shared/mutator_behavior.rb +16 -7
  128. data/spec/spec_helper.rb +26 -5
  129. data/spec/support/compress_helper.rb +5 -5
  130. data/spec/support/ice_nine_config.rb +2 -0
  131. data/spec/support/rspec.rb +2 -0
  132. data/spec/support/test_app.rb +2 -0
  133. data/spec/unit/mutant/class_methods/singleton_subclass_instance_spec.rb +2 -0
  134. data/spec/unit/mutant/cli/class_methods/new_spec.rb +17 -8
  135. data/spec/unit/mutant/cli/class_methods/run_spec.rb +10 -2
  136. data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +4 -1
  137. data/spec/unit/mutant/cli/classifier/method/each_spec.rb +89 -0
  138. data/spec/unit/mutant/cli/classifier/namespace/flat/each_spec.rb +58 -0
  139. data/spec/unit/mutant/cli/classifier/namespace/recursive/each_spec.rb +58 -0
  140. data/spec/unit/mutant/cli/classifier/scope/each_spec.rb +33 -0
  141. data/spec/unit/mutant/context/root_spec.rb +5 -1
  142. data/spec/unit/mutant/context/scope/root_spec.rb +2 -0
  143. data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +2 -0
  144. data/spec/unit/mutant/differ/class_methods/build_spec.rb +2 -0
  145. data/spec/unit/mutant/differ/class_methods/colorize_line_spec.rb +2 -0
  146. data/spec/unit/mutant/differ/diff_spec.rb +67 -5
  147. data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +21 -4
  148. data/spec/unit/mutant/killer/success_predicate_spec.rb +2 -0
  149. data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +12 -5
  150. data/spec/unit/mutant/matcher/chain/each_spec.rb +2 -0
  151. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +2 -0
  152. data/spec/unit/mutant/matcher/each_spec.rb +8 -1
  153. data/spec/unit/mutant/matcher/method/instance/class_methods/build_spec.rb +4 -2
  154. data/spec/unit/mutant/matcher/method/instance/each_spec.rb +21 -20
  155. data/spec/unit/mutant/matcher/method/singleton/each_spec.rb +22 -19
  156. data/spec/unit/mutant/matcher/methods/instance/each_spec.rb +8 -3
  157. data/spec/unit/mutant/matcher/methods/singleton/each_spec.rb +8 -3
  158. data/spec/unit/mutant/matcher/namespace/each_spec.rb +8 -2
  159. data/spec/unit/mutant/mutator/each_spec.rb +2 -0
  160. data/spec/unit/mutant/mutator/emit_new_spec.rb +10 -3
  161. data/spec/unit/mutant/mutator/emit_spec.rb +4 -2
  162. data/spec/unit/mutant/mutator/node/and_asgn/mutation_spec.rb +26 -0
  163. data/spec/unit/mutant/mutator/node/begin/mutation_spec.rb +2 -0
  164. data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +4 -2
  165. data/spec/unit/mutant/mutator/node/block_pass/mutation_spec.rb +14 -0
  166. data/spec/unit/mutant/mutator/node/break/mutation_spec.rb +15 -0
  167. data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +2 -0
  168. data/spec/unit/mutant/mutator/node/cbase/mutation_spec.rb +3 -6
  169. data/spec/unit/mutant/mutator/node/connective/binary/mutation_spec.rb +2 -0
  170. data/spec/unit/mutant/mutator/node/const/mutation_spec.rb +3 -6
  171. data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +2 -1
  172. data/spec/unit/mutant/mutator/node/defined_predicate/mutation_spec.rb +10 -0
  173. data/spec/unit/mutant/mutator/node/dstr/mutation_spec.rb +21 -0
  174. data/spec/unit/mutant/mutator/node/dsym/mutation_spec.rb +21 -0
  175. data/spec/unit/mutant/mutator/node/ensure/mutation_spec.rb +15 -0
  176. data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +2 -1
  177. data/spec/unit/mutant/mutator/node/literal/array_spec.rb +2 -0
  178. data/spec/unit/mutant/mutator/node/literal/boolean/mutation_spec.rb +2 -0
  179. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +2 -0
  180. data/spec/unit/mutant/mutator/node/literal/float_spec.rb +4 -2
  181. data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +2 -0
  182. data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +4 -5
  183. data/spec/unit/mutant/mutator/node/literal/range_spec.rb +8 -8
  184. data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +2 -0
  185. data/spec/unit/mutant/mutator/node/literal/string_spec.rb +2 -0
  186. data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +2 -0
  187. data/spec/unit/mutant/mutator/node/masgn/mutation_spec.rb +4 -10
  188. data/spec/unit/mutant/mutator/node/match_current_line/mutation_spec.rb +20 -0
  189. data/spec/unit/mutant/mutator/node/named_value/access/mutation_spec.rb +3 -2
  190. data/spec/unit/mutant/mutator/node/named_value/constant_assignment/mutation_spec.rb +3 -2
  191. data/spec/unit/mutant/mutator/node/named_value/variable_assignment/mutation_spec.rb +3 -2
  192. data/spec/unit/mutant/mutator/node/next/mutation_spec.rb +15 -0
  193. data/spec/unit/mutant/mutator/node/op_assgn/mutation_spec.rb +26 -0
  194. data/spec/unit/mutant/mutator/node/or_asgn/mutation_spec.rb +26 -0
  195. data/spec/unit/mutant/mutator/node/redo/mutation_spec.rb +10 -0
  196. data/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb +24 -0
  197. data/spec/unit/mutant/mutator/node/restarg/mutation_spec.rb +16 -0
  198. data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +2 -0
  199. data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +3 -1
  200. data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +2 -0
  201. data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +3 -1
  202. data/spec/unit/mutant/mutator/node/yield/mutation_spec.rb +15 -0
  203. data/spec/unit/mutant/node_helpers/n_not_spec.rb +2 -0
  204. data/spec/unit/mutant/runner/config/subjects_spec.rb +6 -2
  205. data/spec/unit/mutant/runner/config/success_predicate_spec.rb +15 -6
  206. data/spec/unit/mutant/runner/mutation/killer_spec.rb +3 -1
  207. data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +15 -8
  208. data/spec/unit/mutant/strategy/method_expansion/class_methods/run_spec.rb +2 -0
  209. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/instance/spec_files_spec.rb +32 -11
  210. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/singleton/spec_files_spec.rb +31 -11
  211. data/spec/unit/mutant/subject/context_spec.rb +2 -0
  212. data/spec/unit/mutant/subject/mutations_spec.rb +2 -0
  213. data/spec/unit/mutant/subject/node_spec.rb +2 -0
  214. data/test_app/lib/test_app.rb +2 -0
  215. data/test_app/lib/test_app/literal.rb +2 -0
  216. data/test_app/spec/shared/method_filter_parse_behavior.rb +5 -1
  217. data/test_app/spec/shared/method_match_behavior.rb +2 -0
  218. data/test_app/spec/spec_helper.rb +3 -1
  219. data/test_app/spec/unit/test_app/literal/command_spec.rb +2 -0
  220. data/test_app/spec/unit/test_app/literal/string_spec.rb +3 -1
  221. metadata +66 -18
  222. data/bin/zombie +0 -18
  223. data/test_app/spec/shared/mutator_behavior.rb +0 -44
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class CLI
3
5
  # A classifier for input strings
@@ -6,13 +8,19 @@ module Mutant
6
8
 
7
9
  include Equalizer.new(:identifier)
8
10
 
9
- SCOPE_NAME_PATTERN = /[A-Za-z][A-Za-z_0-9]*/.freeze
10
- OPERATOR_PATTERN = Regexp.union(*OPERATOR_METHODS.map(&:to_s)).freeze
11
- METHOD_NAME_PATTERN = /([_A-Za-z][A-Za-z0-9_]*[!?=]?|#{OPERATOR_PATTERN})/.freeze
12
- SCOPE_PATTERN = /(?:::)?#{SCOPE_NAME_PATTERN}(?:::#{SCOPE_NAME_PATTERN})*/.freeze
13
- CBASE_PATTERN = /\A::/.freeze
14
- SCOPE_OPERATOR = '::'.freeze
15
- SINGLETON_PATTERN = %r(\A(#{SCOPE_PATTERN})\z).freeze
11
+ SCOPE_NAME_PATTERN = /[A-Za-z][A-Za-z\d_]*/.freeze
12
+ SCOPE_OPERATOR = '::'.freeze
13
+ CBASE_PATTERN = /\A#{SCOPE_OPERATOR}/.freeze
14
+
15
+ METHOD_NAME_PATTERN = Regexp.union(
16
+ /[A-Za-z_][A-Za-z\d_]*[!?=]?/,
17
+ *OPERATOR_METHODS.map(&:to_s)
18
+ ).freeze
19
+
20
+ SCOPE_PATTERN = /
21
+ (?:#{SCOPE_OPERATOR})?#{SCOPE_NAME_PATTERN}
22
+ (?:#{SCOPE_OPERATOR}#{SCOPE_NAME_PATTERN})*
23
+ /x.freeze
16
24
 
17
25
  REGISTRY = []
18
26
 
@@ -36,9 +44,12 @@ module Mutant
36
44
  # @api private
37
45
  #
38
46
  def self.constant_lookup(location)
39
- location.gsub(CBASE_PATTERN, EMPTY_STRING).split(SCOPE_OPERATOR).inject(Object) do |parent, name|
40
- parent.const_get(name)
41
- end
47
+ location
48
+ .sub(CBASE_PATTERN, EMPTY_STRING)
49
+ .split(SCOPE_OPERATOR)
50
+ .reduce(Object) do |parent, name|
51
+ parent.const_get(name, nil)
52
+ end
42
53
  end
43
54
 
44
55
  # Return matchers for input
@@ -119,6 +130,7 @@ module Mutant
119
130
  # @api private
120
131
  #
121
132
  abstract_method :matcher
133
+ private :matcher
122
134
 
123
135
  end # Classifier
124
136
  end # CLI
@@ -1,22 +1,33 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class CLI
3
5
  class Classifier
6
+
4
7
  # Explicit method classifier
5
8
  class Method < self
6
9
  register
7
10
 
8
11
  TABLE = {
9
12
  '.' => Matcher::Methods::Singleton,
10
- '#' => Matcher::Methods::Instance
13
+ '#' => Matcher::Methods::Instance,
11
14
  }.freeze
12
15
 
13
- REGEXP = %r(\A(#{SCOPE_PATTERN})([.#])(#{METHOD_NAME_PATTERN}\z)).freeze
16
+ REGEXP = /
17
+ \A
18
+ (#{SCOPE_PATTERN})
19
+ ([.#])
20
+ (#{METHOD_NAME_PATTERN})
21
+ \z
22
+ /x.freeze
14
23
 
15
24
  # Positions of captured regexp groups
16
25
  SCOPE_NAME_POSITION = 1
17
26
  SCOPE_SYMBOL_POSITION = 2
18
27
  METHOD_NAME_POSITION = 3
19
28
 
29
+ private
30
+
20
31
  # Return method matcher
21
32
  #
22
33
  # @return [Matcher::Method]
@@ -28,18 +39,6 @@ module Mutant
28
39
  end
29
40
  memoize :matcher
30
41
 
31
- # Return identification
32
- #
33
- # @return [String]
34
- #
35
- # @api private
36
- #
37
- def identification
38
- match.to_s
39
- end
40
-
41
- private
42
-
43
42
  # Return method
44
43
  #
45
44
  # @return [Method, UnboundMethod]
@@ -49,7 +48,7 @@ module Mutant
49
48
  def method
50
49
  methods_matcher.methods.detect do |method|
51
50
  method.name == method_name
52
- end or raise("Cannot find method #{identification}")
51
+ end or raise NameError, "Cannot find method #{identifier}"
53
52
  end
54
53
  memoize :method, :freezer => :noop
55
54
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class CLI
3
5
  class Classifier
@@ -29,15 +31,17 @@ module Mutant
29
31
 
30
32
  # Recursive namespace classifier
31
33
  class Recursive < self
32
- REGEXP = %r(\A(#{SCOPE_PATTERN})\*\z).freeze
34
+ REGEXP = /\A(#{SCOPE_PATTERN})\*\z/.freeze
33
35
  MATCHER = Matcher::Namespace
36
+
34
37
  register
35
38
  end # Recursive
36
39
 
37
40
  # Recursive namespace classifier
38
41
  class Flat < self
39
- REGEXP = %r(\A(#{SCOPE_PATTERN})\z).freeze
42
+ REGEXP = /\A(#{SCOPE_PATTERN})\z/.freeze
40
43
  MATCHER = Matcher::Scope
44
+
41
45
  register
42
46
  end # Flat
43
47
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class CLI
3
5
  class Classifier
@@ -5,7 +7,7 @@ module Mutant
5
7
  # Scope classifier
6
8
  class Scope < self
7
9
 
8
- REGEXP = %r(\A(#{SCOPE_PATTERN})\z).freeze
10
+ REGEXP = /\A(#{SCOPE_PATTERN})\z/.freeze
9
11
 
10
12
  private
11
13
 
data/lib/mutant/color.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # Class to colorize strings
3
5
  class Color
@@ -27,7 +29,8 @@ module Mutant
27
29
  "\e[#{@code}m#{text}\e[0m"
28
30
  end
29
31
 
30
- NONE = Class.new(self) do
32
+ Mutant.singleton_subclass_instance('NONE', self) do
33
+
31
34
  # Format null color
32
35
  #
33
36
  # @param [String] text
@@ -49,13 +52,14 @@ module Mutant
49
52
  #
50
53
  # @api private
51
54
  #
52
- def initialize(*)
55
+ def initialize
53
56
  end
54
57
 
55
- end.new.freeze
58
+ end
56
59
 
57
60
  RED = Color.new(31)
58
61
  GREEN = Color.new(32)
59
62
  BLUE = Color.new(34)
63
+
60
64
  end # Color
61
65
  end # Mutant
data/lib/mutant/config.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # The configuration of a mutator run
3
5
  class Config
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
 
3
5
  METHOD_POSTFIX_EXPANSIONS = {
@@ -17,8 +19,7 @@ module Mutant
17
19
  ].to_set.freeze
18
20
 
19
21
  # Set of node types that are not valid when emitted standalone
20
- NOT_STANDALONE = [ :splat, :block_pass ].to_set.freeze
21
-
22
+ NOT_STANDALONE = [:splat, :restarg, :block_pass].to_set.freeze
22
23
 
23
24
  OPERATOR_EXPANSIONS = {
24
25
  :<=> => :spaceship_operator,
@@ -50,7 +51,7 @@ module Mutant
50
51
  :'!' => :negation_operator
51
52
  }.freeze
52
53
 
53
- INDEX_OPERATORS = [ :[], :[]= ].freeze
54
+ INDEX_OPERATORS = [:[], :[]=].freeze
54
55
 
55
56
  UNARY_METHOD_OPERATORS = [
56
57
  :~@, :+@, :-@, :'!'
@@ -78,7 +79,7 @@ module Mutant
78
79
  :xstr, :def, :defs, :case, :when, :ivar, :lvar, :cvar, :gvar,
79
80
  :back_ref, :const, :nth_ref, :class, :sclass, :yield,
80
81
  :match_with_lvasgn, :match_current_line, :irange, :erange,
81
- :or_asgn, :kwbegin, :and_asgn
82
+ :or_asgn, :kwbegin, :and_asgn, :while
82
83
  ].to_set.freeze
83
84
 
84
85
  end # Mutant
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # An abstract context where mutations can be appied to.
3
5
  class Context
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Context
3
5
  # Scope context for mutation (Class or Module)
@@ -12,7 +14,7 @@ module Mutant
12
14
  # @api private
13
15
  #
14
16
  def root(node)
15
- nesting.reverse.inject(node) do |current, scope|
17
+ nesting.reverse.reduce(node) do |current, scope|
16
18
  self.class.wrap(scope, current)
17
19
  end
18
20
  end
data/lib/mutant/differ.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # Class to create diffs from source code
3
5
  class Differ
@@ -19,10 +21,16 @@ module Mutant
19
21
  when 0
20
22
  nil
21
23
  when 1
22
- output = Diff::LCS::Hunk.new(old, new, diffs.first, max_length, 0).diff(:unified)
24
+ output =
25
+ Diff::LCS::Hunk.new(
26
+ old, new, diffs.first, max_length, 0
27
+ ).diff(:unified)
23
28
  output << "\n"
24
29
  else
25
- $stderr.puts 'Mutation resulted in more than one diff, should not happen! PLS report a bug!'
30
+ $stderr.puts(
31
+ 'Mutation resulted in more than one diff, should not happen! ' +
32
+ 'PLS report a bug!'
33
+ )
26
34
  nil
27
35
  end
28
36
  end
data/lib/mutant/killer.rb CHANGED
@@ -1,7 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # Abstract base class for mutant killers
3
5
  class Killer
4
- include Adamantium::Flat, AbstractType, Equalizer.new(:strategy, :mutation, :killed?)
6
+ include Adamantium::Flat, AbstractType
7
+ include Equalizer.new(:strategy, :mutation, :killed?)
5
8
 
6
9
  # Return strategy
7
10
  #
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Killer
3
5
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Killer
3
5
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Killer
3
5
  # Runner for rspec tests
@@ -19,8 +21,22 @@ module Mutant
19
21
  mutation.insert
20
22
  # TODO: replace with real streams from configuration
21
23
  require 'stringio'
22
- null = StringIO.new
23
- !::RSpec::Core::Runner.run(command_line_arguments, null, null).zero?
24
+ # Note: We assume interesting output from a failed rspec run is stderr.
25
+ rspec_err = StringIO.new
26
+
27
+ exit_code = ::RSpec::Core::Runner.run(cli_arguments, nil, rspec_err)
28
+
29
+ killed = !exit_code.zero?
30
+
31
+ if killed and mutation.should_survive?
32
+ rspec_err.rewind
33
+
34
+ puts "#{mutation.class} test failed."
35
+ puts 'RSpec stderr:'
36
+ puts rspec_err.read
37
+ end
38
+
39
+ killed
24
40
  end
25
41
 
26
42
  # Return command line arguments
@@ -29,7 +45,7 @@ module Mutant
29
45
  #
30
46
  # @api private
31
47
  #
32
- def command_line_arguments
48
+ def cli_arguments
33
49
  %W(
34
50
  --fail-fast
35
51
  ) + strategy.spec_files(mutation.subject)
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Killer
3
5
  # Abstract base class for killer with static result
data/lib/mutant/loader.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # Base class for code loaders
3
5
  class Loader
@@ -40,7 +42,12 @@ module Mutant
40
42
  # @api private
41
43
  #
42
44
  def run
43
- eval(source, TOPLEVEL_BINDING, @subject.source_path.to_s, @subject.source_line)
45
+ eval(
46
+ source,
47
+ TOPLEVEL_BINDING,
48
+ @subject.source_path.to_s,
49
+ @subject.source_line
50
+ )
44
51
  end
45
52
 
46
53
  # Return source
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  # Abstract matcher to find subjects to mutate
3
5
  class Matcher
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Matcher
3
5
  # A chain of matchers
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Matcher
3
5
  # Matcher for subjects that are a specific method
@@ -6,7 +8,8 @@ module Mutant
6
8
 
7
9
  # Methods within rbx kernel directory are precompiled and their source
8
10
  # cannot be accessed via reading source location
9
- BLACKLIST = %r(\A#{Regexp.union('kernel/', '(eval)')}).freeze
11
+ SKIP_METHODS = %w[kernel/ (eval)].freeze
12
+ BLACKLIST = /\A#{Regexp.union(*SKIP_METHODS)}/.freeze
10
13
 
11
14
  # Enumerate matches
12
15
  #
@@ -25,7 +28,12 @@ module Mutant
25
28
  if subject
26
29
  yield subject
27
30
  else
28
- $stderr.puts "Cannot find definition of: #{identification} in #{source_location.join(':')}"
31
+ message = sprintf(
32
+ 'Cannot find definition of: %s in %s',
33
+ identification,
34
+ source_location.join(':')
35
+ )
36
+ $stderr.puts(message)
29
37
  end
30
38
  end
31
39
 
@@ -47,7 +55,11 @@ module Mutant
47
55
  def skip?
48
56
  location = source_location
49
57
  if location.nil? or BLACKLIST.match(location.first)
50
- $stderr.puts "#{method.inspect} does not have valid source location so mutant is unable to emit matcher"
58
+ message = sprintf(
59
+ '%s does not have valid source location unable to emit matcher',
60
+ method.inspect
61
+ )
62
+ $stderr.puts(message)
51
63
  return true
52
64
  end
53
65
 
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Matcher
3
5
  class Method
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Mutant
2
4
  class Matcher
3
5
  class Method
@@ -16,7 +18,8 @@ module Mutant
16
18
  # @api private
17
19
  #
18
20
  def self.build(cache, scope, method)
19
- if scope.ancestors.include?(::Adamantium) and scope.memoized?(method.name)
21
+ name = method.name
22
+ if scope.ancestors.include?(::Adamantium) and scope.memoized?(name)
20
23
  return Memoized.new(cache, scope, method)
21
24
  end
22
25
  super