mutant 0.1.1 → 0.2.0
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.
- data/.gitignore +5 -11
- data/.rspec +0 -1
- data/.travis.yml +14 -3
- data/Changelog.md +3 -0
- data/Gemfile +5 -1
- data/Gemfile.devtools +49 -0
- data/Guardfile +18 -0
- data/README.md +67 -0
- data/Rakefile +4 -1
- data/TODO +13 -0
- data/bin/mutant +14 -0
- data/bin/zombie +14 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/roodi.yml +26 -0
- data/config/site.reek +93 -0
- data/config/yardstick.yml +2 -0
- data/lib/inflector.rb +7 -0
- data/lib/inflector/defaults.rb +62 -0
- data/lib/inflector/inflections.rb +209 -0
- data/lib/inflector/methods.rb +149 -0
- data/lib/inflector/version.rb +3 -0
- data/lib/mutant.rb +96 -21
- data/lib/mutant/cli.rb +309 -0
- data/lib/mutant/color.rb +61 -0
- data/lib/mutant/context.rb +36 -0
- data/lib/mutant/context/scope.rb +138 -0
- data/lib/mutant/differ.rb +100 -0
- data/lib/mutant/helper.rb +38 -0
- data/lib/mutant/killer.rb +136 -0
- data/lib/mutant/killer/forking.rb +41 -0
- data/lib/mutant/killer/rspec.rb +49 -0
- data/lib/mutant/killer/static.rb +19 -0
- data/lib/mutant/loader.rb +129 -0
- data/lib/mutant/matcher.rb +55 -0
- data/lib/mutant/matcher/chain.rb +66 -0
- data/lib/mutant/matcher/method.rb +173 -0
- data/lib/mutant/matcher/method/classifier.rb +126 -0
- data/lib/mutant/matcher/method/instance.rb +67 -0
- data/lib/mutant/matcher/method/singleton.rb +141 -0
- data/lib/mutant/matcher/object_space.rb +114 -0
- data/lib/mutant/matcher/scope_methods.rb +127 -0
- data/lib/mutant/mutation.rb +101 -12
- data/lib/mutant/mutation/filter.rb +75 -0
- data/lib/mutant/mutation/filter/code.rb +68 -0
- data/lib/mutant/mutation/filter/regexp.rb +39 -0
- data/lib/mutant/mutation/filter/whitelist.rb +47 -0
- data/lib/mutant/mutator.rb +134 -30
- data/lib/mutant/mutator/node.rb +163 -0
- data/lib/mutant/mutator/node/arguments.rb +24 -0
- data/lib/mutant/mutator/node/block.rb +24 -0
- data/lib/mutant/mutator/node/define.rb +24 -0
- data/lib/mutant/mutator/node/if_statement.rb +93 -0
- data/lib/mutant/mutator/node/literal.rb +54 -0
- data/lib/mutant/mutator/node/literal/array.rb +28 -0
- data/lib/mutant/mutator/node/literal/boolean.rb +49 -0
- data/lib/mutant/mutator/node/literal/dynamic.rb +24 -0
- data/lib/mutant/mutator/node/literal/empty_array.rb +26 -0
- data/lib/mutant/mutator/node/literal/fixnum.rb +37 -0
- data/lib/mutant/mutator/node/literal/float.rb +48 -0
- data/lib/mutant/mutator/node/literal/hash.rb +89 -0
- data/lib/mutant/mutator/node/literal/nil.rb +25 -0
- data/lib/mutant/mutator/node/literal/range.rb +94 -0
- data/lib/mutant/mutator/node/literal/regex.rb +43 -0
- data/lib/mutant/mutator/node/literal/string.rb +26 -0
- data/lib/mutant/mutator/node/literal/symbol.rb +26 -0
- data/lib/mutant/mutator/node/noop.rb +55 -0
- data/lib/mutant/mutator/node/receiver_case.rb +140 -0
- data/lib/mutant/mutator/node/return.rb +31 -0
- data/lib/mutant/mutator/node/send.rb +112 -0
- data/lib/mutant/mutator/registry.rb +48 -0
- data/lib/mutant/mutator/util.rb +87 -0
- data/lib/mutant/random.rb +24 -27
- data/lib/mutant/reporter.rb +48 -30
- data/lib/mutant/reporter/cli.rb +221 -0
- data/lib/mutant/reporter/null.rb +42 -0
- data/lib/mutant/reporter/stats.rb +64 -0
- data/lib/mutant/runner.rb +112 -0
- data/lib/mutant/strategy.rb +42 -0
- data/lib/mutant/strategy/rspec.rb +59 -0
- data/lib/mutant/strategy/rspec/example_lookup.rb +122 -0
- data/lib/mutant/subject.rb +115 -0
- data/lib/mutant/support/method_object.rb +31 -0
- data/locator.rb +87 -0
- data/mutant.gemspec +21 -21
- data/spec/integration/mutant/differ_spec.rb +15 -0
- data/spec/integration/mutant/loader_spec.rb +21 -0
- data/spec/integration/mutant/method_matching_spec.rb +269 -0
- data/spec/integration/mutant/rspec_killer_spec.rb +24 -0
- data/spec/integration/mutant/runner_spec.rb +26 -0
- data/spec/integration/mutant/zombie_spec.rb +8 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/command_method_behavior.rb +7 -0
- data/spec/shared/each_method_behaviour.rb +15 -0
- data/spec/shared/hash_method_behavior.rb +17 -0
- data/spec/shared/idempotent_method_behavior.rb +7 -0
- data/spec/shared/invertible_method_behaviour.rb +9 -0
- data/spec/shared/method_filter_parse_behavior.rb +16 -0
- data/spec/shared/method_match_behavior.rb +39 -0
- data/spec/shared/mutator_behavior.rb +46 -0
- data/spec/spec_helper.rb +11 -14
- data/spec/support/compress_helper.rb +10 -0
- data/spec/support/rspec.rb +22 -0
- data/spec/support/test_app.rb +5 -0
- data/spec/support/zombie.rb +141 -0
- data/spec/unit/mutant/cli/class_methods/new_spec.rb +87 -0
- data/spec/unit/mutant/cli/class_methods/run_spec.rb +38 -0
- data/spec/unit/mutant/context/root_spec.rb +11 -0
- data/spec/unit/mutant/context/scope/class_methods/build_spec.rb +29 -0
- data/spec/unit/mutant/context/scope/root_spec.rb +22 -0
- data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +27 -0
- data/spec/unit/mutant/killer/fail_ques_spec.rb +39 -0
- data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +32 -0
- data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +33 -0
- data/spec/unit/mutant/loader/rubinius/class_methods/run_spec.rb +42 -0
- data/spec/unit/mutant/matcher/chain/each_spec.rb +37 -0
- data/spec/unit/mutant/matcher/chain/matchers_spec.rb +12 -0
- data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +49 -0
- data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +12 -0
- data/spec/unit/mutant/matcher/each_spec.rb +14 -0
- data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +21 -0
- data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +34 -0
- data/spec/unit/mutant/matcher/method/method_spec.rb +11 -0
- data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +24 -0
- data/spec/unit/mutant/matcher/object_space/each_spec.rb +31 -0
- data/spec/unit/mutant/mutator/each_spec.rb +25 -0
- data/spec/unit/mutant/mutator/emit_new_spec.rb +51 -0
- data/spec/unit/mutant/mutator/emit_spec.rb +52 -0
- data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +36 -0
- data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +47 -0
- data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +30 -0
- data/spec/unit/mutant/mutator/node/literal/array_spec.rb +30 -0
- data/spec/unit/mutant/mutator/node/literal/boolean/mutation_spec.rb +23 -0
- data/spec/unit/mutant/mutator/node/literal/empty_array_spec.rb +17 -0
- data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +17 -0
- data/spec/unit/mutant/mutator/node/literal/float_spec.rb +25 -0
- data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +34 -0
- data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +13 -0
- data/spec/unit/mutant/mutator/node/literal/range_spec.rb +35 -0
- data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +23 -0
- data/spec/unit/mutant/mutator/node/literal/string_spec.rb +17 -0
- data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +17 -0
- data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +27 -0
- data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +21 -0
- data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +78 -0
- data/spec/unit/mutant/mutator/self_spec.rb +7 -0
- data/spec/unit/mutant/subject/class_methods/new_spec.rb +13 -0
- data/spec/unit/mutant/subject/context_spec.rb +14 -0
- data/spec/unit/mutant/subject/each_spec.rb +35 -0
- data/spec/unit/mutant/subject/node_spec.rb +13 -0
- data/tasks/metrics/ci.rake +7 -0
- data/tasks/metrics/flay.rake +41 -0
- data/tasks/metrics/flog.rake +43 -0
- data/tasks/metrics/heckle.rake +216 -0
- data/tasks/metrics/metric_fu.rake +31 -0
- data/tasks/metrics/reek.rake +15 -0
- data/tasks/metrics/roodi.rake +15 -0
- data/tasks/metrics/yardstick.rake +23 -0
- data/tasks/spec.rake +45 -0
- data/tasks/yard.rake +9 -0
- data/test_app/.rspec +1 -0
- data/test_app/lib/test_app.rb +5 -0
- data/test_app/lib/test_app/literal.rb +32 -0
- data/test_app/spec/shared/command_method_behavior.rb +7 -0
- data/test_app/spec/shared/each_method_behaviour.rb +15 -0
- data/test_app/spec/shared/hash_method_behavior.rb +17 -0
- data/test_app/spec/shared/idempotent_method_behavior.rb +7 -0
- data/test_app/spec/shared/invertible_method_behaviour.rb +9 -0
- data/test_app/spec/shared/method_filter_parse_behavior.rb +16 -0
- data/test_app/spec/shared/method_match_behavior.rb +39 -0
- data/test_app/spec/shared/mutator_behavior.rb +44 -0
- data/test_app/spec/spec_helper.rb +7 -0
- data/test_app/spec/unit/test_app/literal/command_spec.rb +9 -0
- data/test_app/spec/unit/test_app/literal/string_spec.rb +9 -0
- metadata +346 -124
- data/.rvmrc +0 -1
- data/Readme.md +0 -13
- data/exe/mutate +0 -6
- data/lib/mutant/extensions.rb +0 -8
- data/lib/mutant/formatter.rb +0 -19
- data/lib/mutant/implementation.rb +0 -70
- data/lib/mutant/literal.rb +0 -147
- data/lib/mutant/method.rb +0 -31
- data/lib/mutant/mutatee.rb +0 -61
- data/lib/mutant/node.rb +0 -26
- data/lib/mutant/runners/rspec.rb +0 -34
- data/lib/mutant/version.rb +0 -3
- data/spec/functional/class_spec.rb +0 -46
- data/spec/functional/instance_method/array_spec.rb +0 -53
- data/spec/functional/instance_method/boolean_spec.rb +0 -101
- data/spec/functional/instance_method/call_spec.rb +0 -161
- data/spec/functional/instance_method/fixnum_spec.rb +0 -53
- data/spec/functional/instance_method/float_spec.rb +0 -53
- data/spec/functional/instance_method/hash_spec.rb +0 -53
- data/spec/functional/instance_method/if_spec.rb +0 -57
- data/spec/functional/instance_method/ivar_assign_spec.rb +0 -62
- data/spec/functional/instance_method/range_spec.rb +0 -53
- data/spec/functional/instance_method/regex_spec.rb +0 -55
- data/spec/functional/instance_method/string_spec.rb +0 -53
- data/spec/functional/instance_method/symbol_spec.rb +0 -53
- data/spec/functional/reporter/method_loaded_spec.rb +0 -62
- data/spec/functional/reporter/running_mutations_spec.rb +0 -60
- data/spec/functional/runners/rspec_spec.rb +0 -26
- data/spec/functional/singleton_method/array_spec.rb +0 -53
- data/spec/functional/singleton_method/boolean_spec.rb +0 -101
- data/spec/functional/singleton_method/call_spec.rb +0 -161
- data/spec/functional/singleton_method/fixnum_spec.rb +0 -53
- data/spec/functional/singleton_method/float_spec.rb +0 -53
- data/spec/functional/singleton_method/hash_spec.rb +0 -53
- data/spec/functional/singleton_method/if_spec.rb +0 -57
- data/spec/functional/singleton_method/ivar_assign_spec.rb +0 -60
- data/spec/functional/singleton_method/range_spec.rb +0 -53
- data/spec/functional/singleton_method/regex_spec.rb +0 -55
- data/spec/functional/singleton_method/string_spec.rb +0 -53
- data/spec/functional/singleton_method/symbol_spec.rb +0 -53
- data/spec/mutant/extensions_spec.rb +0 -13
- data/spec/mutant/implementation_spec.rb +0 -223
- data/spec/mutant/literal_spec.rb +0 -129
- data/spec/mutant/mutatee_spec.rb +0 -28
- data/spec/mutant/node_spec.rb +0 -41
- data/spec/mutant/random_spec.rb +0 -33
- data/spec/mutant/reporter_spec.rb +0 -17
- data/spec/mutant_spec.rb +0 -28
- data/spec/support/example_group_helpers.rb +0 -11
- data/spec/support/example_helpers.rb +0 -5
data/.rvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rvm use rbx-head@mutant --create
|
data/Readme.md
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# mutant [](http://travis-ci.org/txus/mutant) [](https://gemnasium.com/txus/mutant)
|
|
2
|
-
|
|
3
|
-
Mutant is a mutation tester. It modifies your code and runs your tests to make sure they fail. The idea is that if code can be changed and your tests don't notice, either that code isn't being covered or it doesn't do anything.
|
|
4
|
-
|
|
5
|
-
Largely based on [heckle](https://github.com/seattlerb/heckle), this is a rewrite on top of [Rubinius](http://rubini.us).
|
|
6
|
-
|
|
7
|
-
## Development roadmap
|
|
8
|
-
|
|
9
|
-
As an experiment, I've set up a [public Trello board](https://trello.com/board/mutant/4f452510101d860b203b542d) with the development roadmap up to the 1.0 release. You can vote and comment cards to give constructive feedback to the project. Just have a look and leave a comment! :)
|
|
10
|
-
|
|
11
|
-
## Who's this
|
|
12
|
-
|
|
13
|
-
This project was originally created by [@justinko](http://twitter.com/justinko) and is released under the MIT license. I am pleased to be the current maintainer :) I'm [@txustice](http://twitter.com/txustice) on twitter (where you should probably follow me!).
|
data/exe/mutate
DELETED
data/lib/mutant/extensions.rb
DELETED
data/lib/mutant/formatter.rb
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Implementation
|
|
3
|
-
SINGLETON_SCOPE = '.'
|
|
4
|
-
INSTANCE_SCOPE = '#'
|
|
5
|
-
SCOPE_REGEXP = Regexp.union(SINGLETON_SCOPE, INSTANCE_SCOPE)
|
|
6
|
-
|
|
7
|
-
def initialize(str)
|
|
8
|
-
@str = str
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def scope_type
|
|
12
|
-
{ SINGLETON_SCOPE => :singleton, INSTANCE_SCOPE => :instance
|
|
13
|
-
}[method_scope]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def class_name
|
|
17
|
-
@str.split(SCOPE_REGEXP)[0]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def method_scope
|
|
21
|
-
@str[SCOPE_REGEXP]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def method_name
|
|
25
|
-
@str.split(SCOPE_REGEXP)[1] if method_scope
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def constant
|
|
29
|
-
class_name.split(/::/).inject(Object) do |context, name|
|
|
30
|
-
context.const_get name
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def all_implementations
|
|
35
|
-
all_methods.map {|formatted_method| self.class.new(formatted_method)}
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def all_methods
|
|
39
|
-
all_singleton_methods + all_instance_methods
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def all_singleton_methods
|
|
43
|
-
constant.singleton_methods(false).delete_if {|meth_name|
|
|
44
|
-
meth_name.to_s == '__class_init__' }.map {|meth_name|
|
|
45
|
-
format_method(meth_name, SINGLETON_SCOPE)}
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def all_instance_methods
|
|
49
|
-
constant.instance_methods(false).map do |meth_name|
|
|
50
|
-
format_method(meth_name, INSTANCE_SCOPE)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def mutatees
|
|
55
|
-
Array(method_scope ? self : all_implementations).map do |impl|
|
|
56
|
-
Mutatee.new(impl)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def to_s
|
|
61
|
-
@str
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
private
|
|
65
|
-
|
|
66
|
-
def format_method(meth_name, method_scope_type)
|
|
67
|
-
class_name + method_scope_type + meth_name.to_s
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
data/lib/mutant/literal.rb
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Literal
|
|
3
|
-
def self.literal_class(node)
|
|
4
|
-
const_get(node.class.basename)
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def initialize(node)
|
|
8
|
-
@node = node
|
|
9
|
-
@class = self.class.literal_class(node)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def swap
|
|
13
|
-
@class.new(@node).swap
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class BaseLiteral
|
|
17
|
-
def initialize(node)
|
|
18
|
-
@node = node
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
class FalseLiteral < BaseLiteral
|
|
23
|
-
def swap
|
|
24
|
-
Rubinius::AST::TrueLiteral.new(@node.line)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
class TrueLiteral < BaseLiteral
|
|
29
|
-
def swap
|
|
30
|
-
Rubinius::AST::FalseLiteral.new(@node.line)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class SymbolLiteral < BaseLiteral
|
|
35
|
-
def swap
|
|
36
|
-
@node.value = Random.symbol
|
|
37
|
-
@node
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
class StringLiteral < BaseLiteral
|
|
42
|
-
def swap
|
|
43
|
-
@node.string = Random.string
|
|
44
|
-
@node
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class FixnumLiteral < BaseLiteral
|
|
49
|
-
def swap
|
|
50
|
-
@node.value = Random.fixnum
|
|
51
|
-
@node
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
class FloatLiteral < BaseLiteral
|
|
56
|
-
def swap
|
|
57
|
-
@node.value = Random.float
|
|
58
|
-
@node
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
class Range < BaseLiteral
|
|
63
|
-
def swap
|
|
64
|
-
range = Random.range
|
|
65
|
-
@node.start = Rubinius::AST::FixnumLiteral.new(@node.line, range.min)
|
|
66
|
-
@node.finish = Rubinius::AST::FixnumLiteral.new(@node.line, range.max)
|
|
67
|
-
@node
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
class RegexLiteral < BaseLiteral
|
|
72
|
-
def swap
|
|
73
|
-
@node.source = Regexp.escape(Random.string)
|
|
74
|
-
@node
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
class ArrayLiteral < BaseLiteral
|
|
79
|
-
def swap
|
|
80
|
-
@node.body = @node.body.reverse[1..-1]
|
|
81
|
-
@node
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
class HashLiteral < BaseLiteral
|
|
86
|
-
def swap
|
|
87
|
-
new_body = @node.array.each_slice(2).inject([]) do |body, (key, value)|
|
|
88
|
-
new_value = literal_class(value).new(value.clone).swap
|
|
89
|
-
|
|
90
|
-
body << key << new_value
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
@node.array = new_body
|
|
94
|
-
@node
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
private
|
|
98
|
-
|
|
99
|
-
def literal_class(value)
|
|
100
|
-
Module.nesting[1].literal_class(value)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
class LocalVariableAssignment < BaseLiteral
|
|
105
|
-
def swap
|
|
106
|
-
@node.value = literal_class.new(@node.value.clone).swap
|
|
107
|
-
@node
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
private
|
|
111
|
-
|
|
112
|
-
def literal_class
|
|
113
|
-
Module.nesting[1].literal_class(@node.value)
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
class InstanceVariableAssignment < BaseLiteral
|
|
118
|
-
def swap
|
|
119
|
-
@node.value = literal_class.new(@node.value.clone).swap
|
|
120
|
-
@node
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
private
|
|
124
|
-
|
|
125
|
-
def literal_class
|
|
126
|
-
Module.nesting[1].literal_class(@node.value)
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
class If < BaseLiteral
|
|
131
|
-
def swap
|
|
132
|
-
@node.body, @node.else = @node.else, @node.body
|
|
133
|
-
@node
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
class Send < BaseLiteral
|
|
138
|
-
def swap
|
|
139
|
-
line = @node.line
|
|
140
|
-
@node = Rubinius::AST::NilLiteral.new(line)
|
|
141
|
-
@node
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
SendWithArguments = Send
|
|
146
|
-
end
|
|
147
|
-
end
|
data/lib/mutant/method.rb
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Method < Rubinius::Melbourne
|
|
3
|
-
attr_reader :ast, :source_name, :source_file, :source_line
|
|
4
|
-
|
|
5
|
-
DEFAULT_LINE = 1
|
|
6
|
-
|
|
7
|
-
def initialize(method)
|
|
8
|
-
@ast = nil
|
|
9
|
-
@source_name = method.name.to_sym
|
|
10
|
-
@source_file, @source_line = method.source_location
|
|
11
|
-
super(source_file, DEFAULT_LINE)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# TODO: Check for edge cases where just the line won't work.
|
|
15
|
-
def match?(ast)
|
|
16
|
-
source_line == ast.line
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
class InstanceMethod < Method
|
|
21
|
-
def process_defn(*)
|
|
22
|
-
super.tap { |ast| @ast = ast if match?(ast) }
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
class SingletonMethod < Method
|
|
27
|
-
def process_defs(*)
|
|
28
|
-
super.tap { |ast| @ast = ast if match?(ast.body) }
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
data/lib/mutant/mutatee.rb
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
require 'forwardable'
|
|
2
|
-
|
|
3
|
-
module Mutant
|
|
4
|
-
class Mutatee
|
|
5
|
-
extend Forwardable
|
|
6
|
-
|
|
7
|
-
attr_reader :implementation, :mutations
|
|
8
|
-
|
|
9
|
-
def initialize(implementation)
|
|
10
|
-
@implementation = implementation
|
|
11
|
-
@mutations = []
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def_delegators :@implementation, :class_name, :method_name, :to_s
|
|
15
|
-
|
|
16
|
-
def clean
|
|
17
|
-
body.array.delete_if do |literal|
|
|
18
|
-
not Mutant::Literal.constants.map(&:to_sym).include?(literal.class.basename.to_sym)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def set_mutations
|
|
23
|
-
nodes.each do |node|
|
|
24
|
-
@mutations << Mutation.new(node, body.array)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def nodes
|
|
29
|
-
body.array.map {|item| Node.new(item) }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def mutations_remaining
|
|
33
|
-
@mutations.reject(&:mutated?)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def ast
|
|
37
|
-
@ast ||= rbx_method.parse_file && rbx_method.ast
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def body
|
|
41
|
-
@body ||= rbx_method.is_a?(SingletonMethod) ? ast.body.body : ast.body
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def rbx_method
|
|
46
|
-
@rbx_method ||=
|
|
47
|
-
case implementation.scope_type
|
|
48
|
-
when :singleton then SingletonMethod.new \
|
|
49
|
-
implementation.constant.method(method_name)
|
|
50
|
-
when :instance then InstanceMethod.new \
|
|
51
|
-
implementation.constant.instance_method(method_name)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
def marshal(data)
|
|
58
|
-
Marshal.load(Marshal.dump(data))
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
data/lib/mutant/node.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Node
|
|
3
|
-
attr_reader :item, :copy
|
|
4
|
-
|
|
5
|
-
def initialize(item)
|
|
6
|
-
@item = item
|
|
7
|
-
@copy = item.clone
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def line
|
|
11
|
-
item.line
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def from
|
|
15
|
-
@from ||= Formatter.new(item)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def to
|
|
19
|
-
@to ||= Formatter.new(copy)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def swap
|
|
23
|
-
@copy = Literal.new(copy).swap
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/mutant/runners/rspec.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
require 'rspec/core'
|
|
2
|
-
|
|
3
|
-
module Mutant
|
|
4
|
-
module Runners
|
|
5
|
-
class RSpec
|
|
6
|
-
ABORT_MESSAGE = 'Initial run of specs failed... fix and run mutant again'
|
|
7
|
-
|
|
8
|
-
def self.run(args)
|
|
9
|
-
runner = new(args)
|
|
10
|
-
runner.initial_run
|
|
11
|
-
runner.mutate
|
|
12
|
-
puts runner.run.zero? ? 'failed' : 'passed'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def initialize(args)
|
|
16
|
-
@implementation = Implementation.new(args.shift)
|
|
17
|
-
@args = args
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def initial_run
|
|
21
|
-
abort ABORT_MESSAGE unless run.zero?
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def run
|
|
25
|
-
::RSpec::Core::Runner.run(@args)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def mutate
|
|
29
|
-
Mutant.mutate(@implementation)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
data/lib/mutant/version.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe 'Mutating a class' do
|
|
4
|
-
before do
|
|
5
|
-
write_file 'thing.rb', """
|
|
6
|
-
class Thing
|
|
7
|
-
def alive?; true end
|
|
8
|
-
def dead?; false end
|
|
9
|
-
def mood; :happy end
|
|
10
|
-
def gender; 'male' end
|
|
11
|
-
def alphabet_range; 'a'..'k' end
|
|
12
|
-
end
|
|
13
|
-
"""
|
|
14
|
-
write_file 'spec/thing_spec.rb', """
|
|
15
|
-
$: << '.'
|
|
16
|
-
require 'thing'
|
|
17
|
-
|
|
18
|
-
describe Thing do
|
|
19
|
-
describe '#alive?' do
|
|
20
|
-
specify { Thing.new.should be_alive }
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '#dead?' do
|
|
24
|
-
specify { Thing.new.should_not be_dead }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
describe '#mood' do
|
|
28
|
-
specify { Thing.new.mood.should eq(:happy) }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
describe '#gender' do
|
|
32
|
-
specify { Thing.new.gender.should eq('male') }
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe '#alphabet_range' do
|
|
36
|
-
specify { Thing.new.alphabet_range.should eq('a'..'k') }
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
"""
|
|
40
|
-
mutate 'Thing spec/thing_spec.rb'
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'runs all possible mutations' do
|
|
44
|
-
all_output.should include('passed')
|
|
45
|
-
end
|
|
46
|
-
end
|