attestor 1.0.0 → 2.0.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 (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