ward 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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