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,25 @@
|
|
1
|
+
Feature: EqualTo matcher
|
2
|
+
In order to validate that an exact value
|
3
|
+
I want to be able to use the equal_to matcher to set the expected value
|
4
|
+
|
5
|
+
#
|
6
|
+
# The equal_to keyword can often be removed in favour of using +is+ with a
|
7
|
+
# value. See is_keyword.feature for examples.
|
8
|
+
#
|
9
|
+
|
10
|
+
Background:
|
11
|
+
Given a class with an 'name' attribute
|
12
|
+
And using a validation set like
|
13
|
+
"""
|
14
|
+
object.name.is.equal_to('Michael Scarn')
|
15
|
+
|
16
|
+
"""
|
17
|
+
|
18
|
+
Scenario: When the attribute value matches the expected value
|
19
|
+
When the instance 'name' attribute is 'Michael Scarn'
|
20
|
+
Then the validation set should pass
|
21
|
+
|
22
|
+
Scenario: When the attribute value does not match the expected value
|
23
|
+
When the instance 'name' attribute is 'Michael Scott'
|
24
|
+
Then the validation set should fail
|
25
|
+
And the error on 'name' should be 'Name should be Michael Scarn'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
Feature: Error messages when a validation fails
|
2
|
+
In order to provide useful information when a validation fails
|
3
|
+
I want to be able to retrieve a list of nicely worded error messages
|
4
|
+
So that descriptive messages which describe the errors can be displayed
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a class with a 'name' attribute
|
8
|
+
|
9
|
+
Scenario: When validating an attribute of the object
|
10
|
+
When using a validation set like
|
11
|
+
"""
|
12
|
+
object.name.is.present
|
13
|
+
|
14
|
+
"""
|
15
|
+
When the instance 'name' attribute is ''
|
16
|
+
Then the error on 'name' should be 'Name should be present'
|
17
|
+
|
18
|
+
Scenario: When validating the object itself
|
19
|
+
When using a validation set like
|
20
|
+
"""
|
21
|
+
object.is_not.present
|
22
|
+
|
23
|
+
"""
|
24
|
+
Then the error on 'base' should be 'Should not be present'
|
25
|
+
|
26
|
+
Scenario: Interpolating extra values from the matcher
|
27
|
+
When using a validation set like
|
28
|
+
"""
|
29
|
+
object.name.has(1).character
|
30
|
+
|
31
|
+
"""
|
32
|
+
When the instance 'name' attribute is ''
|
33
|
+
Then the error on 'name' should be 'Name should have 1 character'
|
34
|
+
|
35
|
+
Scenario: When the matcher indicates a specific error key
|
36
|
+
When using a validation set like
|
37
|
+
"""
|
38
|
+
object.name.has.between(1..5).characters
|
39
|
+
|
40
|
+
"""
|
41
|
+
When the instance 'name' attribute is ''
|
42
|
+
Then the error on 'name' should be 'Name should have between 1 and 5 characters'
|
43
|
+
|
44
|
+
Scenario: Providing a custom error when the validation is defined
|
45
|
+
When using a validation set like
|
46
|
+
"""
|
47
|
+
object.name.is.present.message('Whoops!')
|
48
|
+
|
49
|
+
"""
|
50
|
+
When the instance 'name' attribute is ''
|
51
|
+
Then the error on 'name' should be 'Whoops!'
|
52
|
+
|
53
|
+
Scenario: Providing a custom error with interpolation
|
54
|
+
When using a validation set like
|
55
|
+
"""
|
56
|
+
object.name.is.present.message('%{context} had a whoopsie')
|
57
|
+
|
58
|
+
"""
|
59
|
+
When the instance 'name' attribute is ''
|
60
|
+
Then the error on 'name' should be 'Name had a whoopsie'
|
61
|
+
|
62
|
+
Scenario: Providing a custom name for the context
|
63
|
+
When using a validation set like
|
64
|
+
"""
|
65
|
+
object.name.is.present.context('you')
|
66
|
+
|
67
|
+
"""
|
68
|
+
When the instance 'name' attribute is ''
|
69
|
+
Then the error on 'name' should be 'You should be present'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Validating objects without "include"ing any modules
|
2
|
+
In order to reduce the impact on a user's environment
|
3
|
+
I want to be able to validate an object which knows nothing about Ward
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given a class with a 'name' attribute
|
7
|
+
When validating the 'name' attribute
|
8
|
+
|
9
|
+
Scenario: Passing validation
|
10
|
+
When the instance 'name' attribute is valid
|
11
|
+
Then the validation set should pass
|
12
|
+
|
13
|
+
Scenario: Failing validation
|
14
|
+
When the instance 'name' attribute is invalid
|
15
|
+
Then the validation set should fail
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Feature: Has matcher
|
2
|
+
In order to validate the length of a collection
|
3
|
+
I want to be able to ensure collections have a certain number of members
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given a class with a 'posts' attribute
|
7
|
+
|
8
|
+
Scenario: When validating with a collection name and the correct member size
|
9
|
+
When using a validation set like
|
10
|
+
"""
|
11
|
+
object.has(2).posts
|
12
|
+
|
13
|
+
"""
|
14
|
+
When the instance 'posts' attribute is '[1, 2]'
|
15
|
+
Then the validation set should pass
|
16
|
+
|
17
|
+
Scenario: When validating with a collection name and an incorrect member size
|
18
|
+
When using a validation set like
|
19
|
+
"""
|
20
|
+
object.has(2).posts
|
21
|
+
|
22
|
+
"""
|
23
|
+
When the instance 'posts' attribute is '[1]'
|
24
|
+
Then the validation set should fail
|
25
|
+
And the error on 'base' should be 'Should have 2 posts'
|
26
|
+
|
27
|
+
Scenario: When validating without a collection name and the correct member size
|
28
|
+
When using a validation set like
|
29
|
+
"""
|
30
|
+
object.posts.has(2)
|
31
|
+
|
32
|
+
"""
|
33
|
+
When the instance 'posts' attribute is '[1, 2]'
|
34
|
+
Then the validation set should pass
|
35
|
+
|
36
|
+
Scenario: When validating without a collection name and an incorrect member size
|
37
|
+
When using a validation set like
|
38
|
+
"""
|
39
|
+
object.posts.has(2)
|
40
|
+
|
41
|
+
"""
|
42
|
+
When the instance 'posts' attribute is '[1]'
|
43
|
+
Then the validation set should fail
|
44
|
+
And the error on 'posts' should be 'Posts should have 2 items'
|
45
|
+
|
46
|
+
Scenario: When validating without a non-responding collection name and the correct member size
|
47
|
+
When using a validation set like
|
48
|
+
"""
|
49
|
+
object.posts.has(2).members
|
50
|
+
|
51
|
+
"""
|
52
|
+
When the instance 'posts' attribute is '[1, 2]'
|
53
|
+
Then the validation set should pass
|
54
|
+
|
55
|
+
Scenario: When validating without a non-responding collection name and an incorrect member size
|
56
|
+
When using a validation set like
|
57
|
+
"""
|
58
|
+
object.posts.has(2).members
|
59
|
+
|
60
|
+
"""
|
61
|
+
When the instance 'posts' attribute is '[1]'
|
62
|
+
Then the validation set should fail
|
63
|
+
And the error on 'posts' should be 'Posts should have 2 members'
|
64
|
+
|
65
|
+
Scenario: When using a singular collection name and the value responds to the plural
|
66
|
+
When using a validation set like
|
67
|
+
"""
|
68
|
+
object.has(1).post
|
69
|
+
|
70
|
+
"""
|
71
|
+
When the instance 'posts' attribute is '[1]'
|
72
|
+
Then the validation set should pass
|
@@ -0,0 +1,94 @@
|
|
1
|
+
Feature: Has matcher when initialized with an expected length
|
2
|
+
In order allow the has matcher to read more like a natural language
|
3
|
+
I want to be able to initialize the matcher with an expectation
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given a class with a 'posts' attribute
|
7
|
+
|
8
|
+
Scenario: Initialized with an exact value and the correct member size
|
9
|
+
When using a validation set like
|
10
|
+
"""
|
11
|
+
object.has(2).posts
|
12
|
+
|
13
|
+
"""
|
14
|
+
When the instance 'posts' attribute is '[1, 2]'
|
15
|
+
Then the validation set should pass
|
16
|
+
|
17
|
+
Scenario: Initialized with an exact value and an incorrect member size
|
18
|
+
When using a validation set like
|
19
|
+
"""
|
20
|
+
object.has(2).posts
|
21
|
+
|
22
|
+
"""
|
23
|
+
When the instance 'posts' attribute is '[1]'
|
24
|
+
Then the validation set should fail
|
25
|
+
|
26
|
+
Scenario Outline: Initialized with no value and a member size > 0
|
27
|
+
When using a validation set like
|
28
|
+
"""
|
29
|
+
object.has.posts
|
30
|
+
|
31
|
+
"""
|
32
|
+
When the instance 'posts' attribute is '<posts>'
|
33
|
+
Then the validation set should pass
|
34
|
+
|
35
|
+
Examples:
|
36
|
+
| posts |
|
37
|
+
| [1] |
|
38
|
+
| [1, 2] |
|
39
|
+
|
40
|
+
Scenario: Initialized with no value and an incorrect member size
|
41
|
+
When using a validation set like
|
42
|
+
"""
|
43
|
+
object.has.posts
|
44
|
+
|
45
|
+
"""
|
46
|
+
When the instance 'posts' attribute is '[]'
|
47
|
+
Then the validation set should fail
|
48
|
+
|
49
|
+
Scenario: Initialized with :no and the correct member size
|
50
|
+
When using a validation set like
|
51
|
+
"""
|
52
|
+
object.has(:no).posts
|
53
|
+
|
54
|
+
"""
|
55
|
+
When the instance 'posts' attribute is '[]'
|
56
|
+
Then the validation set should pass
|
57
|
+
|
58
|
+
Scenario: Initialized with :no and an incorrect member size
|
59
|
+
When using a validation set like
|
60
|
+
"""
|
61
|
+
object.has(:no).posts
|
62
|
+
|
63
|
+
"""
|
64
|
+
When the instance 'posts' attribute is '[1]'
|
65
|
+
Then the validation set should fail
|
66
|
+
|
67
|
+
Scenario Outline: Initialized with a range and the correct member size
|
68
|
+
When using a validation set like
|
69
|
+
"""
|
70
|
+
object.has(2..3).posts
|
71
|
+
|
72
|
+
"""
|
73
|
+
When the instance 'posts' attribute is '<posts>'
|
74
|
+
Then the validation set should pass
|
75
|
+
|
76
|
+
Examples:
|
77
|
+
| posts |
|
78
|
+
| [1, 2] |
|
79
|
+
| [1, 2, 3] |
|
80
|
+
|
81
|
+
Scenario Outline: Initialized with a range and an incorrect member size
|
82
|
+
When using a validation set like
|
83
|
+
"""
|
84
|
+
object.has(2..3).posts
|
85
|
+
|
86
|
+
"""
|
87
|
+
When the instance 'posts' attribute is '<posts>'
|
88
|
+
Then the validation set should fail
|
89
|
+
|
90
|
+
Examples:
|
91
|
+
| posts |
|
92
|
+
| [] |
|
93
|
+
| [1] |
|
94
|
+
| [1, 2, 3, 4] |
|
@@ -0,0 +1,171 @@
|
|
1
|
+
Feature: Has matcher relativities
|
2
|
+
In order to validate collections whose length may vary
|
3
|
+
I want to be able to validate that it has a minimum or maximum length
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given a class with a 'name' attribute
|
7
|
+
|
8
|
+
#
|
9
|
+
# 'exactly' is aliased as 'eql' and can also be omitted completely. See
|
10
|
+
# has_matcher_with_initialized_expectation feature for examples.
|
11
|
+
#
|
12
|
+
|
13
|
+
Scenario: Passing validation with exactly
|
14
|
+
When using a validation set like
|
15
|
+
"""
|
16
|
+
object.name.has.exactly(5).characters
|
17
|
+
|
18
|
+
"""
|
19
|
+
When the instance 'name' attribute is 'Dwigt'
|
20
|
+
Then the validation set should pass
|
21
|
+
And there should be no validation errors
|
22
|
+
|
23
|
+
Scenario: Failing validation with exactly
|
24
|
+
When using a validation set like
|
25
|
+
"""
|
26
|
+
object.name.has.exactly(5).characters
|
27
|
+
|
28
|
+
"""
|
29
|
+
When the instance 'name' attribute is ''
|
30
|
+
Then the validation set should fail
|
31
|
+
And the error on 'name' should be 'Name should have 5 characters'
|
32
|
+
|
33
|
+
#
|
34
|
+
# 'fewer_than' is aliased as 'lt' and 'less_than'
|
35
|
+
#
|
36
|
+
|
37
|
+
Scenario: Passing validation with lte
|
38
|
+
When using a validation set like
|
39
|
+
"""
|
40
|
+
object.name.has.fewer_than(6).characters
|
41
|
+
|
42
|
+
"""
|
43
|
+
When the instance 'name' attribute is 'Dwigt'
|
44
|
+
Then the validation set should pass
|
45
|
+
And there should be no validation errors
|
46
|
+
|
47
|
+
Scenario: Failing validation with lte
|
48
|
+
When using a validation set like
|
49
|
+
"""
|
50
|
+
object.name.has.fewer_than(6).characters
|
51
|
+
|
52
|
+
"""
|
53
|
+
When the instance 'name' attribute is 'abcdef'
|
54
|
+
Then the validation set should fail
|
55
|
+
And the error on 'name' should be 'Name should have at most 5 characters'
|
56
|
+
|
57
|
+
#
|
58
|
+
# 'at_most' is aliased as 'lte'
|
59
|
+
#
|
60
|
+
|
61
|
+
Scenario: Passing validation with lte
|
62
|
+
When using a validation set like
|
63
|
+
"""
|
64
|
+
object.name.has.at_most(5).characters
|
65
|
+
|
66
|
+
"""
|
67
|
+
When the instance 'name' attribute is 'Dwigt'
|
68
|
+
Then the validation set should pass
|
69
|
+
And there should be no validation errors
|
70
|
+
|
71
|
+
Scenario: Failing validation with lte
|
72
|
+
When using a validation set like
|
73
|
+
"""
|
74
|
+
object.name.has.at_most(5).characters
|
75
|
+
|
76
|
+
"""
|
77
|
+
When the instance 'name' attribute is 'abcdef'
|
78
|
+
Then the validation set should fail
|
79
|
+
And the error on 'name' should be 'Name should have at most 5 characters'
|
80
|
+
|
81
|
+
#
|
82
|
+
# 'at_least' is aliased as 'gte'
|
83
|
+
#
|
84
|
+
|
85
|
+
Scenario: Passing validation with gte
|
86
|
+
When using a validation set like
|
87
|
+
"""
|
88
|
+
object.name.has.at_least(5).characters
|
89
|
+
|
90
|
+
"""
|
91
|
+
When the instance 'name' attribute is 'Dwigt'
|
92
|
+
Then the validation set should pass
|
93
|
+
And there should be no validation errors
|
94
|
+
|
95
|
+
Scenario: Failing validation with gte
|
96
|
+
When using a validation set like
|
97
|
+
"""
|
98
|
+
object.name.has.at_least(5).characters
|
99
|
+
|
100
|
+
"""
|
101
|
+
When the instance 'name' attribute is ''
|
102
|
+
Then the validation set should fail
|
103
|
+
And the error on 'name' should be 'Name should have at least 5 characters'
|
104
|
+
|
105
|
+
#
|
106
|
+
# 'greater_than' is aliased as 'gt' and 'more_than'
|
107
|
+
#
|
108
|
+
|
109
|
+
Scenario: Passing validation with gte
|
110
|
+
When using a validation set like
|
111
|
+
"""
|
112
|
+
object.name.has.greater_than(4).characters
|
113
|
+
|
114
|
+
"""
|
115
|
+
When the instance 'name' attribute is 'Dwigt'
|
116
|
+
Then the validation set should pass
|
117
|
+
And there should be no validation errors
|
118
|
+
|
119
|
+
Scenario: Failing validation with gte
|
120
|
+
When using a validation set like
|
121
|
+
"""
|
122
|
+
object.name.has.greater_than(4).characters
|
123
|
+
|
124
|
+
"""
|
125
|
+
When the instance 'name' attribute is 'abcd'
|
126
|
+
Then the validation set should fail
|
127
|
+
And the error on 'name' should be 'Name should have at least 5 characters'
|
128
|
+
|
129
|
+
#
|
130
|
+
# between
|
131
|
+
#
|
132
|
+
|
133
|
+
Scenario: Passing validation with between and a range
|
134
|
+
When using a validation set like
|
135
|
+
"""
|
136
|
+
object.name.has.between(2..5).characters
|
137
|
+
|
138
|
+
"""
|
139
|
+
When the instance 'name' attribute is 'Dwigt'
|
140
|
+
Then the validation set should pass
|
141
|
+
And there should be no validation errors
|
142
|
+
|
143
|
+
Scenario: Failing validation with between two values and a range
|
144
|
+
When using a validation set like
|
145
|
+
"""
|
146
|
+
object.name.has.between(2..5).characters
|
147
|
+
|
148
|
+
"""
|
149
|
+
When the instance 'name' attribute is ''
|
150
|
+
Then the validation set should fail
|
151
|
+
And the error on 'name' should be 'Name should have between 2 and 5 characters'
|
152
|
+
|
153
|
+
Scenario: Passing validation with between and two values
|
154
|
+
When using a validation set like
|
155
|
+
"""
|
156
|
+
object.name.has.between(2, 5).characters
|
157
|
+
|
158
|
+
"""
|
159
|
+
When the instance 'name' attribute is 'Dwigt'
|
160
|
+
Then the validation set should pass
|
161
|
+
And there should be no validation errors
|
162
|
+
|
163
|
+
Scenario: Failing validation with between and two values
|
164
|
+
When using a validation set like
|
165
|
+
"""
|
166
|
+
object.name.has.between(2, 5).characters
|
167
|
+
|
168
|
+
"""
|
169
|
+
When the instance 'name' attribute is ''
|
170
|
+
Then the validation set should fail
|
171
|
+
And the error on 'name' should be 'Name should have between 2 and 5 characters'
|