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