mutant 0.9.6 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +121 -0
  3. data/.rubocop.yml +203 -0
  4. data/Changelog.md +26 -0
  5. data/Gemfile +0 -7
  6. data/Gemfile.lock +27 -87
  7. data/Gemfile.shared +7 -0
  8. data/README.md +88 -27
  9. data/config/reek.yml +1 -0
  10. data/lib/mutant.rb +4 -2
  11. data/lib/mutant/ast.rb +0 -9
  12. data/lib/mutant/ast/find_metaclass_containing.rb +48 -0
  13. data/lib/mutant/ast/meta/send.rb +0 -6
  14. data/lib/mutant/bootstrap.rb +0 -36
  15. data/lib/mutant/cli.rb +5 -49
  16. data/lib/mutant/config.rb +0 -8
  17. data/lib/mutant/context.rb +0 -3
  18. data/lib/mutant/env.rb +0 -6
  19. data/lib/mutant/expression/method.rb +6 -6
  20. data/lib/mutant/expression/methods.rb +6 -6
  21. data/lib/mutant/expression/parser.rb +0 -6
  22. data/lib/mutant/integration.rb +0 -18
  23. data/lib/mutant/isolation/fork.rb +0 -22
  24. data/lib/mutant/license.rb +11 -0
  25. data/lib/mutant/matcher.rb +0 -14
  26. data/lib/mutant/matcher/config.rb +0 -11
  27. data/lib/mutant/matcher/method.rb +0 -31
  28. data/lib/mutant/matcher/method/instance.rb +0 -8
  29. data/lib/mutant/matcher/method/metaclass.rb +86 -0
  30. data/lib/mutant/matcher/method/singleton.rb +0 -25
  31. data/lib/mutant/matcher/methods.rb +17 -28
  32. data/lib/mutant/matcher/namespace.rb +0 -10
  33. data/lib/mutant/matcher/scope.rb +2 -4
  34. data/lib/mutant/meta/example/dsl.rb +0 -21
  35. data/lib/mutant/meta/example/verification.rb +0 -20
  36. data/lib/mutant/mutation.rb +0 -3
  37. data/lib/mutant/mutator.rb +1 -29
  38. data/lib/mutant/mutator/node.rb +1 -66
  39. data/lib/mutant/mutator/node/and_asgn.rb +0 -3
  40. data/lib/mutant/mutator/node/argument.rb +0 -15
  41. data/lib/mutant/mutator/node/arguments.rb +0 -20
  42. data/lib/mutant/mutator/node/begin.rb +0 -3
  43. data/lib/mutant/mutator/node/binary.rb +0 -23
  44. data/lib/mutant/mutator/node/block.rb +0 -15
  45. data/lib/mutant/mutator/node/break.rb +0 -3
  46. data/lib/mutant/mutator/node/case.rb +0 -9
  47. data/lib/mutant/mutator/node/class.rb +0 -3
  48. data/lib/mutant/mutator/node/conditional_loop.rb +0 -3
  49. data/lib/mutant/mutator/node/const.rb +0 -3
  50. data/lib/mutant/mutator/node/define.rb +0 -11
  51. data/lib/mutant/mutator/node/defined.rb +0 -3
  52. data/lib/mutant/mutator/node/dstr.rb +0 -3
  53. data/lib/mutant/mutator/node/dsym.rb +0 -3
  54. data/lib/mutant/mutator/node/generic.rb +0 -67
  55. data/lib/mutant/mutator/node/if.rb +0 -12
  56. data/lib/mutant/mutator/node/index.rb +0 -27
  57. data/lib/mutant/mutator/node/kwbegin.rb +0 -3
  58. data/lib/mutant/mutator/node/literal.rb +0 -3
  59. data/lib/mutant/mutator/node/literal/array.rb +0 -6
  60. data/lib/mutant/mutator/node/literal/boolean.rb +0 -4
  61. data/lib/mutant/mutator/node/literal/float.rb +0 -9
  62. data/lib/mutant/mutator/node/literal/hash.rb +0 -9
  63. data/lib/mutant/mutator/node/literal/integer.rb +0 -9
  64. data/lib/mutant/mutator/node/literal/nil.rb +0 -3
  65. data/lib/mutant/mutator/node/literal/range.rb +4 -7
  66. data/lib/mutant/mutator/node/literal/regex.rb +0 -6
  67. data/lib/mutant/mutator/node/literal/string.rb +0 -3
  68. data/lib/mutant/mutator/node/literal/symbol.rb +0 -3
  69. data/lib/mutant/mutator/node/masgn.rb +0 -3
  70. data/lib/mutant/mutator/node/match_current_line.rb +0 -3
  71. data/lib/mutant/mutator/node/mlhs.rb +0 -3
  72. data/lib/mutant/mutator/node/named_value/access.rb +2 -14
  73. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -9
  74. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -6
  75. data/lib/mutant/mutator/node/next.rb +0 -3
  76. data/lib/mutant/mutator/node/noop.rb +0 -3
  77. data/lib/mutant/mutator/node/nthref.rb +0 -3
  78. data/lib/mutant/mutator/node/op_asgn.rb +0 -3
  79. data/lib/mutant/mutator/node/or_asgn.rb +0 -3
  80. data/lib/mutant/mutator/node/procarg_zero.rb +0 -3
  81. data/lib/mutant/mutator/node/regopt.rb +0 -6
  82. data/lib/mutant/mutator/node/resbody.rb +0 -6
  83. data/lib/mutant/mutator/node/rescue.rb +2 -19
  84. data/lib/mutant/mutator/node/return.rb +0 -3
  85. data/lib/mutant/mutator/node/sclass.rb +20 -0
  86. data/lib/mutant/mutator/node/send.rb +2 -61
  87. data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -9
  88. data/lib/mutant/mutator/node/send/binary.rb +0 -11
  89. data/lib/mutant/mutator/node/send/conditional.rb +0 -3
  90. data/lib/mutant/mutator/node/splat.rb +0 -3
  91. data/lib/mutant/mutator/node/super.rb +0 -3
  92. data/lib/mutant/mutator/node/when.rb +0 -19
  93. data/lib/mutant/mutator/node/yield.rb +0 -3
  94. data/lib/mutant/mutator/node/zsuper.rb +0 -3
  95. data/lib/mutant/mutator/util/array.rb +0 -6
  96. data/lib/mutant/mutator/util/symbol.rb +0 -3
  97. data/lib/mutant/parallel.rb +0 -13
  98. data/lib/mutant/parallel/driver.rb +0 -10
  99. data/lib/mutant/parallel/worker.rb +0 -22
  100. data/lib/mutant/registry.rb +2 -7
  101. data/lib/mutant/reporter/cli.rb +0 -5
  102. data/lib/mutant/reporter/cli/format.rb +0 -9
  103. data/lib/mutant/reporter/cli/printer.rb +2 -42
  104. data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -15
  105. data/lib/mutant/reporter/cli/printer/isolation_result.rb +0 -18
  106. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -5
  107. data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -22
  108. data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -8
  109. data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -9
  110. data/lib/mutant/repository/diff.rb +1 -13
  111. data/lib/mutant/repository/diff/ranges.rb +0 -11
  112. data/lib/mutant/result.rb +0 -3
  113. data/lib/mutant/runner.rb +0 -18
  114. data/lib/mutant/runner/sink.rb +0 -5
  115. data/lib/mutant/subject.rb +0 -8
  116. data/lib/mutant/subject/method.rb +0 -3
  117. data/lib/mutant/subject/method/instance.rb +40 -6
  118. data/lib/mutant/subject/method/metaclass.rb +30 -0
  119. data/lib/mutant/transform.rb +0 -92
  120. data/lib/mutant/version.rb +1 -1
  121. data/lib/mutant/warnings.rb +0 -6
  122. data/lib/mutant/zombifier.rb +2 -34
  123. data/meta/and.rb +0 -2
  124. data/meta/array.rb +0 -3
  125. data/meta/begin.rb +0 -3
  126. data/meta/block.rb +0 -3
  127. data/meta/break.rb +0 -1
  128. data/meta/case.rb +0 -6
  129. data/meta/casgn.rb +0 -3
  130. data/meta/cvasgn.rb +0 -1
  131. data/meta/def.rb +0 -7
  132. data/meta/ensure.rb +0 -1
  133. data/meta/false.rb +0 -1
  134. data/meta/gvasgn.rb +0 -1
  135. data/meta/hash.rb +0 -4
  136. data/meta/if.rb +0 -5
  137. data/meta/ivasgn.rb +0 -1
  138. data/meta/kwbegin.rb +0 -1
  139. data/meta/lvasgn.rb +0 -1
  140. data/meta/match_current_line.rb +0 -1
  141. data/meta/next.rb +0 -1
  142. data/meta/or.rb +0 -2
  143. data/meta/range.rb +24 -0
  144. data/meta/regexp.rb +0 -1
  145. data/meta/rescue.rb +0 -6
  146. data/meta/sclass.rb +12 -0
  147. data/meta/send.rb +0 -4
  148. data/meta/true.rb +0 -1
  149. data/meta/until.rb +0 -1
  150. data/meta/while.rb +0 -2
  151. data/meta/yield.rb +0 -1
  152. data/mutant.gemspec +7 -4
  153. data/mutant.sh +12 -0
  154. data/spec/spec_helper.rb +37 -22
  155. data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +64 -0
  156. data/spec/unit/mutant/expression/methods_spec.rb +7 -2
  157. data/spec/unit/mutant/license_spec.rb +15 -3
  158. data/spec/unit/mutant/matcher/method/metaclass_spec.rb +108 -0
  159. data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +62 -0
  160. data/spec/unit/mutant/matcher/namespace_spec.rb +3 -1
  161. data/spec/unit/mutant/matcher/scope_spec.rb +11 -1
  162. data/spec/unit/mutant/meta/example_spec.rb +3 -3
  163. data/spec/unit/mutant/mutator/node_spec.rb +1 -6
  164. data/spec/unit/mutant/registry_spec.rb +52 -25
  165. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +1 -1
  166. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +2 -2
  167. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +12 -12
  168. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +1 -1
  169. data/spec/unit/mutant/reporter/cli/printer_spec.rb +4 -4
  170. data/spec/unit/mutant/reporter/cli_spec.rb +1 -1
  171. data/spec/unit/mutant/subject/method/instance_spec.rb +117 -22
  172. data/spec/unit/mutant/subject/method/metaclass_spec.rb +63 -0
  173. data/test_app/Gemfile.minitest +2 -0
  174. data/test_app/lib/test_app.rb +5 -0
  175. data/test_app/lib/test_app/metaclasses.rb +108 -0
  176. metadata +74 -25
  177. data/.circleci/config.yml +0 -53
  178. data/config/rubocop.yml +0 -205
  179. data/lib/mutant/color.rb +0 -43
  180. data/lib/mutant/diff.rb +0 -114
  181. data/spec/shared/base_behavior.rb +0 -45
  182. data/spec/support/test_app.rb +0 -7
  183. data/spec/support/warnings.yml +0 -6
  184. data/spec/unit/mutant/diff_spec.rb +0 -189
@@ -1,53 +0,0 @@
1
- defaults: &defaults
2
- working_directory: ~/mutant
3
- docker:
4
- - image: circleci/ruby:2.6.0
5
- version: 2
6
- jobs:
7
- unit_specs:
8
- <<: *defaults
9
- steps:
10
- - checkout
11
- - run: bundle install
12
- - run: bundle exec rspec spec/unit spec/integration/mutant/test_mutator_handles_types_spec.rb
13
- integration_minitest:
14
- <<: *defaults
15
- steps:
16
- - checkout
17
- - run: bundle install
18
- - run: bundle exec rspec spec/integration -e minitest
19
- integration_rspec:
20
- <<: *defaults
21
- steps:
22
- - checkout
23
- - run: bundle install
24
- - run: bundle exec rspec spec/integration -e rspec
25
- integration_mutation_generation:
26
- <<: *defaults
27
- steps:
28
- - checkout
29
- - run: bundle install
30
- - run: bundle exec rspec spec/integration -e generation
31
- metrics:
32
- <<: *defaults
33
- steps:
34
- - checkout
35
- - run: bundle install
36
- - run: bundle exec rake metrics:rubocop
37
- - run: bundle exec rake metrics:reek
38
- mutant:
39
- <<: *defaults
40
- steps:
41
- - checkout
42
- - run: bundle install
43
- - run: bundle exec mutant --jobs 4 --since HEAD~1 --zombie -- 'Mutant*'
44
- workflows:
45
- version: 2
46
- test:
47
- jobs:
48
- - unit_specs
49
- - integration_rspec
50
- - integration_minitest
51
- - integration_mutation_generation
52
- - metrics
53
- - mutant
@@ -1,205 +0,0 @@
1
- inherit_from: ../.rubocop.yml
2
-
3
- # Avoid parameter lists longer than five parameters.
4
- ParameterLists:
5
- Max: 3
6
- CountKeywordArgs: true
7
-
8
- # Avoid more than `Max` levels of nesting.
9
- BlockNesting:
10
- Max: 3
11
-
12
- # Align with the style guide.
13
- CollectionMethods:
14
- Enabled: true
15
- PreferredMethods:
16
- collect: 'map'
17
- inject: 'reduce'
18
- find: 'detect'
19
- find_all: 'select'
20
-
21
- AccessModifierIndentation:
22
- Enabled: false
23
-
24
- # Limit line length
25
- LineLength:
26
- Max: 120
27
-
28
- # Disable documentation checking until a class needs to be documented once
29
- Documentation:
30
- Enabled: false
31
-
32
- # Permit
33
- #
34
- # boolean_check? or fail
35
- #
36
- # Reject
37
- #
38
- # if foo or bar
39
- # ...
40
- # end
41
- AndOr:
42
- EnforcedStyle: conditionals
43
-
44
- # Do not favor modifier if/unless usage when you have a single-line body
45
- IfUnlessModifier:
46
- Enabled: false
47
-
48
- # Allow case equality operator (in limited use within the specs)
49
- CaseEquality:
50
- Enabled: false
51
-
52
- # Constants do not always have to use SCREAMING_SNAKE_CASE
53
- ConstantName:
54
- Enabled: false
55
-
56
- # Not all trivial readers/writers can be defined with attr_* methods
57
- TrivialAccessors:
58
- Enabled: false
59
-
60
- # Allow empty lines around class body
61
- EmptyLinesAroundClassBody:
62
- Enabled: false
63
-
64
- # Allow empty lines around module body
65
- EmptyLinesAroundModuleBody:
66
- Enabled: false
67
-
68
- # Allow empty lines around block body
69
- EmptyLinesAroundBlockBody:
70
- Enabled: false
71
-
72
- # Allow multiple line operations to not require indentation
73
- MultilineOperationIndentation:
74
- Enabled: false
75
-
76
- # Prefer String#% over Kernel#sprintf
77
- FormatString:
78
- EnforcedStyle: percent
79
-
80
- # Use square brackets for literal Array objects
81
- PercentLiteralDelimiters:
82
- PreferredDelimiters:
83
- '%': '{}'
84
- '%i': '[]'
85
- '%q': ()
86
- '%Q': ()
87
- '%r': '{}'
88
- '%s': ()
89
- '%w': '[]'
90
- '%W': '[]'
91
- '%x': ()
92
-
93
- # Use %i[...] for arrays of symbols
94
- SymbolArray:
95
- Enabled: true
96
-
97
- # Prefer #kind_of? over #is_a?
98
- ClassCheck:
99
- EnforcedStyle: kind_of?
100
-
101
- # Do not prefer double quotes to be used when %q or %Q is more appropriate
102
- Style/RedundantPercentQ:
103
- Enabled: false
104
-
105
- # Allow a maximum ABC score
106
- Metrics/AbcSize:
107
- Max: 21.02
108
-
109
- Metrics/BlockLength:
110
- Exclude:
111
- - 'spec/**/*.rb'
112
- - 'mutant.gemspec'
113
-
114
- # Buggy cop, returns false positive for our code base
115
- NonLocalExitFromIterator:
116
- Enabled: false
117
-
118
- # To allow alignment of similar expressions we want to allow more than one
119
- # space around operators:
120
- #
121
- # let(:a) { bar + something }
122
- # let(:b) { foobar + something }
123
- #
124
- SpaceAroundOperators:
125
- Enabled: false
126
-
127
- # We use parallel assignments with great success
128
- ParallelAssignment:
129
- Enabled: false
130
-
131
- # Allow additional specs
132
- ExtraSpacing:
133
- AllowForAlignment: true
134
-
135
- # Buggy
136
- FormatParameterMismatch:
137
- Enabled: false
138
-
139
- # Different preference
140
- SignalException:
141
- EnforcedStyle: semantic
142
-
143
- # Do not use `alias`
144
- Alias:
145
- EnforcedStyle: prefer_alias_method
146
-
147
- # Do not waste my horizontal or vertical space
148
- Layout/FirstArrayElementIndentation:
149
- Enabled: false
150
-
151
- # Prefer
152
- #
153
- # some_receiver
154
- # .foo
155
- # .bar
156
- # .baz
157
- #
158
- # Over
159
- #
160
- # some_receiver.foo
161
- # .bar
162
- # .baz
163
- MultilineMethodCallIndentation:
164
- EnforcedStyle: indented
165
-
166
- # Prefer `public_send` and `__send__` over `send`
167
- Send:
168
- Enabled: true
169
-
170
- Layout/HashAlignment:
171
- EnforcedColonStyle: table
172
- EnforcedHashRocketStyle: table
173
- Layout/EmptyLineAfterGuardClause:
174
- Enabled: false
175
- Layout/SpaceInsideArrayLiteralBrackets:
176
- Enabled: false
177
- Lint/BooleanSymbol:
178
- Enabled: false
179
- Lint/InterpolationCheck:
180
- Enabled: false
181
- Lint/MissingCopEnableDirective:
182
- Enabled: false
183
- Lint/UnifiedInteger:
184
- Enabled: false
185
- Naming/FileName:
186
- Enabled: false
187
- Style/AccessModifierDeclarations:
188
- Enabled: false
189
- Style/CommentedKeyword:
190
- Enabled: false
191
- Style/MixinGrouping:
192
- Enabled: false
193
- Style/RaiseArgs:
194
- Enabled: false
195
- Style/RescueStandardError:
196
- Enabled: false
197
- Style/StderrPuts:
198
- Enabled: false
199
- # suggesting single letter variablesl bah
200
- Naming/RescuedExceptionsVariableName:
201
- Enabled: false
202
- # false positive on private keywords
203
- Layout/IndentationWidth:
204
- Enabled: false
205
-
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- # Class to colorize strings
5
- class Color
6
- include Adamantium::Flat, Concord.new(:code)
7
-
8
- # Format text with color
9
- #
10
- # @param [String] text
11
- #
12
- # @return [String]
13
- def format(text)
14
- "\e[#{code}m#{text}\e[0m"
15
- end
16
-
17
- NONE = Class.new(self) do
18
-
19
- # Format null color
20
- #
21
- # @param [String] text
22
- #
23
- # @return [String]
24
- # the argument string
25
- def format(text)
26
- text
27
- end
28
-
29
- private
30
-
31
- # Initialize null color
32
- #
33
- # @return [undefined]
34
- def initialize; end
35
-
36
- end.new
37
-
38
- RED = Color.new(31)
39
- GREEN = Color.new(32)
40
- BLUE = Color.new(34)
41
-
42
- end # Color
43
- end # Mutant
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- # Class to create diffs from source code
5
- class Diff
6
- include Adamantium::Flat, Concord.new(:old, :new)
7
-
8
- ADDITION = '+'
9
- DELETION = '-'
10
- NEWLINE = "\n"
11
-
12
- # Unified source diff between old and new
13
- #
14
- # @return [String]
15
- # if there is exactly one diff
16
- #
17
- # @return [nil]
18
- # otherwise
19
- def diff
20
- return if diffs.empty?
21
-
22
- minimized_hunk.diff(:unified) + NEWLINE
23
- end
24
- memoize :diff
25
-
26
- # Colorized unified source diff between old and new
27
- #
28
- # @return [String]
29
- # if there is a diff
30
- #
31
- # @return [nil]
32
- # otherwise
33
- def colorized_diff
34
- return unless diff
35
- diff.lines.map(&self.class.method(:colorize_line)).join
36
- end
37
- memoize :colorized_diff
38
-
39
- # Build new object from source strings
40
- #
41
- # @param [String] old
42
- # @param [String] new
43
- #
44
- # @return [Diff]
45
- def self.build(old, new)
46
- new(lines(old), lines(new))
47
- end
48
-
49
- # Break up source into lines
50
- #
51
- # @param [String] source
52
- #
53
- # @return [Array<String>]
54
- def self.lines(source)
55
- source.lines.map(&:chomp)
56
- end
57
- private_class_method :lines
58
-
59
- private
60
-
61
- # Diffs between old and new
62
- #
63
- # @return [Array<Array>]
64
- def diffs
65
- ::Diff::LCS.diff(old, new)
66
- end
67
-
68
- # Raw diff-lcs hunks
69
- #
70
- # @return [Array<Diff::LCS::Hunk>]
71
- def hunks
72
- diffs.map do |diff|
73
- ::Diff::LCS::Hunk.new(old.map(&:dup), new, diff, max_length, 0)
74
- end
75
- end
76
-
77
- # Minimized hunk
78
- #
79
- # @return Diff::LCS::Hunk
80
- def minimized_hunk
81
- head, *tail = hunks
82
-
83
- tail.reduce(head) do |left, right|
84
- right.merge(left)
85
- right
86
- end
87
- end
88
-
89
- # Max length of source line in new and old
90
- #
91
- # @return [Integer]
92
- def max_length
93
- [old, new].map(&:length).max
94
- end
95
-
96
- # Colorized a unified diff line
97
- #
98
- # @param [String] line
99
- #
100
- # @return [String]
101
- def self.colorize_line(line)
102
- case line[0]
103
- when ADDITION
104
- Color::GREEN
105
- when DELETION
106
- Color::RED
107
- else
108
- Color::NONE
109
- end.format(line)
110
- end
111
- private_class_method :colorize_line
112
-
113
- end # Diff
114
- end # Mutant
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.shared_examples 'no block evaluation' do
4
- context 'with block' do
5
- let(:block) { -> { fail } }
6
-
7
- it 'does not evaluate block' do
8
- apply
9
- end
10
- end
11
- end
12
-
13
- RSpec.shared_examples 'requires block' do
14
- context 'without block' do
15
- let(:block) { nil }
16
-
17
- specify do
18
- expect { apply }.to raise_error(LocalJumpError)
19
- end
20
- end
21
- end
22
-
23
- RSpec.shared_examples 'returns self' do
24
- it 'returns self' do
25
- expect(apply).to be(subject)
26
- end
27
- end
28
-
29
- RSpec.shared_examples '#apply block evaluation' do
30
- it 'evaluates block and returns its wrapped result' do
31
- expect { expect(apply).to eql(block_result) }
32
- .to change(yields, :to_a)
33
- .from([])
34
- .to([value])
35
- end
36
- end
37
-
38
- RSpec.shared_examples 'Functor#fmap block evaluation' do
39
- it 'evaluates block and returns its wrapped result' do
40
- expect { expect(apply).to eql(described_class.new(block_result)) }
41
- .to change(yields, :to_a)
42
- .from([])
43
- .to([value])
44
- end
45
- end