attestor 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/README.md +69 -55
  4. data/config/metrics/rubocop.yml +4 -0
  5. data/lib/attestor/invalid_error.rb +1 -12
  6. data/lib/attestor/policy/and.rb +2 -19
  7. data/lib/attestor/policy/negator.rb +2 -29
  8. data/lib/attestor/policy/node.rb +7 -33
  9. data/lib/attestor/policy/not.rb +2 -27
  10. data/lib/attestor/policy/or.rb +2 -19
  11. data/lib/attestor/policy/xor.rb +2 -19
  12. data/lib/attestor/policy.rb +0 -18
  13. data/lib/attestor/report.rb +51 -0
  14. data/lib/attestor/validations/delegator.rb +3 -18
  15. data/lib/attestor/validations/message.rb +1 -16
  16. data/lib/attestor/validations/reporter.rb +21 -0
  17. data/lib/attestor/validations/validator.rb +4 -63
  18. data/lib/attestor/validations/validators.rb +13 -41
  19. data/lib/attestor/validations.rb +12 -1
  20. data/lib/attestor/version.rb +1 -1
  21. data/lib/attestor.rb +2 -0
  22. data/spec/features/example_spec.rb +5 -5
  23. data/spec/support/policies.rb +5 -5
  24. data/spec/tests/policy/and_spec.rb +2 -2
  25. data/spec/tests/policy/node_spec.rb +9 -9
  26. data/spec/tests/policy/not_spec.rb +2 -2
  27. data/spec/tests/policy/or_spec.rb +2 -2
  28. data/spec/tests/policy/xor_spec.rb +2 -2
  29. data/spec/tests/policy_spec.rb +0 -48
  30. data/spec/tests/report_spec.rb +106 -0
  31. data/spec/tests/validations/delegator_spec.rb +6 -6
  32. data/spec/tests/validations/message_spec.rb +1 -1
  33. data/spec/tests/validations/reporter_spec.rb +47 -0
  34. data/spec/tests/validations/validator_spec.rb +56 -74
  35. data/spec/tests/validations/validators_spec.rb +81 -4
  36. data/spec/tests/validations_spec.rb +98 -10
  37. metadata +9 -3
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ require "support/policies"
4
+
5
+ describe Attestor::Validations::Reporter do
6
+
7
+ let(:object) { double }
8
+ let(:error) { Attestor::InvalidError.new object, ["foo"] }
9
+ let(:report) { Attestor::Report }
10
+ let(:test_class) { Class.new.send(:include, described_class) }
11
+
12
+ subject { test_class.new }
13
+
14
+ describe "#validate" do
15
+
16
+ let(:result) { subject.validate object }
17
+
18
+ context "when #validate! fails" do
19
+
20
+ before do
21
+ allow(subject).to receive(:validate!).with(object) { fail(error) }
22
+ end
23
+
24
+ it "returns an invalid report" do
25
+ expect(result).to be_kind_of report
26
+ expect(result.object).to eq object
27
+ expect(result.error).not_to be_nil
28
+ expect(result.messages).to eq error.messages
29
+ end
30
+
31
+ end # context
32
+
33
+ context "when #validate! passes" do
34
+
35
+ before { allow(subject).to receive(:validate!).with(object) }
36
+
37
+ it "returns a valid report" do
38
+ expect(result).to be_kind_of report
39
+ expect(result.object).to eq object
40
+ expect(result.error).to be_nil
41
+ end
42
+
43
+ end # context
44
+
45
+ end # describe #validate
46
+
47
+ end # describe Attestor::Validations::Reporter
@@ -4,6 +4,7 @@ require "support/policies"
4
4
 
5
5
  describe Attestor::Validations::Validator do
6
6
 
7
+ let(:reporter_module) { Attestor::Validations::Reporter }
7
8
  subject { described_class.new "foo" }
8
9
 
9
10
  describe ".new" do
@@ -12,32 +13,6 @@ describe Attestor::Validations::Validator do
12
13
  expect(subject).to be_frozen
13
14
  end
14
15
 
15
- it "accepts item option :except" do
16
- expect { described_class.new "foo", except: :bar }.not_to raise_error
17
- end
18
-
19
- it "accepts array option :except" do
20
- expect { described_class.new "foo", except: %w(bar) }.not_to raise_error
21
- end
22
-
23
- it "ignores repetitive :except items" do
24
- expect(described_class.new "foo", except: %i(bar bar))
25
- .to eq(described_class.new "foo", except: %i(bar))
26
- end
27
-
28
- it "accepts item option :only" do
29
- expect { described_class.new "foo", only: :bar }.not_to raise_error
30
- end
31
-
32
- it "accepts array option :only" do
33
- expect { described_class.new "foo", only: %w(bar) }.not_to raise_error
34
- end
35
-
36
- it "ignores repetitive :only items" do
37
- expect(described_class.new "foo", only: %i(bar bar))
38
- .to eq(described_class.new "foo", only: %i(bar))
39
- end
40
-
41
16
  end # describe .new
42
17
 
43
18
  describe "#name" do
@@ -52,66 +27,65 @@ describe Attestor::Validations::Validator do
52
27
 
53
28
  end # describe .name
54
29
 
55
- describe "#==" do
30
+ describe "#whitelist" do
56
31
 
57
- subject { described_class.new :foo, except: [:foo], only: %i(bar) }
58
-
59
- context "item with the same arguments" do
60
-
61
- let(:other) { described_class.new :foo, except: %i(foo), only: %i(bar) }
62
-
63
- it "returns true" do
64
- expect(subject == other).to eq true
65
- expect(subject).to eq other
66
- end
67
-
68
- end # context
69
-
70
- context "item with another name" do
71
-
72
- let(:other) { described_class.new :baz, except: %i(foo), only: %i(bar) }
73
-
74
- it "returns false" do
75
- expect(subject == other).to eq false
76
- expect(subject).not_to eq other
77
- end
32
+ it "returns an empty array by default" do
33
+ expect(subject.whitelist).to eq []
34
+ end
78
35
 
79
- end # context
36
+ it "is initialized" do
37
+ subject = described_class.new("foo", only: :bar)
38
+ expect(subject.whitelist).to eq [:bar]
39
+ end
80
40
 
81
- context "item with another blacklist" do
41
+ it "is symbolized" do
42
+ subject = described_class.new("foo", only: %w(bar baz))
43
+ expect(subject.whitelist).to eq [:bar, :baz]
44
+ end
82
45
 
83
- let(:other) { described_class.new :foo, except: %i(baz), only: %i(bar) }
46
+ it "contains unique items" do
47
+ subject = described_class.new("foo", only: %i(bar bar))
48
+ expect(subject.whitelist).to eq [:bar]
49
+ end
84
50
 
85
- it "returns false" do
86
- expect(subject == other).to eq false
87
- expect(subject).not_to eq other
88
- end
51
+ end # describe .whitelist
89
52
 
90
- end # context
53
+ describe "#blacklist" do
91
54
 
92
- context "item with another whitelist" do
55
+ it "returns an empty array by default" do
56
+ expect(subject.blacklist).to eq []
57
+ end
93
58
 
94
- let(:other) { described_class.new :foo, except: %i(foo), only: %i(baz) }
59
+ it "is initialized" do
60
+ subject = described_class.new("foo", except: :bar)
61
+ expect(subject.blacklist).to eq [:bar]
62
+ end
95
63
 
96
- it "returns false" do
97
- expect(subject == other).to eq false
98
- expect(subject).not_to eq other
99
- end
64
+ it "is symbolized" do
65
+ subject = described_class.new("foo", except: %w(bar baz))
66
+ expect(subject.blacklist).to eq [:bar, :baz]
67
+ end
100
68
 
101
- end # context
69
+ it "contains unique items" do
70
+ subject = described_class.new("foo", except: %i(bar bar))
71
+ expect(subject.blacklist).to eq [:bar]
72
+ end
102
73
 
103
- context "not an item" do
74
+ end # describe .blacklist
104
75
 
105
- let(:other) { "baz" }
76
+ describe "#block" do
106
77
 
107
- it "returns false" do
108
- expect(subject == other).to eq false
109
- expect(subject).not_to eq other
110
- end
78
+ it "returns nil by default" do
79
+ expect(subject.block).to be_nil
80
+ end
111
81
 
112
- end # context
82
+ it "is initialized" do
83
+ block = proc { :foo }
84
+ subject = described_class.new "foo", &block
85
+ expect(subject.block).to eq block
86
+ end
113
87
 
114
- end # describe #==
88
+ end # describe .blacklist
115
89
 
116
90
  describe "#used_in_context?" do
117
91
 
@@ -156,10 +130,10 @@ describe Attestor::Validations::Validator do
156
130
 
157
131
  end # describe #name
158
132
 
159
- describe "#validate" do
133
+ describe "#validate!" do
160
134
 
161
- let(:object) { Class.new { private def foo; end }.new }
162
- after { subject.validate object }
135
+ let(:object) { Class.new { private; def foo; end }.new }
136
+ after { subject.validate! object }
163
137
 
164
138
  context "when no block initialized" do
165
139
 
@@ -181,6 +155,14 @@ describe Attestor::Validations::Validator do
181
155
 
182
156
  end # context
183
157
 
158
+ end # describe #validate!
159
+
160
+ describe "#validate" do
161
+
162
+ it "is is imported from the Reporter" do
163
+ expect(described_class).to include reporter_module
164
+ end
165
+
184
166
  end # describe #validate
185
167
 
186
168
  end # describe Attestor::Validation
@@ -3,7 +3,9 @@
3
3
  describe Attestor::Validations::Validators do
4
4
 
5
5
  let(:validator_class) { Attestor::Validations::Validator }
6
- let(:delegator_class) { Attestor::Validations::Delegator }
6
+ let(:delegator_class) { Attestor::Validations::Delegator }
7
+ let(:reporter_module) { Attestor::Validations::Reporter }
8
+ let(:invalid_error) { Attestor::InvalidError }
7
9
 
8
10
  describe ".new" do
9
11
 
@@ -61,18 +63,24 @@ describe Attestor::Validations::Validators do
61
63
 
62
64
  context "with a block" do
63
65
 
64
- let(:result) { subject.add_validator { foo } }
66
+ let(:block) { proc { foo } }
67
+ let(:result) { subject.add_validator(&block) }
65
68
 
66
69
  it "returns validators" do
67
70
  expect(result).to be_kind_of described_class
68
71
  end
69
72
 
70
- it "adds validator (not a delegator)" do
73
+ it "adds a validator (not a delegator)" do
71
74
  item = result.first
72
75
  expect(item).to be_kind_of validator_class
73
76
  expect(item).not_to be_kind_of delegator_class
74
77
  end
75
78
 
79
+ it "assigns a block to the validator" do
80
+ item = result.first
81
+ expect(item.block).to eq block
82
+ end
83
+
76
84
  end # context
77
85
 
78
86
  context "with contexts" do
@@ -117,7 +125,8 @@ describe Attestor::Validations::Validators do
117
125
 
118
126
  context "with a block" do
119
127
 
120
- let(:result) { subject.add_delegator { foo } }
128
+ let(:block) { proc { foo } }
129
+ let(:result) { subject.add_delegator(&block) }
121
130
 
122
131
  it "returns validators" do
123
132
  expect(result).to be_kind_of described_class
@@ -128,6 +137,11 @@ describe Attestor::Validations::Validators do
128
137
  expect(item).to be_kind_of delegator_class
129
138
  end
130
139
 
140
+ it "assigns a block to the delegator" do
141
+ item = result.first
142
+ expect(item.block).to eq block
143
+ end
144
+
131
145
  end # context
132
146
 
133
147
  context "with contexts" do
@@ -165,4 +179,67 @@ describe Attestor::Validations::Validators do
165
179
 
166
180
  end # describe #set
167
181
 
182
+ describe "#validate!" do
183
+
184
+ let(:object) { double foo: nil, bar: nil }
185
+
186
+ subject do
187
+ described_class.new
188
+ .add_validator("foo")
189
+ .add_validator("bar")
190
+ end
191
+
192
+ context "when all validators passes" do
193
+
194
+ it "calls all validators" do
195
+ expect(object).to receive :foo
196
+ expect(object).to receive :bar
197
+ subject.validate! object
198
+ end
199
+
200
+ it "passes" do
201
+ expect { subject.validate! object }.not_to raise_error
202
+ end
203
+
204
+ end # context
205
+
206
+ context "when any validator fails" do
207
+
208
+ let(:messages) { %w(foo) }
209
+ before do
210
+ allow(object)
211
+ .to receive(:foo) { fail invalid_error.new(object, messages) }
212
+ end
213
+
214
+ it "calls all validators" do
215
+ expect(object).to receive :foo
216
+ expect(object).to receive :bar
217
+ subject.validate! object rescue nil
218
+ end
219
+
220
+ it "fails" do
221
+ expect { subject.validate! object }.to raise_error(invalid_error)
222
+ end
223
+
224
+ it "collects errors from validators" do
225
+ begin
226
+ subject.validate! object
227
+ rescue => error
228
+ expect(error.object).to eq object
229
+ expect(error.messages).to eq messages
230
+ end
231
+ end
232
+
233
+ end # context
234
+
235
+ end # describe #validate!
236
+
237
+ describe "#validate" do
238
+
239
+ it "is is imported from the Reporter" do
240
+ expect(described_class).to include reporter_module
241
+ end
242
+
243
+ end # describe #validate
244
+
168
245
  end # describe Attestor::Validators
@@ -31,18 +31,42 @@ describe Attestor::Validations do
31
31
 
32
32
  describe ".validate" do
33
33
 
34
- context "without options" do
34
+ context "with a name" do
35
35
 
36
36
  before { test_class.validate :foo }
37
37
 
38
38
  it "registers a validator" do
39
- expect(test_class.validators.map(&:name)).to eq [:foo]
40
- expect(test_class.validators.first).not_to be_kind_of delegator_class
39
+ item = test_class.validators.first
40
+ expect(item).to be_kind_of validator_class
41
+ expect(item).not_to be_kind_of delegator_class
42
+ end
43
+
44
+ it "assigns the name to the validator" do
45
+ item = test_class.validators.first
46
+ expect(item.name).to eq :foo
47
+ end
48
+
49
+ end # context
50
+
51
+ context "with a block" do
52
+
53
+ let(:block) { proc { foo } }
54
+ before { test_class.validate(&block) }
55
+
56
+ it "registers a validator" do
57
+ item = test_class.validators.first
58
+ expect(item).to be_kind_of validator_class
59
+ expect(item).not_to be_kind_of delegator_class
60
+ end
61
+
62
+ it "assigns the block to the validator" do
63
+ item = test_class.validators.first
64
+ expect(item.block).to eq block
41
65
  end
42
66
 
43
67
  end # context
44
68
 
45
- context "with restrictions" do
69
+ context "with options" do
46
70
 
47
71
  before { test_class.validate :foo, only: %w(bar baz), except: "bar" }
48
72
 
@@ -58,18 +82,40 @@ describe Attestor::Validations do
58
82
 
59
83
  describe ".validates" do
60
84
 
61
- context "without options" do
85
+ context "with a name" do
62
86
 
63
87
  before { test_class.validates :foo }
64
88
 
65
89
  it "registers a delegator" do
66
- expect(test_class.validators.map(&:name)).to eq [:foo]
67
- expect(test_class.validators.first).to be_kind_of delegator_class
90
+ item = test_class.validators.first
91
+ expect(item).to be_kind_of delegator_class
92
+ end
93
+
94
+ it "assigns the name to the delegator" do
95
+ item = test_class.validators.first
96
+ expect(item.name).to eq :foo
68
97
  end
69
98
 
70
99
  end # context
71
100
 
72
- context "with restrictions" do
101
+ context "with a block" do
102
+
103
+ let(:block) { proc { foo } }
104
+ before { test_class.validates(&block) }
105
+
106
+ it "registers a delegator" do
107
+ item = test_class.validators.first
108
+ expect(item).to be_kind_of delegator_class
109
+ end
110
+
111
+ it "assigns the block to the delegator" do
112
+ item = test_class.validators.first
113
+ expect(item.block).to eq block
114
+ end
115
+
116
+ end # context
117
+
118
+ context "with options" do
73
119
 
74
120
  before { test_class.validates :foo, only: %w(bar baz), except: "bar" }
75
121
 
@@ -87,7 +133,13 @@ describe Attestor::Validations do
87
133
 
88
134
  shared_examples "raising an error" do |name, options = {}|
89
135
 
90
- let(:message) { message_class.new(name, subject, options) }
136
+ let(:message) { double }
137
+ before do
138
+ allow(message_class)
139
+ .to receive(:new)
140
+ .with(name, subject, options)
141
+ .and_return message
142
+ end
91
143
 
92
144
  it "raises an InvalidError" do
93
145
  expect { invalid }.to raise_error invalid_error
@@ -122,6 +174,42 @@ describe Attestor::Validations do
122
174
 
123
175
  end # invalid
124
176
 
177
+ describe "#validate!" do
178
+
179
+ before do
180
+ test_class.validate :foo
181
+ test_class.validate :bar, only: :all
182
+ test_class.validates :baz, only: :foo
183
+
184
+ allow(subject).to receive(:foo)
185
+ allow(subject).to receive(:bar)
186
+ allow(subject).to receive(:baz) { valid_policy }
187
+ end
188
+
189
+ context "without an argument" do
190
+
191
+ it "calls validators for :all context" do
192
+ expect(subject).to receive(:foo)
193
+ expect(subject).to receive(:bar)
194
+ expect(subject).not_to receive(:baz)
195
+ subject.validate!
196
+ end
197
+
198
+ end # context
199
+
200
+ context ":foo" do
201
+
202
+ it "calls validators for :foo context" do
203
+ expect(subject).to receive(:foo)
204
+ expect(subject).to receive(:baz)
205
+ expect(subject).not_to receive(:bar)
206
+ subject.validate! :foo
207
+ end
208
+
209
+ end # context
210
+
211
+ end # describe #validate!
212
+
125
213
  describe "#validate" do
126
214
 
127
215
  before do
@@ -156,6 +244,6 @@ describe Attestor::Validations do
156
244
 
157
245
  end # context
158
246
 
159
- end # describe #validate
247
+ end # describe #validate!
160
248
 
161
249
  end # describe Attestor::Validations
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attestor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-28 00:00:00.000000000 Z
11
+ date: 2015-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: extlib
@@ -80,9 +80,11 @@ files:
80
80
  - lib/attestor/policy/not.rb
81
81
  - lib/attestor/policy/or.rb
82
82
  - lib/attestor/policy/xor.rb
83
+ - lib/attestor/report.rb
83
84
  - lib/attestor/validations.rb
84
85
  - lib/attestor/validations/delegator.rb
85
86
  - lib/attestor/validations/message.rb
87
+ - lib/attestor/validations/reporter.rb
86
88
  - lib/attestor/validations/validator.rb
87
89
  - lib/attestor/validations/validators.rb
88
90
  - lib/attestor/version.rb
@@ -98,8 +100,10 @@ files:
98
100
  - spec/tests/policy/or_spec.rb
99
101
  - spec/tests/policy/xor_spec.rb
100
102
  - spec/tests/policy_spec.rb
103
+ - spec/tests/report_spec.rb
101
104
  - spec/tests/validations/delegator_spec.rb
102
105
  - spec/tests/validations/message_spec.rb
106
+ - spec/tests/validations/reporter_spec.rb
103
107
  - spec/tests/validations/validator_spec.rb
104
108
  - spec/tests/validations/validators_spec.rb
105
109
  - spec/tests/validations_spec.rb
@@ -123,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
127
  version: '0'
124
128
  requirements: []
125
129
  rubyforge_project:
126
- rubygems_version: 2.4.6
130
+ rubygems_version: 2.2.2
127
131
  signing_key:
128
132
  specification_version: 4
129
133
  summary: Validations for immutable Ruby objects
@@ -132,8 +136,10 @@ test_files:
132
136
  - spec/tests/policy_spec.rb
133
137
  - spec/tests/invalid_error_spec.rb
134
138
  - spec/tests/validations_spec.rb
139
+ - spec/tests/report_spec.rb
135
140
  - spec/tests/validations/message_spec.rb
136
141
  - spec/tests/validations/validator_spec.rb
142
+ - spec/tests/validations/reporter_spec.rb
137
143
  - spec/tests/validations/delegator_spec.rb
138
144
  - spec/tests/validations/validators_spec.rb
139
145
  - spec/tests/policy/or_spec.rb