mutant 0.8.10 → 0.8.11
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -4
- data/Changelog.md +8 -0
- data/README.md +112 -43
- data/Rakefile +2 -16
- data/circle.yml +1 -1
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/reek.yml +3 -4
- data/config/rubocop.yml +53 -16
- data/lib/mutant.rb +27 -6
- data/lib/mutant/ast/meta/const.rb +2 -0
- data/lib/mutant/ast/meta/optarg.rb +2 -0
- data/lib/mutant/ast/meta/resbody.rb +2 -0
- data/lib/mutant/ast/meta/restarg.rb +2 -0
- data/lib/mutant/ast/meta/send.rb +4 -0
- data/lib/mutant/ast/meta/symbol.rb +2 -0
- data/lib/mutant/ast/named_children.rb +14 -4
- data/lib/mutant/ast/nodes.rb +3 -1
- data/lib/mutant/ast/regexp.rb +53 -0
- data/lib/mutant/ast/regexp/transformer.rb +185 -0
- data/lib/mutant/ast/regexp/transformer/alternative.rb +39 -0
- data/lib/mutant/ast/regexp/transformer/character_set.rb +46 -0
- data/lib/mutant/ast/regexp/transformer/direct.rb +99 -0
- data/lib/mutant/ast/regexp/transformer/options_group.rb +66 -0
- data/lib/mutant/ast/regexp/transformer/quantifier.rb +112 -0
- data/lib/mutant/ast/regexp/transformer/recursive.rb +50 -0
- data/lib/mutant/ast/regexp/transformer/root.rb +29 -0
- data/lib/mutant/ast/regexp/transformer/text.rb +55 -0
- data/lib/mutant/ast/types.rb +92 -5
- data/lib/mutant/cli.rb +2 -14
- data/lib/mutant/color.rb +1 -1
- data/lib/mutant/config.rb +1 -3
- data/lib/mutant/expression/methods.rb +1 -1
- data/lib/mutant/expression/namespace.rb +2 -2
- data/lib/mutant/expression/parser.rb +1 -1
- data/lib/mutant/integration.rb +10 -28
- data/lib/mutant/isolation.rb +9 -60
- data/lib/mutant/isolation/fork.rb +72 -0
- data/lib/mutant/isolation/none.rb +25 -0
- data/lib/mutant/matcher/config.rb +2 -0
- data/lib/mutant/matcher/method/singleton.rb +5 -4
- data/lib/mutant/meta.rb +11 -4
- data/lib/mutant/meta/example.rb +2 -116
- data/lib/mutant/meta/example/dsl.rb +22 -19
- data/lib/mutant/meta/example/verification.rb +86 -0
- data/lib/mutant/mutator.rb +22 -49
- data/lib/mutant/mutator/node.rb +15 -19
- data/lib/mutant/mutator/node/and_asgn.rb +1 -1
- data/lib/mutant/mutator/node/argument.rb +10 -5
- data/lib/mutant/mutator/node/arguments.rb +5 -9
- data/lib/mutant/mutator/node/begin.rb +4 -17
- data/lib/mutant/mutator/node/block.rb +1 -1
- data/lib/mutant/mutator/node/break.rb +1 -1
- data/lib/mutant/mutator/node/class.rb +21 -0
- data/lib/mutant/mutator/node/conditional_loop.rb +1 -1
- data/lib/mutant/mutator/node/define.rb +1 -1
- data/lib/mutant/mutator/node/defined.rb +1 -1
- data/lib/mutant/mutator/node/dstr.rb +1 -1
- data/lib/mutant/mutator/node/dsym.rb +1 -1
- data/lib/mutant/mutator/node/generic.rb +3 -3
- data/lib/mutant/mutator/node/kwbegin.rb +1 -1
- data/lib/mutant/mutator/node/literal.rb +9 -0
- data/lib/mutant/mutator/node/literal/boolean.rb +1 -1
- data/lib/mutant/mutator/node/literal/fixnum.rb +2 -2
- data/lib/mutant/mutator/node/literal/float.rb +4 -6
- data/lib/mutant/mutator/node/literal/hash.rb +1 -1
- data/lib/mutant/mutator/node/literal/nil.rb +1 -1
- data/lib/mutant/mutator/node/literal/range.rb +2 -19
- data/lib/mutant/mutator/node/literal/regex.rb +43 -3
- data/lib/mutant/mutator/node/literal/string.rb +1 -1
- data/lib/mutant/mutator/node/literal/symbol.rb +2 -4
- data/lib/mutant/mutator/node/masgn.rb +1 -1
- data/lib/mutant/mutator/node/match_current_line.rb +1 -1
- data/lib/mutant/mutator/node/mlhs.rb +2 -3
- data/lib/mutant/mutator/node/named_value/access.rb +2 -2
- data/lib/mutant/mutator/node/named_value/constant_assignment.rb +4 -3
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +4 -4
- data/lib/mutant/mutator/node/next.rb +1 -1
- data/lib/mutant/mutator/node/nthref.rb +1 -1
- data/lib/mutant/mutator/node/or_asgn.rb +1 -1
- data/lib/mutant/mutator/node/regexp.rb +44 -0
- data/lib/mutant/mutator/node/regopt.rb +31 -0
- data/lib/mutant/mutator/node/resbody.rb +1 -1
- data/lib/mutant/mutator/node/rescue.rb +1 -3
- data/lib/mutant/mutator/node/return.rb +1 -1
- data/lib/mutant/mutator/node/send.rb +43 -3
- data/lib/mutant/mutator/node/send/attribute_assignment.rb +4 -1
- data/lib/mutant/mutator/node/send/conditional.rb +23 -0
- data/lib/mutant/mutator/node/send/index.rb +1 -1
- data/lib/mutant/mutator/node/splat.rb +1 -1
- data/lib/mutant/mutator/node/when.rb +1 -1
- data/lib/mutant/mutator/node/yield.rb +1 -1
- data/lib/mutant/mutator/util.rb +0 -30
- data/lib/mutant/mutator/util/array.rb +4 -16
- data/lib/mutant/parallel.rb +1 -1
- data/lib/mutant/parallel/worker.rb +1 -1
- data/lib/mutant/registry.rb +44 -0
- data/lib/mutant/reporter/cli/format.rb +2 -0
- data/lib/mutant/reporter/cli/printer.rb +2 -2
- data/lib/mutant/reporter/cli/printer/config.rb +0 -1
- data/lib/mutant/reporter/cli/printer/env_progress.rb +1 -11
- data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +1 -1
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +2 -0
- data/lib/mutant/reporter/cli/tput.rb +1 -1
- data/lib/mutant/reporter/sequence.rb +3 -0
- data/lib/mutant/require_highjack.rb +6 -2
- data/lib/mutant/result.rb +1 -1
- data/lib/mutant/subject.rb +5 -5
- data/lib/mutant/subject/method/instance.rb +1 -2
- data/lib/mutant/util.rb +18 -0
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/zombifier.rb +5 -3
- data/meta/and.rb +1 -1
- data/meta/and_asgn.rb +1 -1
- data/meta/array.rb +2 -2
- data/meta/begin.rb +2 -2
- data/meta/block.rb +7 -7
- data/meta/block_pass.rb +1 -1
- data/meta/blockarg.rb +1 -1
- data/meta/break.rb +1 -1
- data/meta/case.rb +2 -2
- data/meta/casgn.rb +11 -2
- data/meta/cbase.rb +1 -1
- data/meta/class.rb +10 -0
- data/meta/const.rb +9 -1
- data/meta/csend.rb +8 -0
- data/meta/cvar.rb +1 -1
- data/meta/cvasgn.rb +1 -1
- data/meta/date.rb +4 -4
- data/meta/def.rb +14 -14
- data/meta/defined.rb +1 -1
- data/meta/dstr.rb +1 -1
- data/meta/dsym.rb +1 -1
- data/meta/ensure.rb +1 -1
- data/meta/false.rb +1 -1
- data/meta/float.rb +3 -3
- data/meta/gvar.rb +1 -1
- data/meta/gvasgn.rb +1 -1
- data/meta/hash.rb +1 -1
- data/meta/if.rb +17 -3
- data/meta/int.rb +1 -1
- data/meta/ivar.rb +1 -1
- data/meta/ivasgn.rb +14 -1
- data/meta/kwarg.rb +8 -0
- data/meta/kwbegin.rb +1 -1
- data/meta/kwoptarg.rb +11 -0
- data/meta/lvar.rb +1 -1
- data/meta/lvasgn.rb +1 -1
- data/meta/masgn.rb +1 -1
- data/meta/match_current_line.rb +2 -2
- data/meta/next.rb +1 -1
- data/meta/nil.rb +1 -1
- data/meta/nthref.rb +5 -5
- data/meta/op_assgn.rb +1 -1
- data/meta/or.rb +1 -1
- data/meta/or_asgn.rb +5 -5
- data/meta/range.rb +2 -8
- data/meta/redo.rb +1 -1
- data/meta/regexp.rb +106 -0
- data/meta/regexp/regexp_bol_anchor.rb +13 -0
- data/meta/regexp/regexp_bos_anchor.rb +26 -0
- data/meta/regexp/regexp_root_expression.rb +13 -0
- data/meta/regopt.rb +8 -0
- data/meta/rescue.rb +49 -4
- data/meta/restarg.rb +6 -9
- data/meta/return.rb +2 -2
- data/meta/self.rb +1 -1
- data/meta/send.rb +228 -55
- data/meta/str.rb +1 -1
- data/meta/super.rb +3 -3
- data/meta/{symbol.rb → sym.rb} +1 -1
- data/meta/true.rb +1 -1
- data/meta/until.rb +1 -1
- data/meta/while.rb +2 -2
- data/meta/yield.rb +1 -1
- data/mutant-rspec.gemspec +2 -2
- data/mutant.gemspec +6 -5
- data/spec/integration/mutant/isolation/fork_spec.rb +8 -0
- data/spec/integration/mutant/rspec_spec.rb +1 -1
- data/spec/integration/mutant/test_mutator_handles_types_spec.rb +1 -2
- data/spec/integrations.yml +93 -24
- data/spec/spec_helper.rb +12 -7
- data/spec/support/compress_helper.rb +1 -1
- data/spec/support/corpus.rb +115 -50
- data/spec/support/fake_actor.rb +5 -5
- data/spec/support/file_system.rb +1 -1
- data/spec/support/ice_nine_config.rb +3 -3
- data/spec/support/ruby_vm.rb +11 -12
- data/spec/support/shared_context.rb +22 -13
- data/spec/support/test_app.rb +1 -1
- data/spec/support/warning.rb +64 -0
- data/spec/support/warnings.yml +4 -0
- data/spec/support/xspec.rb +177 -0
- data/spec/unit/mutant/actor/env_spec.rb +2 -2
- data/spec/unit/mutant/actor/sender_spec.rb +1 -1
- data/spec/unit/mutant/ast/meta/send_spec.rb +1 -1
- data/spec/unit/mutant/ast/named_children_spec.rb +26 -0
- data/spec/unit/mutant/ast/regexp/parse_spec.rb +7 -0
- data/spec/unit/mutant/ast/regexp/supported_predicate_spec.rb +14 -0
- data/spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb +19 -0
- data/spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb +33 -0
- data/spec/unit/mutant/ast/regexp/transformer_spec.rb +19 -0
- data/spec/unit/mutant/ast/regexp_spec.rb +617 -0
- data/spec/unit/mutant/cli_spec.rb +7 -45
- data/spec/unit/mutant/context_spec.rb +4 -7
- data/spec/unit/mutant/env/{boostrap_spec.rb → bootstrap_spec.rb} +2 -2
- data/spec/unit/mutant/env_spec.rb +13 -16
- data/spec/unit/mutant/expression/namespace/{flat_spec.rb → exact_spec.rb} +0 -0
- data/spec/unit/mutant/integration/rspec_spec.rb +2 -2
- data/spec/unit/mutant/integration_spec.rb +14 -0
- data/spec/unit/mutant/isolation/fork_spec.rb +155 -0
- data/spec/unit/mutant/isolation/none_spec.rb +16 -0
- data/spec/unit/mutant/loader_spec.rb +1 -1
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +2 -4
- data/spec/unit/mutant/meta/example/dsl_spec.rb +106 -0
- data/spec/unit/mutant/meta/example/verification_spec.rb +120 -0
- data/spec/unit/mutant/meta/example_spec.rb +32 -0
- data/spec/unit/mutant/mutator/node_spec.rb +37 -4
- data/spec/unit/mutant/mutator_spec.rb +21 -0
- data/spec/unit/mutant/{runner → parallel}/driver_spec.rb +0 -0
- data/spec/unit/mutant/parallel/master_spec.rb +13 -13
- data/spec/unit/mutant/registry_spec.rb +47 -0
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -4
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -8
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -2
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -8
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +0 -34
- data/spec/unit/mutant/reporter/cli_spec.rb +0 -22
- data/spec/unit/mutant/repository/diff_spec.rb +6 -6
- data/spec/unit/mutant/require_highjack_spec.rb +38 -14
- data/spec/unit/mutant/result/env_spec.rb +1 -4
- data/spec/unit/mutant/runner_spec.rb +1 -1
- data/spec/unit/mutant/subject/method/instance_spec.rb +1 -1
- data/spec/unit/mutant/subject_spec.rb +3 -3
- data/spec/unit/mutant/util/one_spec.rb +20 -0
- data/spec/unit/mutant/zombifier_spec.rb +18 -18
- data/test_app/{Gemfile.rspec3.3 → Gemfile.rspec3.5} +2 -2
- metadata +94 -24
- data/TODO +0 -21
- data/lib/mutant/mutator/node/blockarg.rb +0 -13
- data/lib/mutant/mutator/node/restarg.rb +0 -13
- data/lib/mutant/mutator/registry.rb +0 -49
- data/meta/boolean.rb +0 -13
- data/meta/regex.rb +0 -19
- data/spec/unit/mutant/isolation_spec.rb +0 -104
- data/spec/unit/mutant/mutator/registry_spec.rb +0 -57
data/meta/str.rb
CHANGED
data/meta/super.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
Mutant::Meta::Example.add do
|
1
|
+
Mutant::Meta::Example.add :super do
|
2
2
|
source 'super'
|
3
3
|
|
4
4
|
singleton_mutations
|
5
5
|
mutation 'super()'
|
6
6
|
end
|
7
7
|
|
8
|
-
Mutant::Meta::Example.add do
|
8
|
+
Mutant::Meta::Example.add :super do
|
9
9
|
source 'super()'
|
10
10
|
|
11
11
|
singleton_mutations
|
12
12
|
end
|
13
13
|
|
14
|
-
Mutant::Meta::Example.add do
|
14
|
+
Mutant::Meta::Example.add :super do
|
15
15
|
source 'super(foo, bar)'
|
16
16
|
|
17
17
|
singleton_mutations
|
data/meta/{symbol.rb → sym.rb}
RENAMED
data/meta/true.rb
CHANGED
data/meta/until.rb
CHANGED
data/meta/while.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Mutant::Meta::Example.add do
|
1
|
+
Mutant::Meta::Example.add :while do
|
2
2
|
source 'while true; foo; bar; end'
|
3
3
|
|
4
4
|
singleton_mutations
|
@@ -14,7 +14,7 @@ Mutant::Meta::Example.add do
|
|
14
14
|
mutation 'while true; raise; end'
|
15
15
|
end
|
16
16
|
|
17
|
-
Mutant::Meta::Example.add do
|
17
|
+
Mutant::Meta::Example.add :while do
|
18
18
|
source 'while true; end'
|
19
19
|
|
20
20
|
singleton_mutations
|
data/meta/yield.rb
CHANGED
data/mutant-rspec.gemspec
CHANGED
@@ -13,10 +13,10 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.require_paths = %w[lib]
|
14
14
|
gem.files = `git ls-files -- lib/mutant/integration/rspec.rb`.split("\n")
|
15
15
|
gem.test_files = `git ls-files -- spec/{integration,unit}/mutant/rspec_spec.rb}`.split("\n")
|
16
|
-
gem.extra_rdoc_files = %w[
|
16
|
+
gem.extra_rdoc_files = %w[LICENSE]
|
17
17
|
|
18
18
|
gem.add_runtime_dependency('mutant', "~> #{gem.version}")
|
19
|
-
gem.add_runtime_dependency('rspec-core', '>= 3.
|
19
|
+
gem.add_runtime_dependency('rspec-core', '>= 3.4.0', '< 3.6.0')
|
20
20
|
|
21
21
|
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
22
22
|
end
|
data/mutant.gemspec
CHANGED
@@ -10,18 +10,18 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.homepage = 'https://github.com/mbj/mutant'
|
11
11
|
gem.license = 'MIT'
|
12
12
|
|
13
|
-
gem.require_paths
|
13
|
+
gem.require_paths = %w[lib]
|
14
14
|
|
15
|
-
mutant_integration_files
|
15
|
+
mutant_integration_files = `git ls-files -- lib/mutant/integration/*.rb`.split("\n")
|
16
16
|
|
17
17
|
gem.files = `git ls-files`.split("\n") - mutant_integration_files
|
18
18
|
gem.test_files = `git ls-files -- spec/{unit,integration}`.split("\n")
|
19
|
-
gem.extra_rdoc_files = %w[
|
19
|
+
gem.extra_rdoc_files = %w[LICENSE]
|
20
20
|
gem.executables = %w[mutant]
|
21
21
|
|
22
22
|
gem.required_ruby_version = '>= 2.1'
|
23
23
|
|
24
|
-
gem.add_runtime_dependency('parser', '~> 2.3.0')
|
24
|
+
gem.add_runtime_dependency('parser', '~> 2.3.0', '>= 2.3.0.2')
|
25
25
|
gem.add_runtime_dependency('ast', '~> 2.2')
|
26
26
|
gem.add_runtime_dependency('diff-lcs', '~> 1.2')
|
27
27
|
gem.add_runtime_dependency('parallel', '~> 1.3')
|
@@ -35,8 +35,9 @@ Gem::Specification.new do |gem|
|
|
35
35
|
gem.add_runtime_dependency('equalizer', '~> 0.0.9')
|
36
36
|
gem.add_runtime_dependency('anima', '~> 0.3.0')
|
37
37
|
gem.add_runtime_dependency('concord', '~> 0.1.5')
|
38
|
+
gem.add_runtime_dependency('regexp_parser', '~> 0.3.6')
|
38
39
|
|
39
|
-
gem.add_development_dependency('devtools', '~> 0.1.
|
40
|
+
gem.add_development_dependency('devtools', '~> 0.1.4')
|
40
41
|
gem.add_development_dependency('bundler', '~> 1.10')
|
41
42
|
gem.add_development_dependency('ffi', '~> 1.9.6')
|
42
43
|
end
|
@@ -2,7 +2,7 @@ RSpec.describe 'rspec integration', mutant: false do
|
|
2
2
|
|
3
3
|
let(:base_cmd) { 'bundle exec mutant -I lib --require test_app --use rspec' }
|
4
4
|
|
5
|
-
%w[3.
|
5
|
+
%w[3.4 3.5].each do |version|
|
6
6
|
context "RSpec #{version}" do
|
7
7
|
let(:gemfile) { "Gemfile.rspec#{version}" }
|
8
8
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
RSpec.describe 'AST type coverage', mutant: false do
|
2
|
-
|
3
2
|
specify 'mutant should not crash for any node parser can generate' do
|
4
3
|
Mutant::AST::Types::ALL.each do |type|
|
5
|
-
Mutant::Mutator::REGISTRY.lookup(
|
4
|
+
Mutant::Mutator::REGISTRY.lookup(type)
|
6
5
|
end
|
7
6
|
end
|
8
7
|
end
|
data/spec/integrations.yml
CHANGED
@@ -4,37 +4,106 @@
|
|
4
4
|
repo_uri: 'https://github.com/ruby/rubyspec.git'
|
5
5
|
mutation_coverage: false
|
6
6
|
mutation_generation: true
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
7
|
+
expected_errors:
|
8
|
+
"#<Parser::SyntaxError: invalid multibyte escape: /\xAA/>":
|
9
|
+
- language/regexp/escapes_spec.rb
|
10
|
+
"#<Parser::SyntaxError: literal contains escape sequences incompatible with UTF-8>":
|
11
|
+
- core/array/fixtures/encoded_strings.rb
|
12
|
+
- core/array/pack/shared/string.rb
|
13
|
+
- core/array/pack/shared/unicode.rb
|
14
|
+
- core/encoding/converter/convert_spec.rb
|
15
|
+
- core/encoding/converter/last_error_spec.rb
|
16
|
+
- core/encoding/converter/primitive_convert_spec.rb
|
17
|
+
- core/encoding/converter/primitive_errinfo_spec.rb
|
18
|
+
- core/encoding/converter/putback_spec.rb
|
19
|
+
- core/encoding/fixtures/classes.rb
|
20
|
+
- core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb
|
21
|
+
- core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb
|
22
|
+
- core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb
|
23
|
+
- core/encoding/replicate_spec.rb
|
24
|
+
- core/file/expand_path_spec.rb
|
25
|
+
- core/io/gets_spec.rb
|
26
|
+
- core/io/read_spec.rb
|
27
|
+
- core/io/shared/gets_ascii.rb
|
28
|
+
- core/io/write_spec.rb
|
29
|
+
- core/marshal/dump_spec.rb
|
30
|
+
- core/marshal/fixtures/marshal_data.rb
|
31
|
+
- core/marshal/shared/load.rb
|
32
|
+
- core/random/bytes_spec.rb
|
33
|
+
- core/regexp/match_spec.rb
|
34
|
+
- core/regexp/shared/new_ascii.rb
|
35
|
+
- core/string/byteslice_spec.rb
|
36
|
+
- core/string/codepoints_spec.rb
|
37
|
+
- core/string/comparison_spec.rb
|
38
|
+
- core/string/count_spec.rb
|
39
|
+
- core/string/delete_spec.rb
|
40
|
+
- core/string/element_set_spec.rb
|
41
|
+
- core/string/encode_spec.rb
|
42
|
+
- core/string/encoding_spec.rb
|
43
|
+
- core/string/fixtures/iso-8859-9-encoding.rb
|
44
|
+
- core/string/getbyte_spec.rb
|
45
|
+
- core/string/gsub_spec.rb
|
46
|
+
- core/string/new_spec.rb
|
47
|
+
- core/string/scrub_spec.rb
|
48
|
+
- core/string/shared/chars.rb
|
49
|
+
- core/string/shared/codepoints.rb
|
50
|
+
- core/string/shared/each_codepoint_without_block.rb
|
51
|
+
- core/string/shared/encode.rb
|
52
|
+
- core/string/shared/eql.rb
|
53
|
+
- core/string/shared/succ.rb
|
54
|
+
- core/string/slice_spec.rb
|
55
|
+
- core/string/squeeze_spec.rb
|
56
|
+
- core/string/unicode_normalize_spec.rb
|
57
|
+
- core/string/valid_encoding_spec.rb
|
58
|
+
- core/symbol/casecmp_spec.rb
|
59
|
+
- core/time/_dump_spec.rb
|
60
|
+
- core/time/_load_spec.rb
|
61
|
+
- language/regexp/encoding_spec.rb
|
62
|
+
- language/string_spec.rb
|
63
|
+
- library/digest/md5/shared/constants.rb
|
64
|
+
- library/digest/md5/shared/sample.rb
|
65
|
+
- library/digest/sha1/shared/constants.rb
|
66
|
+
- library/digest/sha256/shared/constants.rb
|
67
|
+
- library/digest/sha384/shared/constants.rb
|
68
|
+
- library/digest/sha512/shared/constants.rb
|
69
|
+
- library/openssl/shared/constants.rb
|
70
|
+
- library/socket/basicsocket/recv_spec.rb
|
71
|
+
- library/socket/socket/gethostbyname_spec.rb
|
72
|
+
- library/stringscanner/getch_spec.rb
|
73
|
+
- library/stringscanner/shared/get_byte.rb
|
74
|
+
- library/zlib/deflate/deflate_spec.rb
|
75
|
+
- library/zlib/deflate/set_dictionary_spec.rb
|
76
|
+
- library/zlib/gzipreader/each_byte_spec.rb
|
77
|
+
- library/zlib/gzipreader/eof_spec.rb
|
78
|
+
- library/zlib/gzipreader/getc_spec.rb
|
79
|
+
- library/zlib/gzipreader/pos_spec.rb
|
80
|
+
- library/zlib/gzipreader/read_spec.rb
|
81
|
+
- library/zlib/gzipreader/rewind_spec.rb
|
82
|
+
- library/zlib/inflate/append_spec.rb
|
83
|
+
- library/zlib/inflate/inflate_spec.rb
|
84
|
+
- library/zlib/inflate/set_dictionary_spec.rb
|
85
|
+
- library/zlib/zstream/flush_next_out_spec.rb
|
86
|
+
- optional/capi/encoding_spec.rb
|
87
|
+
- optional/capi/string_spec.rb
|
88
|
+
'#<RegexpError: invalid multibyte escape: /\xAA/>':
|
89
|
+
- language/regexp/escapes_spec.rb
|
90
|
+
"#<Regexp::Scanner::PrematureEndError: Premature end of pattern at #{str}>":
|
91
|
+
- language/regexp/interpolation_spec.rb
|
92
|
+
- name: regexp_parser
|
93
|
+
namespace: Regexp
|
94
|
+
repo_uri: 'https://github.com/ammar/regexp_parser.git'
|
95
|
+
mutation_coverage: false
|
96
|
+
mutation_generation: true
|
97
|
+
expected_errors: {}
|
27
98
|
- name: auom
|
28
99
|
namespace: AUOM
|
29
100
|
repo_uri: 'https://github.com/mbj/auom.git'
|
30
101
|
mutation_coverage: true
|
31
102
|
mutation_generation: true
|
32
|
-
|
33
|
-
expect_coverage: 1
|
103
|
+
expected_errors: {}
|
34
104
|
- name: axiom
|
35
105
|
namespace: Axiom
|
36
106
|
repo_uri: 'https://github.com/dkubb/axiom.git'
|
37
107
|
mutation_coverage: false
|
38
108
|
mutation_generation: true
|
39
|
-
|
40
|
-
expect_coverage: 1
|
109
|
+
expected_errors: {}
|
data/spec/spec_helper.rb
CHANGED
@@ -8,16 +8,16 @@ if ENV['COVERAGE'] == 'true'
|
|
8
8
|
add_filter 'spec'
|
9
9
|
add_filter 'vendor'
|
10
10
|
add_filter 'test_app'
|
11
|
-
add_filter 'lib/mutant
|
12
|
-
add_filter 'lib/mutant/zombifier'
|
13
|
-
add_filter 'lib/mutant/zombifier/*'
|
14
|
-
# Trace points shadow each other under 2.0 (fixed in 2.1)
|
15
|
-
add_filter 'lib/mutant/line_trace.rb' if RUBY_VERSION.eql?('2.0.0')
|
11
|
+
add_filter 'lib/mutant.rb' # simplecov bug not seeing default block is executed
|
16
12
|
|
17
13
|
minimum_coverage 100
|
18
14
|
end
|
19
15
|
end
|
20
16
|
|
17
|
+
# Require warning support first in order to catch any warnings emitted during boot
|
18
|
+
require_relative './support/warning'
|
19
|
+
$stderr = MutantSpec::Warning::EXTRACTOR
|
20
|
+
|
21
21
|
require 'tempfile'
|
22
22
|
require 'concord'
|
23
23
|
require 'anima'
|
@@ -48,13 +48,13 @@ module ParserHelper
|
|
48
48
|
def parse_expression(string)
|
49
49
|
Mutant::Config::DEFAULT.expression_parser.(string)
|
50
50
|
end
|
51
|
-
end
|
51
|
+
end # ParserHelper
|
52
52
|
|
53
53
|
module MessageHelper
|
54
54
|
def message(*arguments)
|
55
55
|
Mutant::Actor::Message.new(*arguments)
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end # MessageHelper
|
58
58
|
|
59
59
|
RSpec.configure do |config|
|
60
60
|
config.extend(SharedContext)
|
@@ -62,4 +62,9 @@ RSpec.configure do |config|
|
|
62
62
|
config.include(MessageHelper)
|
63
63
|
config.include(ParserHelper)
|
64
64
|
config.include(Mutant::AST::Sexp)
|
65
|
+
|
66
|
+
config.after(:suite) do
|
67
|
+
$stderr = STDERR
|
68
|
+
MutantSpec::Warning.assert_no_warnings
|
69
|
+
end
|
65
70
|
end
|
data/spec/support/corpus.rb
CHANGED
@@ -24,9 +24,15 @@ module MutantSpec
|
|
24
24
|
# rubocop:disable ClassLength
|
25
25
|
class Project
|
26
26
|
MUTEX = Mutex.new
|
27
|
+
|
28
|
+
MUTATION_GENERATION_MESSAGE = 'Total Mutations/Time/Parse-Errors: %s/%0.2fs - %0.2f/s'.freeze
|
29
|
+
START_MESSAGE = 'Starting - %s'.freeze
|
30
|
+
FINISH_MESSAGE = 'Mutations - %4i - %s'.freeze
|
31
|
+
|
32
|
+
DEFAULT_MUTATION_COUNT = 0
|
33
|
+
|
27
34
|
include Adamantium, Anima.new(
|
28
|
-
:
|
29
|
-
:expect_coverage,
|
35
|
+
:expected_errors,
|
30
36
|
:mutation_coverage,
|
31
37
|
:mutation_generation,
|
32
38
|
:name,
|
@@ -51,7 +57,6 @@ module MutantSpec
|
|
51
57
|
--use rspec
|
52
58
|
--include lib
|
53
59
|
--require #{name}
|
54
|
-
--expected-coverage #{expect_coverage}
|
55
60
|
#{namespace}*
|
56
61
|
]
|
57
62
|
)
|
@@ -75,28 +80,12 @@ module MutantSpec
|
|
75
80
|
start: method(:start),
|
76
81
|
in_processes: parallel_processes
|
77
82
|
}
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
Parser::CurrentRuby.parse(path.read)
|
83
|
-
rescue EncodingError, ArgumentError
|
84
|
-
nil # Make rubocop happy
|
85
|
-
end
|
86
|
-
if node
|
87
|
-
Mutant::Mutator::Node.each(node) do
|
88
|
-
count += 1
|
89
|
-
end
|
90
|
-
end
|
91
|
-
count
|
92
|
-
end.inject(0, :+)
|
83
|
+
|
84
|
+
total = Parallel.map(effective_ruby_paths, options, &method(:count_mutations_and_check_errors))
|
85
|
+
.inject(DEFAULT_MUTATION_COUNT, :+)
|
86
|
+
|
93
87
|
took = Time.now - start
|
94
|
-
puts
|
95
|
-
'Total Mutations/Time/Parse-Errors: %s/%0.2fs - %0.2f/s',
|
96
|
-
total,
|
97
|
-
took,
|
98
|
-
total / took
|
99
|
-
)
|
88
|
+
puts MUTATION_GENERATION_MESSAGE % [total, took, total / took]
|
100
89
|
self
|
101
90
|
end
|
102
91
|
|
@@ -124,6 +113,40 @@ module MutantSpec
|
|
124
113
|
|
125
114
|
private
|
126
115
|
|
116
|
+
# Count mutations and check error results against whitelist
|
117
|
+
#
|
118
|
+
# @param path [Pathname] path responsible for exception
|
119
|
+
#
|
120
|
+
# @return [Fixnum] mutations generated
|
121
|
+
def count_mutations_and_check_errors(path)
|
122
|
+
relative_path = path.relative_path_from(repo_path)
|
123
|
+
|
124
|
+
count = count_mutations(path)
|
125
|
+
|
126
|
+
expected_errors.assert_success(relative_path)
|
127
|
+
|
128
|
+
count
|
129
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
130
|
+
expected_errors.assert_error(relative_path, exception)
|
131
|
+
|
132
|
+
DEFAULT_MUTATION_COUNT
|
133
|
+
end
|
134
|
+
|
135
|
+
# Count mutations generated for provided source file
|
136
|
+
#
|
137
|
+
# @param path [Pathname] path to a source file
|
138
|
+
#
|
139
|
+
# @raise [Exception] any error specified by integrations.yml
|
140
|
+
#
|
141
|
+
# @return [Fixnum] number of mutations generated
|
142
|
+
def count_mutations(path)
|
143
|
+
node = Parser::CurrentRuby.parse(path.read)
|
144
|
+
|
145
|
+
return DEFAULT_MUTATION_COUNT unless node
|
146
|
+
|
147
|
+
Mutant::Mutator.mutate(node).length
|
148
|
+
end
|
149
|
+
|
127
150
|
# Install mutant
|
128
151
|
#
|
129
152
|
# @return [undefined]
|
@@ -144,19 +167,10 @@ module MutantSpec
|
|
144
167
|
#
|
145
168
|
# @return [Array<Pathname>]
|
146
169
|
def effective_ruby_paths
|
147
|
-
|
170
|
+
Pathname
|
148
171
|
.glob(repo_path.join(RUBY_GLOB_PATTERN))
|
149
172
|
.sort_by(&:size)
|
150
173
|
.reverse
|
151
|
-
|
152
|
-
paths - excluded_paths
|
153
|
-
end
|
154
|
-
|
155
|
-
# The excluded file paths
|
156
|
-
#
|
157
|
-
# @return [Array<Pathname>]
|
158
|
-
def excluded_paths
|
159
|
-
Pathname.glob(repo_path.join(EXCLUDE_GLOB_FORMAT % exclude.join(',')))
|
160
174
|
end
|
161
175
|
|
162
176
|
# Number of parallel processes to use
|
@@ -193,7 +207,7 @@ module MutantSpec
|
|
193
207
|
#
|
194
208
|
def start(path, _index)
|
195
209
|
MUTEX.synchronize do
|
196
|
-
puts
|
210
|
+
puts START_MESSAGE % path
|
197
211
|
end
|
198
212
|
end
|
199
213
|
|
@@ -207,15 +221,18 @@ module MutantSpec
|
|
207
221
|
#
|
208
222
|
def finish(path, _index, count)
|
209
223
|
MUTEX.synchronize do
|
210
|
-
puts
|
224
|
+
puts FINISH_MESSAGE % [count, path]
|
211
225
|
end
|
212
226
|
end
|
213
227
|
|
214
228
|
# Helper method to execute system commands
|
215
229
|
#
|
216
230
|
# @param [Array<String>] arguments
|
231
|
+
#
|
232
|
+
# rubocop:disable GuardClause - guard clause without else does not make sense
|
217
233
|
def system(arguments)
|
218
234
|
return if Kernel.system(*arguments)
|
235
|
+
|
219
236
|
if block_given?
|
220
237
|
yield
|
221
238
|
else
|
@@ -223,7 +240,58 @@ module MutantSpec
|
|
223
240
|
end
|
224
241
|
end
|
225
242
|
|
226
|
-
#
|
243
|
+
# Mapping of files which we expect to cause errors during mutation generation
|
244
|
+
class ErrorWhitelist
|
245
|
+
class UnnecessaryExpectation < StandardError
|
246
|
+
MESSAGE = 'Expected to encounter %s while mutating "%s"'.freeze
|
247
|
+
|
248
|
+
def initialize(*error_info)
|
249
|
+
super(MESSAGE % error_info)
|
250
|
+
end
|
251
|
+
end # UnnecessaryExpectation
|
252
|
+
|
253
|
+
include Concord.new(:map), Adamantium
|
254
|
+
|
255
|
+
# Assert that we expect to encounter the provided exception for this path
|
256
|
+
#
|
257
|
+
# @param path [Pathname]
|
258
|
+
# @param exception [Exception]
|
259
|
+
#
|
260
|
+
# @raise provided exception if we are not expecting this error
|
261
|
+
#
|
262
|
+
# This method is reraising exceptions but rubocop can't tell
|
263
|
+
# rubocop:disable Style/SignalException
|
264
|
+
#
|
265
|
+
# @return [undefined]
|
266
|
+
def assert_error(path, exception)
|
267
|
+
original_error = exception.cause || exception
|
268
|
+
|
269
|
+
raise exception unless map.fetch(original_error.inspect, []).include?(path)
|
270
|
+
end
|
271
|
+
|
272
|
+
# Assert that we expect to not encounter an error for the specified path
|
273
|
+
#
|
274
|
+
# @param path [Pathname]
|
275
|
+
#
|
276
|
+
# @raise [UnnecessaryExpectation] if we are expecting an exception for this path
|
277
|
+
#
|
278
|
+
# @return [undefined]
|
279
|
+
def assert_success(path)
|
280
|
+
map.each do |error, paths|
|
281
|
+
fail UnnecessaryExpectation.new(error, path) if paths.include?(path)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Return representation as hash
|
286
|
+
#
|
287
|
+
# @note this method is necessary for morpher loader to be invertible
|
288
|
+
#
|
289
|
+
# @return [Hash{Pathname => String}]
|
290
|
+
def to_h
|
291
|
+
map
|
292
|
+
end
|
293
|
+
end # ErrorWhitelist
|
294
|
+
|
227
295
|
LOADER = Morpher.build do
|
228
296
|
s(:block,
|
229
297
|
s(:guard, s(:primitive, Array)),
|
@@ -234,23 +302,20 @@ module MutantSpec
|
|
234
302
|
s(:key_symbolize, :repo_uri, s(:guard, s(:primitive, String))),
|
235
303
|
s(:key_symbolize, :name, s(:guard, s(:primitive, String))),
|
236
304
|
s(:key_symbolize, :namespace, s(:guard, s(:primitive, String))),
|
237
|
-
s(:key_symbolize, :expect_coverage, s(:guard, s(:primitive, Fixnum))),
|
238
305
|
s(:key_symbolize, :mutation_coverage,
|
239
306
|
s(:guard, s(:or, s(:primitive, TrueClass), s(:primitive, FalseClass)))),
|
240
307
|
s(:key_symbolize, :mutation_generation,
|
241
308
|
s(:guard, s(:or, s(:primitive, TrueClass), s(:primitive, FalseClass)))),
|
242
|
-
s(:key_symbolize, :
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
)
|
253
|
-
)
|
309
|
+
s(:key_symbolize, :expected_errors,
|
310
|
+
s(:block,
|
311
|
+
s(:guard, s(:primitive, Hash)),
|
312
|
+
s(:custom,
|
313
|
+
[
|
314
|
+
->(hash) { hash.map { |key, values| [key, values.map(&Pathname.method(:new))] }.to_h },
|
315
|
+
->(hash) { hash.map { |key, values| [key, values.map(&:to_s)] }.to_h }
|
316
|
+
]),
|
317
|
+
s(:load_attribute_hash, s(:param, ErrorWhitelist))))),
|
318
|
+
s(:anima_load, Project))))
|
254
319
|
end
|
255
320
|
|
256
321
|
ALL = LOADER.call(YAML.load_file(ROOT.join('spec', 'integrations.yml')))
|