ward 0.1.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/.document +5 -0
- data/.gitignore +28 -0
- data/LICENSE +19 -0
- data/README.markdown +99 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/features/acceptance_matcher.feature +78 -0
- data/features/attribute_keyword.feature +13 -0
- data/features/close_to_matcher.feature +130 -0
- data/features/context_arguments.feature +47 -0
- data/features/equal_to_matcher.feature +25 -0
- data/features/error_messages.feature +69 -0
- data/features/external_validation.feature +15 -0
- data/features/has_matcher.feature +72 -0
- data/features/has_matcher_initialized_with_expectation.feature +94 -0
- data/features/has_matcher_relativities.feature +171 -0
- data/features/include_matcher.feature +28 -0
- data/features/is_keyword.feature +42 -0
- data/features/is_not_keyword.feature +62 -0
- data/features/match_matcher.feature +49 -0
- data/features/multiple_validators.feature +29 -0
- data/features/nil_matcher.feature +25 -0
- data/features/predicate_matcher.feature +23 -0
- data/features/present_matcher.feature +59 -0
- data/features/satisfy_matcher.feature +80 -0
- data/features/scenario_validation.feature +81 -0
- data/features/step_definitions/external_validation_steps.rb +69 -0
- data/features/step_definitions/generic_validation_steps.rb +33 -0
- data/features/step_definitions/object_definition_steps.rb +43 -0
- data/features/support/env.rb +12 -0
- data/features/support/object_builder.rb +33 -0
- data/features/support/struct.rb +38 -0
- data/lang/en.yml +56 -0
- data/lib/ward.rb +26 -0
- data/lib/ward/context.rb +70 -0
- data/lib/ward/context_chain.rb +87 -0
- data/lib/ward/dsl.rb +7 -0
- data/lib/ward/dsl/validation_block.rb +73 -0
- data/lib/ward/dsl/validation_builder.rb +190 -0
- data/lib/ward/errors.rb +213 -0
- data/lib/ward/matchers.rb +97 -0
- data/lib/ward/matchers/acceptance.rb +43 -0
- data/lib/ward/matchers/close_to.rb +60 -0
- data/lib/ward/matchers/equal_to.rb +33 -0
- data/lib/ward/matchers/has.rb +283 -0
- data/lib/ward/matchers/include.rb +54 -0
- data/lib/ward/matchers/match.rb +29 -0
- data/lib/ward/matchers/matcher.rb +68 -0
- data/lib/ward/matchers/nil.rb +30 -0
- data/lib/ward/matchers/predicate.rb +31 -0
- data/lib/ward/matchers/present.rb +56 -0
- data/lib/ward/matchers/satisfy.rb +65 -0
- data/lib/ward/spec.rb +17 -0
- data/lib/ward/spec/matcher_matcher.rb +114 -0
- data/lib/ward/support.rb +7 -0
- data/lib/ward/support/basic_object.rb +55 -0
- data/lib/ward/support/result.rb +49 -0
- data/lib/ward/validator.rb +147 -0
- data/lib/ward/validator_set.rb +115 -0
- data/lib/ward/version.rb +3 -0
- data/spec/lib/has_matcher_relativity_examples.rb +15 -0
- data/spec/lib/have_public_method_defined.rb +22 -0
- data/spec/rcov.opts +8 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/ward/context_chain_spec.rb +178 -0
- data/spec/ward/context_spec.rb +57 -0
- data/spec/ward/dsl/validation_block_spec.rb +27 -0
- data/spec/ward/dsl/validation_builder_spec.rb +212 -0
- data/spec/ward/errors_spec.rb +149 -0
- data/spec/ward/matchers/acceptance_spec.rb +16 -0
- data/spec/ward/matchers/close_to_spec.rb +57 -0
- data/spec/ward/matchers/equal_to_spec.rb +16 -0
- data/spec/ward/matchers/has_spec.rb +175 -0
- data/spec/ward/matchers/include_spec.rb +41 -0
- data/spec/ward/matchers/match_spec.rb +21 -0
- data/spec/ward/matchers/matcher_spec.rb +54 -0
- data/spec/ward/matchers/nil_spec.rb +16 -0
- data/spec/ward/matchers/predicate_spec.rb +19 -0
- data/spec/ward/matchers/present_spec.rb +16 -0
- data/spec/ward/matchers/satisfy_spec.rb +68 -0
- data/spec/ward/matchers_spec.rb +51 -0
- data/spec/ward/spec/have_public_method_defined_spec.rb +31 -0
- data/spec/ward/spec/matcher_matcher_spec.rb +217 -0
- data/spec/ward/validator_set_spec.rb +178 -0
- data/spec/ward/validator_spec.rb +264 -0
- data/tasks/features.rake +15 -0
- data/tasks/rcov.rake +24 -0
- data/tasks/spec.rake +18 -0
- data/tasks/yard.rake +9 -0
- data/ward.gemspec +176 -0
- metadata +239 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Errors do
|
4
|
+
subject { Ward::Errors }
|
5
|
+
|
6
|
+
it 'should be enumerable' do
|
7
|
+
Ward::Errors.ancestors.should include(Enumerable)
|
8
|
+
end
|
9
|
+
|
10
|
+
it { should have_public_method_defined(:each) }
|
11
|
+
|
12
|
+
describe '#each' do
|
13
|
+
it 'should yield each invalid attribute' do
|
14
|
+
errors = Ward::Errors.new
|
15
|
+
errors.add(:one, 'Whoops')
|
16
|
+
errors.add(:two, 'Whoops')
|
17
|
+
|
18
|
+
attributes = errors.map { |attribute, _| attribute }
|
19
|
+
attributes.should include(:one)
|
20
|
+
attributes.should include(:two)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# add
|
26
|
+
#
|
27
|
+
|
28
|
+
describe '#add' do
|
29
|
+
it 'should return the message which was set' do
|
30
|
+
Ward::Errors.new.add(:name, 'Whoops').should == 'Whoops'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# on
|
36
|
+
#
|
37
|
+
|
38
|
+
it { should have_public_method_defined(:on) }
|
39
|
+
|
40
|
+
describe '#on' do
|
41
|
+
|
42
|
+
describe 'when there is one error keyed on an attribute name' do
|
43
|
+
before(:all) do
|
44
|
+
@errors = Ward::Errors.new
|
45
|
+
@errors.add(:name, 'Name should not fail')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should return nil when no error is present on the attribute' do
|
49
|
+
@errors.on(:__invalid__).should be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'return a string when an error is present on the attribute' do
|
53
|
+
@errors.on(:name).should == ['Name should not fail']
|
54
|
+
end
|
55
|
+
end # when there is one error keyed on an attribute name
|
56
|
+
|
57
|
+
describe 'when there is one error keyed on a single context' do
|
58
|
+
before(:all) do
|
59
|
+
@errors = Ward::Errors.new
|
60
|
+
@errors.add(Ward::Context.new(:name), 'Name should not fail')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should return nil when no error is present on the attribute' do
|
64
|
+
@errors.on(:__invalid__).should be_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'return a string when an error is present on the attribute' do
|
68
|
+
@errors.on(:name).should == ['Name should not fail']
|
69
|
+
end
|
70
|
+
end # when there is one error keyed on a single context
|
71
|
+
|
72
|
+
describe 'when there is one error keyed on a context chain' do
|
73
|
+
before(:all) do
|
74
|
+
chain = Ward::ContextChain.new
|
75
|
+
chain.push(Ward::Context.new(:name))
|
76
|
+
chain.push(Ward::Context.new(:length))
|
77
|
+
|
78
|
+
@errors = Ward::Errors.new
|
79
|
+
@errors.add(chain, 'Name should not fail')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should return nil when no error is present on the attribute' do
|
83
|
+
@errors.on(:__invalid__).should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'return a string when an error is present on the attribute' do
|
87
|
+
@errors.on(:name).should == ['Name should not fail']
|
88
|
+
end
|
89
|
+
end # when there is one error keyed on a context chain
|
90
|
+
|
91
|
+
end # on
|
92
|
+
|
93
|
+
# Class methods ============================================================
|
94
|
+
|
95
|
+
describe '.message' do
|
96
|
+
it 'should return the message specified' do
|
97
|
+
message = Ward::Errors.message('has.eql.positive')
|
98
|
+
message.should == '%{context} should have %{expected} %{collection}'
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should return the first matching message key' do
|
102
|
+
message = Ward::Errors.message(
|
103
|
+
'does.not.exist', 'has.eql.negative', 'has.eql.positive')
|
104
|
+
|
105
|
+
message.should == '%{context} should not have %{expected} %{collection}'
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should return nil when no matching message is found' do
|
109
|
+
Ward::Errors.message('does.not.exist').should be_nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '.format_exclusive_list' do
|
114
|
+
it 'should return an empty string when given an empty Array' do
|
115
|
+
Ward::Errors.format_exclusive_list([]).should == ''
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should return "1" when given [1]' do
|
119
|
+
Ward::Errors.format_exclusive_list([1]).should == '1'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should return "1 or 2" when given [1, 2]' do
|
123
|
+
Ward::Errors.format_exclusive_list([1, 2]).should == '1 or 2'
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should return "1, 2, or 3" when given [1, 2, 3]' do
|
127
|
+
Ward::Errors.format_exclusive_list([1, 2, 3]).should == '1, 2, or 3'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '.format_inclusive_list' do
|
132
|
+
it 'should return an empty string when given an empty Array' do
|
133
|
+
Ward::Errors.format_inclusive_list([]).should == ''
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should return "1" when given [1]' do
|
137
|
+
Ward::Errors.format_inclusive_list([1]).should == '1'
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should return "1 or 2" when given [1, 2]' do
|
141
|
+
Ward::Errors.format_inclusive_list([1, 2]).should == '1 and 2'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should return "1, 2, or 3" when given [1, 2, 3]' do
|
145
|
+
Ward::Errors.format_inclusive_list([1, 2, 3]).should == '1, 2, and 3'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Matchers::Acceptance do
|
4
|
+
|
5
|
+
it 'should be registered with :accepted' do
|
6
|
+
matcher = Ward::Matchers.matchers[:accepted]
|
7
|
+
matcher.should == Ward::Matchers::Acceptance
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# matches?
|
12
|
+
#
|
13
|
+
|
14
|
+
# #matches? tests can be found in features/acceptance_matcher.feature
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Matchers::CloseTo do
|
4
|
+
|
5
|
+
it 'should be registered with :close_to' do
|
6
|
+
matcher = Ward::Matchers.matchers[:close_to]
|
7
|
+
matcher.should == Ward::Matchers::CloseTo
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# initialize
|
12
|
+
#
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
describe 'when given a numeric as the first and second argument' do
|
16
|
+
it 'should not raise an error' do
|
17
|
+
running_this = lambda { Ward::Matchers::CloseTo.new(1, 1) }
|
18
|
+
running_this.should_not raise_exception
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'when given a numeric as neither argument' do
|
23
|
+
it 'should raise an error' do
|
24
|
+
running_this = lambda { Ward::Matchers::CloseTo.new('', '') }
|
25
|
+
running_this.should raise_exception(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'when given a numeric as the first, but not second, argument' do
|
30
|
+
it 'should raise an error' do
|
31
|
+
running_this = lambda { Ward::Matchers::CloseTo.new(1, '') }
|
32
|
+
running_this.should raise_exception(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'when given a numeric as the second, but not first, argument' do
|
37
|
+
it 'should raise an error' do
|
38
|
+
running_this = lambda { Ward::Matchers::CloseTo.new('', 1) }
|
39
|
+
running_this.should raise_exception(ArgumentError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'when given only one argument' do
|
44
|
+
it 'should raise an error' do
|
45
|
+
running_this = lambda { Ward::Matchers::CloseTo.new(1) }
|
46
|
+
running_this.should raise_exception(ArgumentError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# matches?
|
53
|
+
#
|
54
|
+
|
55
|
+
# #matches? tests can be found in features/close_to_matcher.feature
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Matchers::EqualTo do
|
4
|
+
|
5
|
+
it 'should be registered with :equal_to' do
|
6
|
+
matcher = Ward::Matchers.matchers[:equal_to]
|
7
|
+
matcher.should == Ward::Matchers::EqualTo
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# matches?
|
12
|
+
#
|
13
|
+
|
14
|
+
# #matches? tests can be found in features/equal_to_matcher.feature
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Matchers::Has do
|
4
|
+
|
5
|
+
it 'should be registered with :has' do
|
6
|
+
matcher = Ward::Matchers.matchers[:has]
|
7
|
+
matcher.should == Ward::Matchers::Has
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should be registered with :have' do
|
11
|
+
matcher = Ward::Matchers.matchers[:have]
|
12
|
+
matcher.should == Ward::Matchers::Has
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Collections.
|
17
|
+
#
|
18
|
+
|
19
|
+
describe 'when setting a collection' do
|
20
|
+
before(:all) do
|
21
|
+
@matcher = Ward::Matchers::Has.new(1)
|
22
|
+
@return = @matcher.author
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return the matcher' do
|
26
|
+
@return.should == @matcher
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should set the collection name' do
|
30
|
+
@matcher.collection_name.should == :author
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Relativities.
|
36
|
+
#
|
37
|
+
|
38
|
+
[:lt, :less_than, :fewer_than].each do |method|
|
39
|
+
describe "##{method}" do
|
40
|
+
# lt sets the relativity to :lte, and decreases the expectation by
|
41
|
+
# such that is is within the :lte range.
|
42
|
+
before(:all) { @method, @relativity = method, :lte }
|
43
|
+
|
44
|
+
it_should_behave_like 'Has matcher relativity method'
|
45
|
+
|
46
|
+
it 'should set the expected value' do
|
47
|
+
@matcher.expected.should == 4
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
[:lte, :at_most].each do |method|
|
53
|
+
describe "##{method}" do
|
54
|
+
before(:all) { @method, @relativity = method, :lte }
|
55
|
+
|
56
|
+
it_should_behave_like 'Has matcher relativity method'
|
57
|
+
|
58
|
+
it 'should set the expected value' do
|
59
|
+
@matcher.expected.should == 5
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
[:eql, :exactly].each do |method|
|
65
|
+
describe "##{method}" do
|
66
|
+
before(:all) { @method, @relativity = method, :eql }
|
67
|
+
|
68
|
+
it_should_behave_like 'Has matcher relativity method'
|
69
|
+
|
70
|
+
it 'should set the expected value' do
|
71
|
+
@matcher.expected.should == 5
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
[:gte, :at_least].each do |method|
|
77
|
+
describe "##{method}" do
|
78
|
+
before(:all) { @method, @relativity = method, :gte }
|
79
|
+
|
80
|
+
it_should_behave_like 'Has matcher relativity method'
|
81
|
+
|
82
|
+
it 'should set the expected value' do
|
83
|
+
@matcher.expected.should == 5
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
[:gt, :greater_than, :more_than].each do |method|
|
89
|
+
# gt sets the relativity to :gte, and increases the expectation by 1 such
|
90
|
+
# that is is within the :gte range.
|
91
|
+
describe "##{method}" do
|
92
|
+
before(:all) { @method, @relativity = method, :gte }
|
93
|
+
|
94
|
+
it_should_behave_like 'Has matcher relativity method'
|
95
|
+
|
96
|
+
it 'should set the expected value' do
|
97
|
+
@matcher.expected.should == 6
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#between' do
|
103
|
+
before(:all) { @method, @relativity = :between, :between }
|
104
|
+
|
105
|
+
describe 'when given a range as the expectation' do
|
106
|
+
before(:all) { @expectation = [(1..5)] }
|
107
|
+
|
108
|
+
it_should_behave_like 'Has matcher relativity method'
|
109
|
+
|
110
|
+
it 'should set the expected value' do
|
111
|
+
@matcher.expected.should == (1..5)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'when given a two numerics as the expectation' do
|
116
|
+
before(:all) { @expectation = [1, 5] }
|
117
|
+
|
118
|
+
it_should_behave_like 'Has matcher relativity method'
|
119
|
+
|
120
|
+
it 'should set the expected value' do
|
121
|
+
@matcher.expected.should == (1..5)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should raise an error when given a single numeric' do
|
126
|
+
running_this = lambda { Ward::Matchers::Has.new.between(1) }
|
127
|
+
running_this.should raise_exception(ArgumentError, /upper boundary/)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should raise an error if setting a relativity when one is already set' do
|
132
|
+
matcher = Ward::Matchers::Has.new.at_least(1)
|
133
|
+
running_this = lambda { matcher.at_most(6) }
|
134
|
+
running_this.should raise_exception(RuntimeError, /already set/)
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# matches?
|
139
|
+
#
|
140
|
+
|
141
|
+
describe '#matches?' do
|
142
|
+
# Detailed #matches? tests can be found in features/has_matcher*.feature
|
143
|
+
|
144
|
+
it 'should raise an error if the collection is nil' do
|
145
|
+
matcher = Ward::Matchers::Has.new.eql(5)
|
146
|
+
|
147
|
+
running_this = lambda { matcher.should pass_matcher_with(nil) }
|
148
|
+
running_this.should raise_exception(RuntimeError, /not a collection/)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should call #length if available' do
|
152
|
+
actual = mock()
|
153
|
+
actual.should_receive(:length).once.and_return(5)
|
154
|
+
actual.should_not_receive(:size)
|
155
|
+
|
156
|
+
Ward::Matchers::Has.new.eql(5).should pass_matcher_with(actual)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should call #size if #length is not available' do
|
160
|
+
actual = mock()
|
161
|
+
actual.should_receive(:size).once.and_return(5)
|
162
|
+
|
163
|
+
Ward::Matchers::Has.new.eql(5).should pass_matcher_with(actual)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should raise an error if the collection does not respond to ' \
|
167
|
+
'#size or #length' do
|
168
|
+
matcher = Ward::Matchers::Has.new.eql(5)
|
169
|
+
|
170
|
+
running_this = lambda { matcher.should pass_matcher_with(mock()) }
|
171
|
+
running_this.should raise_exception(RuntimeError, /not a collection/)
|
172
|
+
end
|
173
|
+
end # matches?
|
174
|
+
|
175
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Ward::Matchers::Include do
|
4
|
+
|
5
|
+
it 'should be registered with :included_in' do
|
6
|
+
matcher = Ward::Matchers.matchers[:included_in]
|
7
|
+
matcher.should == Ward::Matchers::Include
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should be registered with :one_of' do
|
11
|
+
matcher = Ward::Matchers.matchers[:one_of]
|
12
|
+
matcher.should == Ward::Matchers::Include
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# initialize
|
17
|
+
#
|
18
|
+
|
19
|
+
describe '#initialize' do
|
20
|
+
describe 'when given an object which responds to #include?' do
|
21
|
+
it 'should not raise an error' do
|
22
|
+
running_this = lambda { Ward::Matchers::Include.new([]) }
|
23
|
+
running_this.should_not raise_exception
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'when given an object which does not respond to #include?' do
|
28
|
+
it 'should raise an ArgumentError' do
|
29
|
+
running_this = lambda { Ward::Matchers::Include.new(nil) }
|
30
|
+
running_this.should raise_exception(ArgumentError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# matches?
|
37
|
+
#
|
38
|
+
|
39
|
+
# #matches? tests can be found in features/include_matcher.feature
|
40
|
+
|
41
|
+
end
|