mutant 0.8.10 → 0.8.11
Sign up to get free protection for your applications and to get access to all the features.
- 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')))
|