mutiny 0.2.8 → 0.3.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/RELEASES.md +6 -0
- data/lib/mutiny/analysis/analyser/default.rb +5 -1
- data/lib/mutiny/integration/rspec/parser.rb +2 -4
- data/lib/mutiny/mode/check.rb +10 -6
- data/lib/mutiny/mutants/mutant.rb +1 -1
- data/lib/mutiny/subjects/environment.rb +1 -1
- data/lib/mutiny/subjects/subject_set.rb +19 -1
- data/lib/mutiny/tests/test.rb +13 -3
- data/lib/mutiny/tests/test_set.rb +19 -10
- data/lib/mutiny/tests/test_set/filter.rb +19 -0
- data/lib/mutiny/tests/test_set/filter/default.rb +29 -0
- data/lib/mutiny/tests/test_set/filterable.rb +26 -0
- data/lib/mutiny/version.rb +1 -1
- data/mutiny.gemspec +1 -1
- data/spec/unit/subjects/subject_set_spec.rb +27 -0
- data/spec/unit/tests/test_set/filter/default_spec.rb +32 -0
- data/spec/unit/tests/test_set/filterable_spec.rb +61 -0
- data/spec/unit/tests/test_set_spec.rb +37 -0
- metadata +15 -6
- data/spec/unit/subjects/test_set_spec.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8022ed2607c22424b82450df4d6677b0cca31f7
|
4
|
+
data.tar.gz: 5ae8a0cbc564142fd95b3dbea091c9de2743fe66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 260df403d7bd1d04c1516f08098792f31920ef4b15a6f98eafb1e97d79f7fb71090f84d766b003bd52798555a5de86aaef9519e769d7da7976da24ae6daeb7ad
|
7
|
+
data.tar.gz: f4e6fbfe0cc8a16a4d1055234babbae6f0f381dc4a4a1d332c1127d589a2d19cd4732c9c6dba48752fafc2cacc872468c07896bbd2889a5447aa906117c8c0ac
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mutiny (0.
|
4
|
+
mutiny (0.3.0)
|
5
5
|
gli (~> 2.13.0)
|
6
|
-
metamorpher (~> 0.2.
|
6
|
+
metamorpher (~> 0.2.6)
|
7
7
|
parser (~> 2.2.2)
|
8
8
|
unparser (~> 0.2.4)
|
9
9
|
|
@@ -51,7 +51,7 @@ GEM
|
|
51
51
|
json (1.8.3)
|
52
52
|
memoizable (0.4.2)
|
53
53
|
thread_safe (~> 0.3, >= 0.3.1)
|
54
|
-
metamorpher (0.2.
|
54
|
+
metamorpher (0.2.6)
|
55
55
|
attributable (~> 0.1.0)
|
56
56
|
parser (~> 2.2.2)
|
57
57
|
unparser (~> 0.2.4)
|
data/RELEASES.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
## v0.3.0 (18 March 2016)
|
4
|
+
* Implement more sophisticated test filtering, which works well with targeted tests (e.g., "List#empty should have size 0") and with generic tests (e.g., "Users should be able to log out").
|
5
|
+
* Capture more forms of stillborn mutant, including those arising from instances of `ScriptError`.
|
6
|
+
* Fix bug in which mutation would be repeated if there was more than one subject in a single source file.
|
7
|
+
* Fix bugs in mutations of hash literals and array literals.
|
8
|
+
|
3
9
|
## v0.2.8 (22 February 2016)
|
4
10
|
* Prevent insertion operators from incorrectly mutating private and protected keywords.
|
5
11
|
* Fix bugs in mutating overlapping ASTs (by upgrading to metamorpher v0.2.5).
|
@@ -4,8 +4,12 @@ module Mutiny
|
|
4
4
|
module Analysis
|
5
5
|
class Analyser
|
6
6
|
class Default < self
|
7
|
+
def before_all(mutant_set)
|
8
|
+
@subject_set = Subjects::SubjectSet.new(mutant_set.subjects)
|
9
|
+
end
|
10
|
+
|
7
11
|
def select_tests(mutant)
|
8
|
-
integration.tests.for(mutant.subject)
|
12
|
+
integration.tests.filterable(@subject_set).for(mutant.subject)
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -7,8 +7,6 @@ module Mutiny
|
|
7
7
|
# This code originally based on Markus Schirp's implementation of Mutant::Integration::Rspec
|
8
8
|
# https://github.com/mbj/mutant/blob/master/lib/mutant/integration/rspec.rb
|
9
9
|
class Parser
|
10
|
-
EXPRESSION_DELIMITER = " "
|
11
|
-
|
12
10
|
def initialize(context = Context.new)
|
13
11
|
@world = context.world
|
14
12
|
end
|
@@ -26,9 +24,9 @@ module Mutiny
|
|
26
24
|
def parse_example(example)
|
27
25
|
metadata = example.metadata
|
28
26
|
location = metadata.fetch(:location)
|
29
|
-
|
27
|
+
name = metadata.fetch(:full_description)
|
30
28
|
|
31
|
-
Test.new(location: location,
|
29
|
+
Test.new(location: location, name: name, example: example)
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
data/lib/mutiny/mode/check.rb
CHANGED
@@ -6,7 +6,7 @@ module Mutiny
|
|
6
6
|
def run
|
7
7
|
report "Checking..."
|
8
8
|
|
9
|
-
if
|
9
|
+
if relevant_test_set.empty?
|
10
10
|
report_invalid
|
11
11
|
|
12
12
|
elsif test_run.passed?
|
@@ -25,7 +25,7 @@ module Mutiny
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def report_warning
|
28
|
-
report " At least one relevant test found (#{
|
28
|
+
report " At least one relevant test found (#{relevant_test_set.size} in total)"
|
29
29
|
report " Not all relevant tests passed. The failing tests are:\n"
|
30
30
|
|
31
31
|
failed_test_locations.each do |location|
|
@@ -37,7 +37,7 @@ module Mutiny
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def report_valid
|
40
|
-
report " At least one relevant test found (#{
|
40
|
+
report " At least one relevant test found (#{relevant_test_set.size} in total)"
|
41
41
|
report " All relevant tests passed"
|
42
42
|
report "Looks good!"
|
43
43
|
end
|
@@ -50,12 +50,16 @@ module Mutiny
|
|
50
50
|
test_run.failed_tests.locations
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
@test_set ||=
|
53
|
+
def relevant_test_set
|
54
|
+
@test_set ||= complete_test_set.for_all(environment.subjects)
|
55
|
+
end
|
56
|
+
|
57
|
+
def complete_test_set
|
58
|
+
@complete_test_set ||= configuration.integration.tests.filterable(environment.subjects)
|
55
59
|
end
|
56
60
|
|
57
61
|
def test_run
|
58
|
-
@test_run ||= configuration.integration.run(
|
62
|
+
@test_run ||= configuration.integration.run(relevant_test_set)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
end
|
@@ -3,7 +3,8 @@ module Mutiny
|
|
3
3
|
class SubjectSet
|
4
4
|
include Enumerable
|
5
5
|
extend Forwardable
|
6
|
-
|
6
|
+
attr_reader :subjects
|
7
|
+
def_delegators :@subjects, :each, :product, :hash
|
7
8
|
|
8
9
|
def initialize(subjects)
|
9
10
|
@subjects = subjects
|
@@ -12,6 +13,23 @@ module Mutiny
|
|
12
13
|
def names
|
13
14
|
@names ||= map(&:name).sort
|
14
15
|
end
|
16
|
+
|
17
|
+
def [](index)
|
18
|
+
subjects.detect { |s| s.name == index }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a new SubjectSet which contains only one subject per source file
|
22
|
+
# For source files that contain more than one subject (i.e., Ruby module),
|
23
|
+
# the subjects are ordered by name alphabetically and only the first is used
|
24
|
+
def per_file
|
25
|
+
self.class.new(group_by(&:path).values.map { |subjects| subjects.sort_by(&:name).first })
|
26
|
+
end
|
27
|
+
|
28
|
+
def eql?(other)
|
29
|
+
is_a?(other.class) && other.subjects == subjects
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method "==", "eql?"
|
15
33
|
end
|
16
34
|
end
|
17
35
|
end
|
data/lib/mutiny/tests/test.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
module Mutiny
|
2
2
|
module Tests
|
3
3
|
class Test
|
4
|
-
attr_reader :location, :
|
4
|
+
attr_reader :location, :name
|
5
5
|
|
6
|
-
def initialize(location: nil,
|
6
|
+
def initialize(location: nil, name:)
|
7
7
|
@location = location
|
8
|
-
@
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def eql?(other)
|
12
|
+
other.location == location && other.name == name
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method "==", "eql?"
|
16
|
+
|
17
|
+
def hash
|
18
|
+
[location, name].hash
|
9
19
|
end
|
10
20
|
end
|
11
21
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require "forwardable"
|
2
|
+
require_relative "test_set/filterable"
|
3
|
+
require_relative "test_set/filter/default"
|
2
4
|
|
3
5
|
module Mutiny
|
4
6
|
module Tests
|
@@ -18,31 +20,38 @@ module Mutiny
|
|
18
20
|
tests.map(&:location)
|
19
21
|
end
|
20
22
|
|
21
|
-
def for_all(subject_set)
|
22
|
-
subset { |test| subject_set.names.include?(test.expression) }
|
23
|
-
end
|
24
|
-
|
25
|
-
def for(subject)
|
26
|
-
subset { |test| subject.name == test.expression }
|
27
|
-
end
|
28
|
-
|
29
23
|
def subset(&block)
|
30
|
-
|
24
|
+
derive(tests.select(&block))
|
31
25
|
end
|
32
26
|
|
33
27
|
def take(n)
|
34
|
-
|
28
|
+
derive(tests.take(n))
|
35
29
|
end
|
36
30
|
|
37
31
|
def eql?(other)
|
38
32
|
is_a?(other.class) && other.tests == tests
|
39
33
|
end
|
40
34
|
|
35
|
+
def filterable(subjects, filtering_strategy: Filter::Default)
|
36
|
+
extend(Filterable)
|
37
|
+
self.filter = filtering_strategy.new(subject_names: subjects.names)
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
41
|
alias_method "==", "eql?"
|
42
42
|
|
43
43
|
protected
|
44
44
|
|
45
45
|
attr_reader :tests
|
46
|
+
|
47
|
+
def derive(tests)
|
48
|
+
self.class.new(tests).tap do |derived|
|
49
|
+
if respond_to?(:filter)
|
50
|
+
derived.extend(Filterable)
|
51
|
+
derived.filter = filter
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
46
55
|
end
|
47
56
|
end
|
48
57
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Mutiny
|
2
|
+
module Tests
|
3
|
+
class TestSet
|
4
|
+
class Filter
|
5
|
+
def initialize(subject_names:)
|
6
|
+
@subject_names = subject_names
|
7
|
+
end
|
8
|
+
|
9
|
+
def related?(subject_name:, test_name:)
|
10
|
+
fail "Subclasses must implement Filter#related? for #{subject_name}, #{test_name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
attr_reader :subject_names
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "../filter"
|
2
|
+
|
3
|
+
module Mutiny
|
4
|
+
module Tests
|
5
|
+
class TestSet
|
6
|
+
class Filter
|
7
|
+
class Default < self
|
8
|
+
def related?(subject_name:, test_name:)
|
9
|
+
general?(test_name) || specific_to?(test_name, subject_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# Returns true if the test is applicable to no specific subject
|
15
|
+
# (e.g., is an end-to-end test)
|
16
|
+
def general?(test_name)
|
17
|
+
subject_names.none? { |subject_name| test_name.start_with?(subject_name) }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns true if the test is specific to the given subject
|
21
|
+
# (e.g., is a unit test for the specified subject)
|
22
|
+
def specific_to?(test_name, subject_name)
|
23
|
+
test_name.start_with?(subject_name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require_relative "filter/default"
|
3
|
+
|
4
|
+
module Mutiny
|
5
|
+
module Tests
|
6
|
+
class TestSet
|
7
|
+
module Filterable
|
8
|
+
attr_accessor :filter
|
9
|
+
|
10
|
+
def for_all(subject_set)
|
11
|
+
subset { |test| subject_set.any? { |subject| related?(subject, test) } }
|
12
|
+
end
|
13
|
+
|
14
|
+
def for(subject)
|
15
|
+
subset { |test| related?(subject, test) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def related?(subject, test)
|
21
|
+
filter.related?(subject_name: subject.name, test_name: test.name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/mutiny/version.rb
CHANGED
data/mutiny.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_runtime_dependency "parser", "~> 2.2.2"
|
22
22
|
spec.add_runtime_dependency "unparser", "~> 0.2.4"
|
23
23
|
spec.add_runtime_dependency "gli", "~> 2.13.0"
|
24
|
-
spec.add_runtime_dependency "metamorpher", "~> 0.2.
|
24
|
+
spec.add_runtime_dependency "metamorpher", "~> 0.2.6"
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.11"
|
27
27
|
spec.add_development_dependency "rake", "~> 10.4.2"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mutiny
|
2
|
+
module Subjects
|
3
|
+
describe SubjectSet do
|
4
|
+
context "per_file" do
|
5
|
+
it "should contain only the alphabetically first subject when more than one in a file" do
|
6
|
+
first = Subject.new(name: "Bar", path: "main.rb")
|
7
|
+
second = Subject.new(name: "Foo", path: "main.rb")
|
8
|
+
nested = Subject.new(name: "Foo::Bar", path: "main.rb")
|
9
|
+
|
10
|
+
all_subjects = SubjectSet.new([first, second, nested])
|
11
|
+
|
12
|
+
expect(all_subjects.per_file).to eq(SubjectSet.new([first]))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should contain all subjects when there are one-per-file" do
|
16
|
+
first = Subject.new(name: "Bar", path: "bar.rb")
|
17
|
+
second = Subject.new(name: "Foo", path: "foo.rb")
|
18
|
+
nested = Subject.new(name: "Foo::Bar", path: "foo/bar.rb")
|
19
|
+
|
20
|
+
all_subjects = SubjectSet.new([first, second, nested])
|
21
|
+
|
22
|
+
expect(all_subjects.per_file).to eq(all_subjects)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mutiny
|
2
|
+
module Tests
|
3
|
+
class TestSet
|
4
|
+
class Filter
|
5
|
+
describe Default do
|
6
|
+
subject { Default.new(subject_names: %w(Max Min)) }
|
7
|
+
|
8
|
+
it "should return true when the test and subject have the same name" do
|
9
|
+
expect(subject.related?(subject_name: "Max", test_name: "Max")).to be_truthy
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return true when the test is for a specific method in the subject" do
|
13
|
+
expect(subject.related?(subject_name: "Max", test_name: "Max.run")).to be_truthy
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return true when the test is for a specific class method in the subject" do
|
17
|
+
expect(subject.related?(subject_name: "Max", test_name: "Max#run")).to be_truthy
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return false when the test and subject have different names" do
|
21
|
+
expect(subject.related?(subject_name: "Min", test_name: "Max")).to be_falsey
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return true when the test does not begin with a known subject" do
|
25
|
+
expect(subject.related?(subject_name: "Max", test_name: "system test")).to be_truthy
|
26
|
+
expect(subject.related?(subject_name: "Min", test_name: "system test")).to be_truthy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Mutiny
|
2
|
+
module Tests
|
3
|
+
class TestSet
|
4
|
+
describe Filterable do
|
5
|
+
context "for" do
|
6
|
+
let(:subjects) { subject_set_for("Max", "Min") }
|
7
|
+
let(:test_set) { test_set_for("Min", "Min#run", subjects: subjects) }
|
8
|
+
|
9
|
+
it "should return only those tests that are relevant to the subject" do
|
10
|
+
expected = test_set_for("Min", "Min#run", subjects: subjects)
|
11
|
+
expect(test_set.for(subjects["Min"])).to eq(expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return no tests if none are relevant to the subject" do
|
15
|
+
expect(test_set.for(subjects["Max"])).to eq(TestSet.empty)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "for all" do
|
20
|
+
let(:subjects) { subject_set_for("Max", "Min") }
|
21
|
+
let(:test_set) { test_set_for("Min", "Min#run", subjects: subjects) }
|
22
|
+
|
23
|
+
it "should remove irrelevant tests" do
|
24
|
+
expected = test_set.subset { |t| t.name != "Subtract" }
|
25
|
+
|
26
|
+
expect(test_set.for_all(subjects)).to eq(expected)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return all relevant tests" do
|
30
|
+
expected = test_set.subset { |t| t.name.start_with?("Min") }
|
31
|
+
|
32
|
+
expect(test_set.for_all(subjects)).to eq(expected)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return no tests when there are no tests" do
|
36
|
+
expect(TestSet.empty.filterable(subjects).for_all(subjects)).to eq(TestSet.empty)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def subject_set_for(*names)
|
41
|
+
Subjects::SubjectSet.new(names.map { |n| Subjects::Subject.new(name: n) })
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_set_for(*expressions, subjects:)
|
45
|
+
TestSet.new(tests_for(*expressions))
|
46
|
+
.filterable(subjects, filtering_strategy: DummyStrategy)
|
47
|
+
end
|
48
|
+
|
49
|
+
def tests_for(*names)
|
50
|
+
names.map { |name| Test.new(name: name) }
|
51
|
+
end
|
52
|
+
|
53
|
+
class DummyStrategy < Filter
|
54
|
+
def related?(subject_name:, test_name:)
|
55
|
+
test_name.start_with?(subject_name)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Mutiny
|
2
|
+
module Tests
|
3
|
+
describe TestSet do
|
4
|
+
let(:tests) { %w(test1 test2 test3) }
|
5
|
+
subject { TestSet.new(tests) }
|
6
|
+
|
7
|
+
context "take" do
|
8
|
+
it "(n) should return TestSet containing first n tests" do
|
9
|
+
expect(subject.take(2)).to eq(TestSet.new(tests.take(2)))
|
10
|
+
end
|
11
|
+
|
12
|
+
it "(0) should return an empty TestSet" do
|
13
|
+
expect(subject.take(0)).to eq(TestSet.empty)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "(n) of an empty TestSet should return an empty TestSet" do
|
17
|
+
expect(TestSet.empty.take(2)).to eq(TestSet.empty)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "subset" do
|
22
|
+
it "should return TestSet containing tests that match condition" do
|
23
|
+
subset = subject.subset { |t| t.end_with? "2" }
|
24
|
+
expected = TestSet.new(tests.select { |t| t.end_with? "2" })
|
25
|
+
|
26
|
+
expect(subset).to eq(expected)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return empty TestSet when no tests match condition" do
|
30
|
+
subset = subject.subset { |_| false }
|
31
|
+
|
32
|
+
expect(subset).to eq(TestSet.empty)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mutiny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis Rose
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.2.
|
61
|
+
version: 0.2.6
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.2.
|
68
|
+
version: 0.2.6
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -248,6 +248,9 @@ files:
|
|
248
248
|
- lib/mutiny/tests/test.rb
|
249
249
|
- lib/mutiny/tests/test_run.rb
|
250
250
|
- lib/mutiny/tests/test_set.rb
|
251
|
+
- lib/mutiny/tests/test_set/filter.rb
|
252
|
+
- lib/mutiny/tests/test_set/filter/default.rb
|
253
|
+
- lib/mutiny/tests/test_set/filterable.rb
|
251
254
|
- lib/mutiny/version.rb
|
252
255
|
- mutiny.gemspec
|
253
256
|
- spec/integration/check_spec.rb
|
@@ -284,8 +287,11 @@ files:
|
|
284
287
|
- spec/unit/pattern_spec.rb
|
285
288
|
- spec/unit/subjects/environment/type_spec.rb
|
286
289
|
- spec/unit/subjects/environment_spec.rb
|
290
|
+
- spec/unit/subjects/subject_set_spec.rb
|
287
291
|
- spec/unit/subjects/subject_spec.rb
|
288
|
-
- spec/unit/
|
292
|
+
- spec/unit/tests/test_set/filter/default_spec.rb
|
293
|
+
- spec/unit/tests/test_set/filterable_spec.rb
|
294
|
+
- spec/unit/tests/test_set_spec.rb
|
289
295
|
homepage: https://github.com/mutiny/mutiny
|
290
296
|
licenses:
|
291
297
|
- MIT
|
@@ -345,5 +351,8 @@ test_files:
|
|
345
351
|
- spec/unit/pattern_spec.rb
|
346
352
|
- spec/unit/subjects/environment/type_spec.rb
|
347
353
|
- spec/unit/subjects/environment_spec.rb
|
354
|
+
- spec/unit/subjects/subject_set_spec.rb
|
348
355
|
- spec/unit/subjects/subject_spec.rb
|
349
|
-
- spec/unit/
|
356
|
+
- spec/unit/tests/test_set/filter/default_spec.rb
|
357
|
+
- spec/unit/tests/test_set/filterable_spec.rb
|
358
|
+
- spec/unit/tests/test_set_spec.rb
|
@@ -1,75 +0,0 @@
|
|
1
|
-
module Mutiny
|
2
|
-
module Tests
|
3
|
-
describe TestSet do
|
4
|
-
let(:tests) { %w(test1 test2 test3) }
|
5
|
-
subject { TestSet.new(tests) }
|
6
|
-
|
7
|
-
context "take" do
|
8
|
-
it "(n) should return TestSet containing first n tests" do
|
9
|
-
expect(subject.take(2)).to eq(TestSet.new(tests.take(2)))
|
10
|
-
end
|
11
|
-
|
12
|
-
it "(0) should return an empty TestSet" do
|
13
|
-
expect(subject.take(0)).to eq(TestSet.empty)
|
14
|
-
end
|
15
|
-
|
16
|
-
it "(n) of an empty TestSet should return an empty TestSet" do
|
17
|
-
expect(TestSet.empty.take(2)).to eq(TestSet.empty)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
context "subset" do
|
22
|
-
it "should return TestSet containing tests that match condition" do
|
23
|
-
subset = subject.subset { |t| t.end_with? "2" }
|
24
|
-
expected = TestSet.new(tests.select { |t| t.end_with? "2" })
|
25
|
-
|
26
|
-
expect(subset).to eq(expected)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should return empty TestSet when no tests match condition" do
|
30
|
-
subset = subject.subset { |_| false }
|
31
|
-
|
32
|
-
expect(subset).to eq(TestSet.empty)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context "for" do
|
37
|
-
it "should return only those tests (whose expression) matches a subject" do
|
38
|
-
subjects = subject_set_for("Max", "Min")
|
39
|
-
test_set = test_set_for("Subtract", "Min", "Add")
|
40
|
-
|
41
|
-
expect(test_set.for_all(subjects)).to eq(test_set.subset { |t| t.expression == "Min" })
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should return multiple tests for a single subject" do
|
45
|
-
subjects = subject_set_for("Min")
|
46
|
-
test_set = test_set_for("Min", "Max", "Min", "Max", "Min")
|
47
|
-
|
48
|
-
expect(test_set.for_all(subjects)).to eq(test_set.subset { |t| t.expression == "Min" })
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should return no tests when there are no tests" do
|
52
|
-
subjects = subject_set_for("Max", "Min")
|
53
|
-
test_set = TestSet.empty
|
54
|
-
|
55
|
-
expect(test_set.for_all(subjects)).to eq(TestSet.empty)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should return no tests when there are no relevant subjects" do
|
59
|
-
subjects = subject_set_for("Max", "Min")
|
60
|
-
test_set = test_set_for("Subtract", "Add")
|
61
|
-
|
62
|
-
expect(test_set.for_all(subjects)).to eq(TestSet.empty)
|
63
|
-
end
|
64
|
-
|
65
|
-
def subject_set_for(*names)
|
66
|
-
Subjects::SubjectSet.new(names.map { |n| Subjects::Subject.new(name: n) })
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_set_for(*expressions)
|
70
|
-
TestSet.new(expressions.map { |e| Test.new(expression: e) })
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|