mutant 0.8.0 → 0.8.1
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/Changelog.md +7 -0
- data/config/flay.yml +1 -1
- data/config/reek.yml +1 -0
- data/lib/mutant.rb +10 -3
- data/lib/mutant/actor.rb +2 -5
- data/lib/mutant/actor/env.rb +1 -3
- data/lib/mutant/actor/mailbox.rb +2 -4
- data/lib/mutant/actor/receiver.rb +0 -2
- data/lib/mutant/actor/sender.rb +0 -1
- data/lib/mutant/ast.rb +22 -28
- data/lib/mutant/ast/meta.rb +8 -88
- data/lib/mutant/ast/named_children.rb +1 -8
- data/lib/mutant/ast/sexp.rb +0 -2
- data/lib/mutant/cache.rb +1 -3
- data/lib/mutant/cli.rb +9 -19
- data/lib/mutant/color.rb +0 -3
- data/lib/mutant/config.rb +6 -2
- data/lib/mutant/context.rb +2 -4
- data/lib/mutant/context/scope.rb +10 -16
- data/lib/mutant/delegator.rb +0 -3
- data/lib/mutant/diff.rb +8 -17
- data/lib/mutant/env.rb +3 -5
- data/lib/mutant/env/bootstrap.rb +32 -39
- data/lib/mutant/expression.rb +14 -132
- data/lib/mutant/expression/method.rb +25 -42
- data/lib/mutant/expression/methods.rb +17 -29
- data/lib/mutant/expression/namespace.rb +33 -28
- data/lib/mutant/expression/parser.rb +71 -0
- data/lib/mutant/integration.rb +17 -16
- data/lib/mutant/isolation.rb +14 -14
- data/lib/mutant/loader.rb +2 -4
- data/lib/mutant/matcher.rb +1 -11
- data/lib/mutant/matcher/chain.rb +0 -1
- data/lib/mutant/matcher/compiler.rb +19 -52
- data/lib/mutant/matcher/config.rb +65 -5
- data/lib/mutant/matcher/filter.rb +11 -1
- data/lib/mutant/matcher/method.rb +11 -21
- data/lib/mutant/matcher/method/instance.rb +2 -16
- data/lib/mutant/matcher/method/singleton.rb +3 -20
- data/lib/mutant/matcher/methods.rb +11 -21
- data/lib/mutant/matcher/namespace.rb +0 -4
- data/lib/mutant/matcher/null.rb +0 -1
- data/lib/mutant/matcher/scope.rb +0 -12
- data/lib/mutant/meta.rb +0 -1
- data/lib/mutant/meta/example.rb +12 -26
- data/lib/mutant/meta/example/dsl.rb +1 -8
- data/lib/mutant/mutation.rb +6 -14
- data/lib/mutant/mutator.rb +2 -14
- data/lib/mutant/mutator/node.rb +6 -33
- data/lib/mutant/mutator/node/and_asgn.rb +0 -1
- data/lib/mutant/mutator/node/argument.rb +0 -5
- data/lib/mutant/mutator/node/arguments.rb +1 -7
- data/lib/mutant/mutator/node/begin.rb +0 -2
- data/lib/mutant/mutator/node/binary.rb +0 -3
- data/lib/mutant/mutator/node/block.rb +0 -2
- data/lib/mutant/mutator/node/break.rb +0 -1
- data/lib/mutant/mutator/node/case.rb +0 -3
- data/lib/mutant/mutator/node/conditional_loop.rb +0 -1
- data/lib/mutant/mutator/node/const.rb +0 -1
- data/lib/mutant/mutator/node/define.rb +0 -1
- data/lib/mutant/mutator/node/defined.rb +0 -1
- data/lib/mutant/mutator/node/dstr.rb +0 -1
- data/lib/mutant/mutator/node/dsym.rb +0 -1
- data/lib/mutant/mutator/node/generic.rb +0 -1
- data/lib/mutant/mutator/node/if.rb +0 -4
- data/lib/mutant/mutator/node/kwbegin.rb +0 -1
- data/lib/mutant/mutator/node/literal/array.rb +0 -2
- data/lib/mutant/mutator/node/literal/boolean.rb +0 -1
- data/lib/mutant/mutator/node/literal/fixnum.rb +2 -5
- data/lib/mutant/mutator/node/literal/float.rb +1 -4
- data/lib/mutant/mutator/node/literal/hash.rb +0 -3
- data/lib/mutant/mutator/node/literal/nil.rb +0 -1
- data/lib/mutant/mutator/node/literal/range.rb +1 -5
- data/lib/mutant/mutator/node/literal/regex.rb +1 -3
- data/lib/mutant/mutator/node/literal/string.rb +0 -1
- data/lib/mutant/mutator/node/literal/symbol.rb +0 -1
- data/lib/mutant/mutator/node/masgn.rb +0 -1
- data/lib/mutant/mutator/node/match_current_line.rb +0 -1
- data/lib/mutant/mutator/node/mlhs.rb +0 -1
- data/lib/mutant/mutator/node/named_value/access.rb +0 -1
- data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -2
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -2
- data/lib/mutant/mutator/node/next.rb +0 -1
- data/lib/mutant/mutator/node/noop.rb +0 -1
- data/lib/mutant/mutator/node/nthref.rb +0 -1
- data/lib/mutant/mutator/node/op_asgn.rb +0 -1
- data/lib/mutant/mutator/node/or_asgn.rb +1 -2
- data/lib/mutant/mutator/node/resbody.rb +0 -2
- data/lib/mutant/mutator/node/rescue.rb +1 -6
- data/lib/mutant/mutator/node/return.rb +0 -1
- data/lib/mutant/mutator/node/send.rb +16 -17
- data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -3
- data/lib/mutant/mutator/node/send/binary.rb +0 -1
- data/lib/mutant/mutator/node/send/index.rb +0 -3
- data/lib/mutant/mutator/node/splat.rb +0 -1
- data/lib/mutant/mutator/node/super.rb +0 -1
- data/lib/mutant/mutator/node/when.rb +2 -7
- data/lib/mutant/mutator/node/yield.rb +0 -1
- data/lib/mutant/mutator/node/zsuper.rb +0 -1
- data/lib/mutant/mutator/registry.rb +1 -4
- data/lib/mutant/mutator/util.rb +0 -2
- data/lib/mutant/mutator/util/array.rb +0 -3
- data/lib/mutant/mutator/util/symbol.rb +0 -1
- data/lib/mutant/parallel.rb +3 -9
- data/lib/mutant/parallel/master.rb +7 -17
- data/lib/mutant/parallel/source.rb +2 -7
- data/lib/mutant/parallel/worker.rb +1 -5
- data/lib/mutant/reporter.rb +0 -4
- data/lib/mutant/reporter/cli.rb +1 -8
- data/lib/mutant/reporter/cli/format.rb +7 -18
- data/lib/mutant/reporter/cli/printer.rb +2 -12
- data/lib/mutant/reporter/cli/printer/config.rb +1 -4
- data/lib/mutant/reporter/cli/printer/env_progress.rb +3 -7
- data/lib/mutant/reporter/cli/printer/env_result.rb +0 -1
- data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -2
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +3 -11
- data/lib/mutant/reporter/cli/printer/status.rb +1 -4
- data/lib/mutant/reporter/cli/printer/status_progressive.rb +1 -3
- data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -5
- data/lib/mutant/reporter/cli/printer/subject_result.rb +0 -1
- data/lib/mutant/reporter/cli/printer/test_result.rb +0 -1
- data/lib/mutant/reporter/cli/tput.rb +4 -1
- data/lib/mutant/reporter/trace.rb +2 -4
- data/lib/mutant/repository.rb +88 -0
- data/lib/mutant/require_highjack.rb +0 -1
- data/lib/mutant/result.rb +25 -48
- data/lib/mutant/runner.rb +7 -16
- data/lib/mutant/runner/sink.rb +3 -11
- data/lib/mutant/selector.rb +1 -2
- data/lib/mutant/selector/expression.rb +1 -2
- data/lib/mutant/subject.rb +10 -21
- data/lib/mutant/subject/method.rb +11 -12
- data/lib/mutant/subject/method/instance.rb +1 -5
- data/lib/mutant/subject/method/singleton.rb +1 -3
- data/lib/mutant/test.rb +1 -2
- data/lib/mutant/version.rb +2 -2
- data/lib/mutant/warning_filter.rb +2 -7
- data/lib/mutant/zombifier.rb +6 -10
- data/meta/send.rb +8 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/support/corpus.rb +5 -9
- data/spec/support/rb_bug.rb +0 -1
- data/spec/support/rspec.rb +0 -1
- data/spec/support/ruby_vm.rb +0 -2
- data/spec/unit/mutant/ast/meta/send_spec.rb +42 -0
- data/spec/unit/mutant/ast/named_children_spec.rb +51 -0
- data/spec/unit/mutant/ast/sexp_spec.rb +36 -0
- data/spec/unit/mutant/ast_spec.rb +8 -0
- data/spec/unit/mutant/cli_spec.rb +34 -19
- data/spec/unit/mutant/context/scope_spec.rb +11 -0
- data/spec/unit/mutant/env/boostrap_spec.rb +5 -2
- data/spec/unit/mutant/env_spec.rb +14 -15
- data/spec/unit/mutant/expression/method_spec.rb +10 -14
- data/spec/unit/mutant/expression/methods_spec.rb +24 -11
- data/spec/unit/mutant/expression/namespace/flat_spec.rb +5 -6
- data/spec/unit/mutant/expression/namespace/recursive_spec.rb +16 -10
- data/spec/unit/mutant/expression/parser_spec.rb +67 -0
- data/spec/unit/mutant/expression_spec.rb +24 -57
- data/spec/unit/mutant/integration/rspec_spec.rb +7 -7
- data/spec/unit/mutant/integration_spec.rb +2 -2
- data/spec/unit/mutant/isolation_spec.rb +31 -29
- data/spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb +2 -2
- data/spec/unit/mutant/matcher/compiler_spec.rb +27 -58
- data/spec/unit/mutant/matcher/config_spec.rb +45 -0
- data/spec/unit/mutant/matcher/filter_spec.rb +12 -5
- data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -1
- data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -1
- data/spec/unit/mutant/matcher/namespace_spec.rb +4 -4
- data/spec/unit/mutant/parallel/worker_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +4 -4
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +7 -7
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +2 -2
- data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +12 -12
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +1 -1
- data/spec/unit/mutant/reporter/cli_spec.rb +9 -10
- data/spec/unit/mutant/repository/diff_spec.rb +80 -0
- data/spec/unit/mutant/repository/subject_filter_spec.rb +28 -0
- data/spec/unit/mutant/result/env_spec.rb +1 -1
- data/spec/unit/mutant/runner_spec.rb +0 -1
- data/spec/unit/mutant/selector/expression_spec.rb +14 -14
- data/spec/unit/mutant/subject/method/instance_spec.rb +2 -2
- data/spec/unit/mutant/subject/method/singleton_spec.rb +2 -2
- data/spec/unit/mutant/subject_spec.rb +5 -2
- metadata +20 -3
- data/spec/support/mutation_verifier.rb +0 -96
@@ -3,36 +3,45 @@ module Mutant
|
|
3
3
|
|
4
4
|
# Abstract base class for methods expression
|
5
5
|
class Methods < self
|
6
|
+
include Anima.new(:scope_name, :scope_symbol)
|
7
|
+
private(*anima.attribute_names)
|
6
8
|
|
7
9
|
MATCHERS = IceNine.deep_freeze(
|
8
10
|
'.' => Matcher::Methods::Singleton,
|
9
11
|
'#' => Matcher::Methods::Instance
|
10
12
|
)
|
13
|
+
private_constant(*constants(false))
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}\z/.freeze
|
16
|
+
|
17
|
+
# Syntax of expression
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
def syntax
|
23
|
+
[scope_name, scope_symbol].join
|
24
|
+
end
|
25
|
+
memoize :syntax
|
15
26
|
|
16
|
-
#
|
27
|
+
# Matcher on expression
|
17
28
|
#
|
18
29
|
# @param [Env] env
|
19
30
|
#
|
20
31
|
# @return [Matcher::Method]
|
21
32
|
#
|
22
33
|
# @api private
|
23
|
-
#
|
24
34
|
def matcher(env)
|
25
35
|
MATCHERS.fetch(scope_symbol).new(env, scope)
|
26
36
|
end
|
27
37
|
|
28
|
-
#
|
38
|
+
# Length of match with other expression
|
29
39
|
#
|
30
40
|
# @param [Expression] expression
|
31
41
|
#
|
32
42
|
# @return [Fixnum]
|
33
43
|
#
|
34
44
|
# @api private
|
35
|
-
#
|
36
45
|
def match_length(expression)
|
37
46
|
if expression.syntax.start_with?(syntax)
|
38
47
|
syntax.length
|
@@ -43,36 +52,15 @@ module Mutant
|
|
43
52
|
|
44
53
|
private
|
45
54
|
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# @return [String]
|
49
|
-
#
|
50
|
-
# @api private
|
51
|
-
#
|
52
|
-
def scope_name
|
53
|
-
match[__method__]
|
54
|
-
end
|
55
|
-
|
56
|
-
# Return scope
|
55
|
+
# Scope object
|
57
56
|
#
|
58
57
|
# @return [Class, Method]
|
59
58
|
#
|
60
59
|
# @api private
|
61
|
-
#
|
62
60
|
def scope
|
63
61
|
Object.const_get(scope_name)
|
64
62
|
end
|
65
63
|
|
66
|
-
# Return scope symbol
|
67
|
-
#
|
68
|
-
# @return [Symbol]
|
69
|
-
#
|
70
|
-
# @api private
|
71
|
-
#
|
72
|
-
def scope_symbol
|
73
|
-
match[__method__]
|
74
|
-
end
|
75
|
-
|
76
64
|
end # Method
|
77
65
|
end # Expression
|
78
66
|
end # Mutant
|
@@ -2,24 +2,12 @@ module Mutant
|
|
2
2
|
class Expression
|
3
3
|
# Abstract base class for expressions matching namespaces
|
4
4
|
class Namespace < self
|
5
|
-
include AbstractType
|
6
|
-
|
7
|
-
private
|
8
|
-
|
9
|
-
# Return matched namespace
|
10
|
-
#
|
11
|
-
# @return [String]
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
|
-
def namespace
|
16
|
-
match[__method__]
|
17
|
-
end
|
5
|
+
include AbstractType, Anima.new(:scope_name)
|
6
|
+
private(*anima.attribute_names)
|
18
7
|
|
19
8
|
# Recursive namespace expression
|
20
9
|
class Recursive < self
|
21
|
-
|
22
|
-
register(/\A(?<namespace>#{SCOPE_PATTERN})?\*\z/)
|
10
|
+
REGEXP = /\A#{SCOPE_NAME_PATTERN}?\*\z/.freeze
|
23
11
|
|
24
12
|
# Initialize object
|
25
13
|
#
|
@@ -29,35 +17,43 @@ module Mutant
|
|
29
17
|
def initialize(*)
|
30
18
|
super
|
31
19
|
@recursion_pattern = Regexp.union(
|
32
|
-
/\A#{
|
33
|
-
/\A#{
|
34
|
-
/\A#{
|
20
|
+
/\A#{scope_name}\z/,
|
21
|
+
/\A#{scope_name}::/,
|
22
|
+
/\A#{scope_name}[.#]/
|
35
23
|
)
|
36
24
|
end
|
37
25
|
|
38
|
-
#
|
26
|
+
# Syntax for expression
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def syntax
|
32
|
+
"#{scope_name}*"
|
33
|
+
end
|
34
|
+
memoize :syntax
|
35
|
+
|
36
|
+
# Matcher for expression
|
39
37
|
#
|
40
38
|
# @param [Env::Bootstrap] env
|
41
39
|
#
|
42
40
|
# @return [Matcher]
|
43
41
|
#
|
44
42
|
# @api private
|
45
|
-
#
|
46
43
|
def matcher(env)
|
47
44
|
Matcher::Namespace.new(env, self)
|
48
45
|
end
|
49
46
|
|
50
|
-
#
|
47
|
+
# Length of match with other expression
|
51
48
|
#
|
52
49
|
# @param [Expression] expression
|
53
50
|
#
|
54
51
|
# @return [Fixnum]
|
55
52
|
#
|
56
53
|
# @api private
|
57
|
-
#
|
58
54
|
def match_length(expression)
|
59
55
|
if @recursion_pattern =~ expression.syntax
|
60
|
-
|
56
|
+
scope_name.length
|
61
57
|
else
|
62
58
|
0
|
63
59
|
end
|
@@ -68,22 +64,31 @@ module Mutant
|
|
68
64
|
# Exact namespace expression
|
69
65
|
class Exact < self
|
70
66
|
|
71
|
-
register(/\A(?<namespace>#{SCOPE_PATTERN})\z/)
|
72
|
-
|
73
67
|
MATCHER = Matcher::Scope
|
68
|
+
private_constant(*constants(false))
|
69
|
+
|
70
|
+
REGEXP = /\A#{SCOPE_NAME_PATTERN}\z/.freeze
|
74
71
|
|
75
|
-
#
|
72
|
+
# Matcher matcher on expression
|
76
73
|
#
|
77
74
|
# @param [Env::Bootstrap] env
|
78
75
|
#
|
79
76
|
# @return [Matcher]
|
80
77
|
#
|
81
78
|
# @api private
|
82
|
-
#
|
83
79
|
def matcher(env)
|
84
|
-
Matcher::Scope.new(env, Object.const_get(
|
80
|
+
Matcher::Scope.new(env, Object.const_get(scope_name), self)
|
85
81
|
end
|
86
82
|
|
83
|
+
# Syntax for expression
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
alias_method :syntax, :scope_name
|
90
|
+
public :syntax
|
91
|
+
|
87
92
|
end # Exact
|
88
93
|
end # Namespace
|
89
94
|
end # Namespace
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Mutant
|
2
|
+
class Expression
|
3
|
+
class Parser
|
4
|
+
include Concord.new(:types)
|
5
|
+
|
6
|
+
class ParserError < RuntimeError
|
7
|
+
include AbstractType
|
8
|
+
end
|
9
|
+
|
10
|
+
# Error raised on invalid expressions
|
11
|
+
class InvalidExpressionError < ParserError; end
|
12
|
+
|
13
|
+
# Error raised on ambiguous expressions
|
14
|
+
class AmbiguousExpressionError < ParserError; end
|
15
|
+
|
16
|
+
# Parse input into expression or raise
|
17
|
+
#
|
18
|
+
# @param [String] syntax
|
19
|
+
#
|
20
|
+
# @return [Expression]
|
21
|
+
# if expression is valid
|
22
|
+
#
|
23
|
+
# @raise [ParserError]
|
24
|
+
# otherwise
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def call(input)
|
28
|
+
try_parse(input) or fail InvalidExpressionError, "Expression: #{input.inspect} is not valid"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Try to parse input into expression
|
32
|
+
#
|
33
|
+
# @param [String] input
|
34
|
+
#
|
35
|
+
# @return [Expression]
|
36
|
+
# if expression is valid
|
37
|
+
#
|
38
|
+
# @return [nil]
|
39
|
+
# otherwise
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
def try_parse(input)
|
43
|
+
expressions = expressions(input)
|
44
|
+
case expressions.length
|
45
|
+
when 0, 1
|
46
|
+
expressions.first
|
47
|
+
else
|
48
|
+
fail AmbiguousExpressionError, "Ambiguous expression: #{input.inspect}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Expressions parsed from input
|
55
|
+
#
|
56
|
+
# @param [String] input
|
57
|
+
#
|
58
|
+
# @return [Array<Expression>]
|
59
|
+
# if expressions can be parsed from input
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
def expressions(input)
|
63
|
+
types.each_with_object([]) do |type, aggregate|
|
64
|
+
expression = type.try_parse(input)
|
65
|
+
aggregate << expression if expression
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end # Parser
|
70
|
+
end # Expression
|
71
|
+
end # Mutant
|
data/lib/mutant/integration.rb
CHANGED
@@ -2,7 +2,7 @@ module Mutant
|
|
2
2
|
|
3
3
|
# Abstract base class mutant test framework integrations
|
4
4
|
class Integration
|
5
|
-
include AbstractType, Adamantium::Flat,
|
5
|
+
include AbstractType, Adamantium::Flat, Concord.new(:config)
|
6
6
|
|
7
7
|
REGISTRY = {}
|
8
8
|
|
@@ -13,7 +13,6 @@ module Mutant
|
|
13
13
|
# @return [Integration]
|
14
14
|
#
|
15
15
|
# @api private
|
16
|
-
#
|
17
16
|
def self.setup(name)
|
18
17
|
require "mutant/integration/#{name}"
|
19
18
|
lookup(name)
|
@@ -27,9 +26,8 @@ module Mutant
|
|
27
26
|
# if found
|
28
27
|
#
|
29
28
|
# @api private
|
30
|
-
#
|
31
29
|
def self.lookup(name)
|
32
|
-
REGISTRY.fetch(name)
|
30
|
+
REGISTRY.fetch(name)
|
33
31
|
end
|
34
32
|
|
35
33
|
# Register integration
|
@@ -39,11 +37,8 @@ module Mutant
|
|
39
37
|
# @return [undefined]
|
40
38
|
#
|
41
39
|
# @api private
|
42
|
-
#
|
43
40
|
def self.register(name)
|
44
41
|
REGISTRY[name] = self
|
45
|
-
|
46
|
-
define_method(:name) { name }
|
47
42
|
end
|
48
43
|
private_class_method :register
|
49
44
|
|
@@ -52,52 +47,58 @@ module Mutant
|
|
52
47
|
# @return [self]
|
53
48
|
#
|
54
49
|
# @api private
|
55
|
-
#
|
56
50
|
def setup
|
57
51
|
self
|
58
52
|
end
|
59
53
|
|
60
|
-
#
|
54
|
+
# Run a collection of tests
|
61
55
|
#
|
62
56
|
# @param [Enumerable<Test>] tests
|
63
57
|
#
|
64
58
|
# @return [Result::Test]
|
65
59
|
#
|
66
60
|
# @api private
|
67
|
-
#
|
68
61
|
abstract_method :call
|
69
62
|
|
70
|
-
#
|
63
|
+
# Available tests for integration
|
71
64
|
#
|
72
65
|
# @return [Enumerable<Test>]
|
73
66
|
#
|
74
67
|
# @api private
|
75
|
-
#
|
76
68
|
abstract_method :all_tests
|
77
69
|
|
70
|
+
private
|
71
|
+
|
72
|
+
# Expression parser
|
73
|
+
#
|
74
|
+
# @return [Expression::Parser]
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
def expression_parser
|
78
|
+
config.expression_parser
|
79
|
+
end
|
80
|
+
|
78
81
|
# Null integration that never kills a mutation
|
79
82
|
class Null < self
|
80
83
|
|
81
84
|
register('null')
|
82
85
|
|
83
|
-
#
|
86
|
+
# Available tests for integration
|
84
87
|
#
|
85
88
|
# @return [Enumerable<Test>]
|
86
89
|
#
|
87
90
|
# @api private
|
88
|
-
#
|
89
91
|
def all_tests
|
90
92
|
EMPTY_ARRAY
|
91
93
|
end
|
92
94
|
|
93
|
-
#
|
95
|
+
# Run a collection of tests
|
94
96
|
#
|
95
97
|
# @param [Enumerable<Mutant::Test>] tests
|
96
98
|
#
|
97
99
|
# @return [Result::Test]
|
98
100
|
#
|
99
101
|
# @api private
|
100
|
-
#
|
101
102
|
def call(tests)
|
102
103
|
Result::Test.new(
|
103
104
|
tests: tests,
|
data/lib/mutant/isolation.rb
CHANGED
@@ -13,7 +13,6 @@ module Mutant
|
|
13
13
|
# if block terminates abnormal
|
14
14
|
#
|
15
15
|
# @api private
|
16
|
-
#
|
17
16
|
def self.call(&block)
|
18
17
|
block.call
|
19
18
|
rescue => exception
|
@@ -35,28 +34,29 @@ module Mutant
|
|
35
34
|
# @raise [Error]
|
36
35
|
# if block terminates abnormal
|
37
36
|
#
|
38
|
-
# @api private
|
39
|
-
#
|
40
37
|
# rubocop:disable MethodLength
|
41
38
|
#
|
39
|
+
# @api private
|
42
40
|
def self.call(&block)
|
43
|
-
|
41
|
+
IO.pipe(binmode: true) do |reader, writer|
|
42
|
+
begin
|
43
|
+
pid = Process.fork do
|
44
|
+
File.open(File::NULL, 'w') do |file|
|
45
|
+
$stderr.reopen(file)
|
46
|
+
reader.close
|
47
|
+
writer.write(Marshal.dump(block.call))
|
48
|
+
writer.close
|
49
|
+
end
|
50
|
+
end
|
44
51
|
|
45
|
-
pid = Process.fork do
|
46
|
-
File.open('/dev/null', 'w') do |file|
|
47
|
-
$stderr.reopen(file)
|
48
|
-
reader.close
|
49
|
-
writer.write(Marshal.dump(block.call))
|
50
52
|
writer.close
|
53
|
+
Marshal.load(reader.read)
|
54
|
+
ensure
|
55
|
+
Process.waitpid(pid) if pid
|
51
56
|
end
|
52
57
|
end
|
53
|
-
|
54
|
-
writer.close
|
55
|
-
Marshal.load(reader.read)
|
56
58
|
rescue => exception
|
57
59
|
raise Error, exception
|
58
|
-
ensure
|
59
|
-
Process.waitpid(pid) if pid
|
60
60
|
end
|
61
61
|
|
62
62
|
end # Fork
|
data/lib/mutant/loader.rb
CHANGED
@@ -10,12 +10,11 @@ module Mutant
|
|
10
10
|
#
|
11
11
|
# @return [undefined]
|
12
12
|
#
|
13
|
-
# @api private
|
14
|
-
#
|
15
13
|
# One off the very few valid uses of eval
|
16
14
|
#
|
17
15
|
# rubocop:disable Lint/Eval
|
18
16
|
#
|
17
|
+
# @api private
|
19
18
|
def call
|
20
19
|
eval(
|
21
20
|
source,
|
@@ -28,12 +27,11 @@ module Mutant
|
|
28
27
|
|
29
28
|
private
|
30
29
|
|
31
|
-
#
|
30
|
+
# Source generated from AST
|
32
31
|
#
|
33
32
|
# @return [String]
|
34
33
|
#
|
35
34
|
# @api private
|
36
|
-
#
|
37
35
|
def source
|
38
36
|
Unparser.unparse(root)
|
39
37
|
end
|