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.
Files changed (92) hide show
  1. data/.document +5 -0
  2. data/.gitignore +28 -0
  3. data/LICENSE +19 -0
  4. data/README.markdown +99 -0
  5. data/Rakefile +47 -0
  6. data/VERSION +1 -0
  7. data/features/acceptance_matcher.feature +78 -0
  8. data/features/attribute_keyword.feature +13 -0
  9. data/features/close_to_matcher.feature +130 -0
  10. data/features/context_arguments.feature +47 -0
  11. data/features/equal_to_matcher.feature +25 -0
  12. data/features/error_messages.feature +69 -0
  13. data/features/external_validation.feature +15 -0
  14. data/features/has_matcher.feature +72 -0
  15. data/features/has_matcher_initialized_with_expectation.feature +94 -0
  16. data/features/has_matcher_relativities.feature +171 -0
  17. data/features/include_matcher.feature +28 -0
  18. data/features/is_keyword.feature +42 -0
  19. data/features/is_not_keyword.feature +62 -0
  20. data/features/match_matcher.feature +49 -0
  21. data/features/multiple_validators.feature +29 -0
  22. data/features/nil_matcher.feature +25 -0
  23. data/features/predicate_matcher.feature +23 -0
  24. data/features/present_matcher.feature +59 -0
  25. data/features/satisfy_matcher.feature +80 -0
  26. data/features/scenario_validation.feature +81 -0
  27. data/features/step_definitions/external_validation_steps.rb +69 -0
  28. data/features/step_definitions/generic_validation_steps.rb +33 -0
  29. data/features/step_definitions/object_definition_steps.rb +43 -0
  30. data/features/support/env.rb +12 -0
  31. data/features/support/object_builder.rb +33 -0
  32. data/features/support/struct.rb +38 -0
  33. data/lang/en.yml +56 -0
  34. data/lib/ward.rb +26 -0
  35. data/lib/ward/context.rb +70 -0
  36. data/lib/ward/context_chain.rb +87 -0
  37. data/lib/ward/dsl.rb +7 -0
  38. data/lib/ward/dsl/validation_block.rb +73 -0
  39. data/lib/ward/dsl/validation_builder.rb +190 -0
  40. data/lib/ward/errors.rb +213 -0
  41. data/lib/ward/matchers.rb +97 -0
  42. data/lib/ward/matchers/acceptance.rb +43 -0
  43. data/lib/ward/matchers/close_to.rb +60 -0
  44. data/lib/ward/matchers/equal_to.rb +33 -0
  45. data/lib/ward/matchers/has.rb +283 -0
  46. data/lib/ward/matchers/include.rb +54 -0
  47. data/lib/ward/matchers/match.rb +29 -0
  48. data/lib/ward/matchers/matcher.rb +68 -0
  49. data/lib/ward/matchers/nil.rb +30 -0
  50. data/lib/ward/matchers/predicate.rb +31 -0
  51. data/lib/ward/matchers/present.rb +56 -0
  52. data/lib/ward/matchers/satisfy.rb +65 -0
  53. data/lib/ward/spec.rb +17 -0
  54. data/lib/ward/spec/matcher_matcher.rb +114 -0
  55. data/lib/ward/support.rb +7 -0
  56. data/lib/ward/support/basic_object.rb +55 -0
  57. data/lib/ward/support/result.rb +49 -0
  58. data/lib/ward/validator.rb +147 -0
  59. data/lib/ward/validator_set.rb +115 -0
  60. data/lib/ward/version.rb +3 -0
  61. data/spec/lib/has_matcher_relativity_examples.rb +15 -0
  62. data/spec/lib/have_public_method_defined.rb +22 -0
  63. data/spec/rcov.opts +8 -0
  64. data/spec/spec.opts +4 -0
  65. data/spec/spec_helper.rb +19 -0
  66. data/spec/ward/context_chain_spec.rb +178 -0
  67. data/spec/ward/context_spec.rb +57 -0
  68. data/spec/ward/dsl/validation_block_spec.rb +27 -0
  69. data/spec/ward/dsl/validation_builder_spec.rb +212 -0
  70. data/spec/ward/errors_spec.rb +149 -0
  71. data/spec/ward/matchers/acceptance_spec.rb +16 -0
  72. data/spec/ward/matchers/close_to_spec.rb +57 -0
  73. data/spec/ward/matchers/equal_to_spec.rb +16 -0
  74. data/spec/ward/matchers/has_spec.rb +175 -0
  75. data/spec/ward/matchers/include_spec.rb +41 -0
  76. data/spec/ward/matchers/match_spec.rb +21 -0
  77. data/spec/ward/matchers/matcher_spec.rb +54 -0
  78. data/spec/ward/matchers/nil_spec.rb +16 -0
  79. data/spec/ward/matchers/predicate_spec.rb +19 -0
  80. data/spec/ward/matchers/present_spec.rb +16 -0
  81. data/spec/ward/matchers/satisfy_spec.rb +68 -0
  82. data/spec/ward/matchers_spec.rb +51 -0
  83. data/spec/ward/spec/have_public_method_defined_spec.rb +31 -0
  84. data/spec/ward/spec/matcher_matcher_spec.rb +217 -0
  85. data/spec/ward/validator_set_spec.rb +178 -0
  86. data/spec/ward/validator_spec.rb +264 -0
  87. data/tasks/features.rake +15 -0
  88. data/tasks/rcov.rake +24 -0
  89. data/tasks/spec.rake +18 -0
  90. data/tasks/yard.rake +9 -0
  91. data/ward.gemspec +176 -0
  92. metadata +239 -0
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Match do
4
+
5
+ it 'should be registered with :matches' do
6
+ matcher = Ward::Matchers.matchers[:matches]
7
+ matcher.should == Ward::Matchers::Match
8
+ end
9
+
10
+ it 'should be registered with :match' do
11
+ matcher = Ward::Matchers.matchers[:match]
12
+ matcher.should == Ward::Matchers::Match
13
+ end
14
+
15
+ #
16
+ # matches?
17
+ #
18
+
19
+ # #matches? tests can be found in features/match_matcher.feature
20
+
21
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Matcher do
4
+ subject { Ward::Matchers::Matcher }
5
+
6
+ it { should have_public_method_defined(:extra_args) }
7
+
8
+ #
9
+ # initialize
10
+ #
11
+
12
+ describe '#initialize' do
13
+ it 'should not require an argument' do
14
+ lambda { Ward::Matchers::Matcher.new }.should_not raise_exception
15
+ end
16
+
17
+ it 'should store extra arguments' do
18
+ Ward::Matchers::Matcher.new(1, 2, 3).extra_args.should == [2, 3]
19
+ end
20
+ end
21
+
22
+ #
23
+ # expected
24
+ #
25
+
26
+ it { should have_public_method_defined(:expected) }
27
+
28
+ describe '#expected' do
29
+ before(:each) do
30
+ @matcher = Ward::Matchers::Matcher.new(1)
31
+ end
32
+
33
+ it 'should return the expected value' do
34
+ @matcher.expected.should == 1
35
+ end
36
+ end
37
+
38
+ #
39
+ # matches?
40
+ #
41
+
42
+ it { should have_public_method_defined(:matches?) }
43
+
44
+ describe '#matches?' do
45
+ before(:each) do
46
+ @matcher = Ward::Matchers::Matcher.new(1)
47
+ end
48
+
49
+ it 'should pass' do
50
+ @matcher.matches?(nil).should be_true
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Nil do
4
+
5
+ it 'should be registered with :nil' do
6
+ matcher = Ward::Matchers.matchers[:nil]
7
+ matcher.should == Ward::Matchers::Nil
8
+ end
9
+
10
+ #
11
+ # matches?
12
+ #
13
+
14
+ # #matches? tests can be found in features/nil_matcher.feature
15
+
16
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Predicate do
4
+
5
+ #
6
+ # matches?
7
+ #
8
+
9
+ # #matches? tests can be found in features/present_matcher.feature
10
+
11
+ describe '#matches?' do
12
+ it "should raise an error if the actual value doesn't respond to the method" do
13
+ matcher = Ward::Matchers::Predicate.new(:important?)
14
+ running = lambda { matcher.matches?(nil) }
15
+ running.should raise_error(ArgumentError, /does not respond/)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Present do
4
+
5
+ it 'should be registered with :present' do
6
+ matcher = Ward::Matchers.matchers[:present]
7
+ matcher.should == Ward::Matchers::Present
8
+ end
9
+
10
+ #
11
+ # matches?
12
+ #
13
+
14
+ # #matches? tests can be found in features/present_matcher.feature
15
+
16
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers::Satisfy do
4
+
5
+ it 'should be registered with :satisfies' do
6
+ matcher = Ward::Matchers.matchers[:satisfies]
7
+ matcher.should == Ward::Matchers::Satisfy
8
+ end
9
+
10
+ it 'should be registered with :satisfy' do
11
+ matcher = Ward::Matchers.matchers[:satisfy]
12
+ matcher.should == Ward::Matchers::Satisfy
13
+ end
14
+
15
+ #
16
+ # block arguments
17
+ #
18
+
19
+ describe 'when the given block accepts no arguments' do
20
+ it 'should supply nothing to to the block' do
21
+ running = lambda { Ward::Matchers::Satisfy.new {}.matches?('nil') }
22
+ running.should_not raise_error
23
+ end
24
+ end
25
+
26
+ describe 'when the given block accepts one argument' do
27
+ it 'should supply the attribute value to to the block' do
28
+ Ward::Matchers::Satisfy.new do |value|
29
+ value.should == 'Rincewind'
30
+ end.matches?('Rincewind')
31
+ end
32
+ end
33
+
34
+ describe 'when the given block accepts two arguments' do
35
+ it 'should supply the attribute value to to the block' do
36
+ Ward::Matchers::Satisfy.new do |value, record|
37
+ value.should == 'Rincewind'
38
+ end.matches?('Rincewind')
39
+ end
40
+
41
+ it 'should supply the record instance to to the block' do
42
+ Ward::Matchers::Satisfy.new do |value, record|
43
+ record.should == 'Discworld'
44
+ end.matches?('Rincewind', 'Discworld')
45
+ end
46
+ end
47
+
48
+ describe 'when the given block accepts a splat argument' do
49
+ it 'should supply the attribute value to the block' do
50
+ Ward::Matchers::Satisfy.new do |*args|
51
+ args.first.should == 'Rincewind'
52
+ end.matches?('Rincewind', 'Discworld')
53
+ end
54
+
55
+ it 'should supply the record instance to the block' do
56
+ Ward::Matchers::Satisfy.new do |*args|
57
+ args.last.should == 'Discworld'
58
+ end.matches?('Rincewind', 'Discworld')
59
+ end
60
+ end
61
+
62
+ #
63
+ # matches?
64
+ #
65
+
66
+ # #matches? tests can be found in features/satisfy_matcher.feature
67
+
68
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Ward::Matchers do
4
+ subject { Ward::Matchers }
5
+
6
+ #
7
+ # matchers
8
+ #
9
+
10
+ it { should respond_to(:matchers) }
11
+
12
+ describe '#matchers' do
13
+ it 'should return a Hash' do
14
+ Ward::Matchers.matchers.should be_a(Hash)
15
+ end
16
+ end
17
+
18
+ #
19
+ # register
20
+ #
21
+
22
+ it { should respond_to(:register) }
23
+
24
+ describe '#register' do
25
+ before(:all) do
26
+ class ::TestMatcher < Ward::Matchers::Matcher ; end
27
+ class ::TestMatcher2 < Ward::Matchers::Matcher ; end
28
+ end
29
+
30
+ it 'should register the Matcher with the given slug' do
31
+ Ward::Matchers.matchers.should_not have_key(:__test_matcher__)
32
+ Ward::Matchers.matchers.should_not have_value(::TestMatcher)
33
+ Ward::Matchers.register(:__test_matcher__, ::TestMatcher)
34
+ Ward::Matchers.matchers[:__test_matcher__].should == ::TestMatcher
35
+ end
36
+
37
+ it 'should overwrite an existing registration' do
38
+ Ward::Matchers.register(:__test_matcher__, ::TestMatcher)
39
+ Ward::Matchers.register(:__test_matcher__, ::TestMatcher2)
40
+ Ward::Matchers.matchers[:__test_matcher__].should == ::TestMatcher2
41
+ end
42
+
43
+ it 'should permit registration multiple times with different slugs' do
44
+ Ward::Matchers.register(:__test_matcher__, ::TestMatcher)
45
+ Ward::Matchers.register(:__another_test_matcher__, ::TestMatcher)
46
+ Ward::Matchers.matchers[:__test_matcher__].should == ::TestMatcher
47
+ Ward::Matchers.matchers[:__another_test_matcher__].should == ::TestMatcher
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'have_public_method_defined matcher' do
4
+ before(:all) do
5
+ @exception = Spec::Expectations::ExpectationNotMetError
6
+ end
7
+
8
+ describe 'with should' do
9
+ it 'should pass when the method is defined' do
10
+ running = lambda { String.should have_public_method_defined(:length) }
11
+ running.should_not raise_exception(@exception)
12
+ end
13
+
14
+ it 'should fail when the method is not defined' do
15
+ running = lambda { String.should have_public_method_defined(:__invalid__) }
16
+ running.should raise_exception(@exception)
17
+ end
18
+ end
19
+
20
+ describe 'with should_not' do
21
+ it 'should fail when the method is defined' do
22
+ running = lambda { String.should_not have_public_method_defined(:length) }
23
+ running.should raise_exception(@exception)
24
+ end
25
+
26
+ it 'should pass when the method is not defined' do
27
+ running = lambda { String.should_not have_public_method_defined(:__invalid__) }
28
+ running.should_not raise_exception(@exception)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,217 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe "Ward RSpec matcher" do
4
+
5
+ before(:each) do
6
+ @exception = Spec::Expectations::ExpectationNotMetError
7
+ @matcher = Object.new
8
+ @matcher.stub!(:expected).and_return('')
9
+ end
10
+
11
+ describe 'pass_matcher_with' do
12
+ describe 'with "should"' do
13
+ it 'should pass when the matcher returns true' do
14
+ @matcher.should_receive(:matches?).and_return(true)
15
+
16
+ running = lambda { @matcher.should pass_matcher_with('') }
17
+ running.should_not raise_exception(@exception)
18
+ end
19
+
20
+ it 'should pass when the matcher returns an arbitrary object' do
21
+ @matcher.should_receive(:matches?).and_return(Object.new)
22
+
23
+ running = lambda { @matcher.should pass_matcher_with('') }
24
+ running.should_not raise_exception(@exception)
25
+ end
26
+
27
+ it 'should fail when the matcher returns false' do
28
+ @matcher.should_receive(:matches?).and_return(false)
29
+
30
+ running = lambda { @matcher.should pass_matcher_with('') }
31
+ running.should raise_exception(@exception)
32
+ end
33
+
34
+ it 'should fail when the matcher returns [false, ...]' do
35
+ @matcher.should_receive(:matches?).and_return([false])
36
+
37
+ running = lambda { @matcher.should pass_matcher_with('') }
38
+ running.should raise_exception(@exception)
39
+ end
40
+
41
+ it 'should fail when the matcher returns nil' do
42
+ @matcher.should_receive(:matches?).and_return(nil)
43
+
44
+ running = lambda { @matcher.should pass_matcher_with('') }
45
+ running.should raise_exception(@exception)
46
+ end
47
+
48
+ it 'should fail when the matcher returns [nil, ...]' do
49
+ @matcher.should_receive(:matches?).and_return([nil])
50
+
51
+ running = lambda { @matcher.should pass_matcher_with('') }
52
+ running.should raise_exception(@exception)
53
+ end
54
+
55
+ end # with "should"
56
+
57
+ describe 'with "should_not"' do
58
+ it 'should fail when the matcher returns true' do
59
+ @matcher.should_receive(:matches?).and_return(true)
60
+
61
+ running = lambda { @matcher.should_not pass_matcher_with('') }
62
+ running.should raise_exception(@exception)
63
+ end
64
+
65
+ it 'should fail when the matcher returns an arbitrary object' do
66
+ @matcher.should_receive(:matches?).and_return(Object.new)
67
+
68
+ running = lambda { @matcher.should_not pass_matcher_with('') }
69
+ running.should raise_exception(@exception)
70
+ end
71
+
72
+ it 'should pass when the matcher returns false' do
73
+ @matcher.should_receive(:matches?).and_return(false)
74
+
75
+ running = lambda { @matcher.should_not pass_matcher_with('') }
76
+ running.should_not raise_exception(@exception)
77
+ end
78
+
79
+ it 'should pass when the matcher returns [false, ...]' do
80
+ @matcher.should_receive(:matches?).and_return([false])
81
+
82
+ running = lambda { @matcher.should_not pass_matcher_with('') }
83
+ running.should_not raise_exception(@exception)
84
+ end
85
+
86
+ it 'should pass when the matcher returns nil' do
87
+ @matcher.should_receive(:matches?).and_return(nil)
88
+
89
+ running = lambda { @matcher.should_not pass_matcher_with('') }
90
+ running.should_not raise_exception(@exception)
91
+ end
92
+
93
+ it 'should pass when the matcher returns [nil, ...]' do
94
+ @matcher.should_receive(:matches?).and_return([nil])
95
+
96
+ running = lambda { @matcher.should_not pass_matcher_with('') }
97
+ running.should_not raise_exception(@exception)
98
+ end
99
+
100
+ end # with "should_not"
101
+ end # pass_matcher_with
102
+
103
+ describe 'fail_matcher_with' do
104
+ describe 'with no error expectation' do
105
+ describe 'with "should"' do
106
+ it 'should fail when the matcher returns true' do
107
+ @matcher.should_receive(:matches?).and_return(true)
108
+
109
+ running = lambda { @matcher.should fail_matcher_with('') }
110
+ running.should raise_exception(@exception)
111
+ end
112
+
113
+ it 'should fail when the matcher returns an arbitrary object' do
114
+ @matcher.should_receive(:matches?).and_return(Object.new)
115
+
116
+ running = lambda { @matcher.should fail_matcher_with('') }
117
+ running.should raise_exception(@exception)
118
+ end
119
+
120
+ it 'should pass when the matcher returns false' do
121
+ @matcher.should_receive(:matches?).and_return(false)
122
+
123
+ running = lambda { @matcher.should fail_matcher_with('') }
124
+ running.should_not raise_exception(@exception)
125
+ end
126
+
127
+ it 'should pass when the matcher returns [false, ...]' do
128
+ @matcher.should_receive(:matches?).and_return([false])
129
+
130
+ running = lambda { @matcher.should fail_matcher_with('') }
131
+ running.should_not raise_exception(@exception)
132
+ end
133
+
134
+ it 'should pass when the matcher returns nil' do
135
+ @matcher.should_receive(:matches?).and_return([nil])
136
+
137
+ running = lambda { @matcher.should fail_matcher_with('') }
138
+ running.should_not raise_exception(@exception)
139
+ end
140
+
141
+ it 'should pass when the matcher returns [nil, ...]' do
142
+ @matcher.should_receive(:matches?).and_return([nil])
143
+
144
+ running = lambda { @matcher.should fail_matcher_with('') }
145
+ running.should_not raise_exception(@exception)
146
+ end
147
+ end # with "should"
148
+
149
+ describe 'with "should_not"' do
150
+ it 'should pass when the matcher returns true' do
151
+ @matcher.should_receive(:matches?).and_return(true)
152
+
153
+ running = lambda { @matcher.should_not fail_matcher_with('') }
154
+ running.should_not raise_exception(@exception)
155
+ end
156
+
157
+ it 'should pass when the matcher returns an arbitrary object' do
158
+ @matcher.should_receive(:matches?).and_return(Object.new)
159
+
160
+ running = lambda { @matcher.should_not fail_matcher_with('') }
161
+ running.should_not raise_exception(@exception)
162
+ end
163
+
164
+ it 'should fail when the matcher returns false' do
165
+ @matcher.should_receive(:matches?).and_return(false)
166
+
167
+ running = lambda { @matcher.should_not fail_matcher_with('') }
168
+ running.should raise_exception(@exception)
169
+ end
170
+
171
+ it 'should fail when the matcher returns [false, ...]' do
172
+ @matcher.should_receive(:matches?).and_return([false])
173
+
174
+ running = lambda { @matcher.should_not fail_matcher_with('') }
175
+ running.should raise_exception(@exception)
176
+ end
177
+
178
+ it 'should fail when the matcher returns nil' do
179
+ @matcher.should_receive(:matches?).and_return(nil)
180
+
181
+ running = lambda { @matcher.should_not fail_matcher_with('') }
182
+ running.should raise_exception(@exception)
183
+ end
184
+
185
+ it 'should fail when the matcher returns [nil, ...]' do
186
+ @matcher.should_receive(:matches?).and_return([nil])
187
+
188
+ running = lambda { @matcher.should_not fail_matcher_with('') }
189
+ running.should raise_exception(@exception)
190
+ end
191
+ end # with "should_not"
192
+ end # with no error expectation
193
+
194
+ describe 'with an error expectation' do
195
+ it 'should pass when the actual error matches the expected error' do
196
+ @matcher.should_receive(:matches?).and_return([false, :e])
197
+
198
+ running = lambda {
199
+ @matcher.should fail_matcher_with('').with_error(:e)
200
+ }
201
+
202
+ running.should_not raise_exception(@exception)
203
+ end
204
+
205
+ it 'should fail when the actual error does not match the expected error' do
206
+ @matcher.should_receive(:matches?).and_return([false, :e])
207
+
208
+ running = lambda {
209
+ @matcher.should fail_matcher_with('').with_error(:whoops)
210
+ }
211
+
212
+ running.should raise_exception(@exception)
213
+ end
214
+ end # with an error expectation
215
+ end # fail_matcher_with
216
+
217
+ end