attestor 2.0.0 → 2.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.
- checksums.yaml +4 -4
- data/README.md +40 -9
- data/lib/attestor/rspec.rb +31 -0
- data/lib/attestor/version.rb +1 -1
- data/spec/tests/rspec_spec.rb +98 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ed10bee06c2caea561384393fd3c3a09d8548aa
|
4
|
+
data.tar.gz: 4a808081721ac3ce602ebcb26c1a733878189112
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2ebc2cd9437e77946faf52f458fe719daa70a8cc9baeda2d33a16e31f5dfd34cdf3c9e588f4199f3e749e8bc29f9eee738936a7d70c688d620ad69d32b037b0
|
7
|
+
data.tar.gz: 36c544456aa601a9b87bbd50568eb27253a866853b06081e714651e7acd37e2f6fdb622827bd55952c250f5cbbb1304f21b13a41d2d53ceb72321857c950b963
|
data/README.md
CHANGED
@@ -86,7 +86,7 @@ Transfer = Struct.new(:debet, :credit) do
|
|
86
86
|
end
|
87
87
|
```
|
88
88
|
|
89
|
-
Alternatively, you can describe validation in
|
89
|
+
Alternatively, you can describe validation in a block, executed in an instance's scope:
|
90
90
|
|
91
91
|
```ruby
|
92
92
|
class Transfer
|
@@ -95,7 +95,7 @@ class Transfer
|
|
95
95
|
end
|
96
96
|
```
|
97
97
|
|
98
|
-
The `#invalid` method translates its argument
|
98
|
+
The `#invalid` method translates its argument and raises an exception with the resulting message.
|
99
99
|
|
100
100
|
```yaml
|
101
101
|
# config/locales/en.yml
|
@@ -107,7 +107,7 @@ en:
|
|
107
107
|
inconsistent: "Credit differs from debet by %{fraud}"
|
108
108
|
```
|
109
109
|
|
110
|
-
To
|
110
|
+
To validate an object, use its `#validate!` method:
|
111
111
|
|
112
112
|
```ruby
|
113
113
|
debet = OpenStruct.new(sum: 100)
|
@@ -122,7 +122,8 @@ rescue Attestor::InvalidError => error
|
|
122
122
|
end
|
123
123
|
```
|
124
124
|
|
125
|
-
|
125
|
+
Alternatively use the safe version `#validate`.
|
126
|
+
It rescues from an exception and returns a corresponding report:
|
126
127
|
|
127
128
|
```ruby
|
128
129
|
report = transfer.validate # without the bang
|
@@ -134,6 +135,8 @@ report.messages # => ["Credit differs from debet by 10"]
|
|
134
135
|
report.error # => <Attestor::InvalidError ...>
|
135
136
|
```
|
136
137
|
|
138
|
+
Once again, the report collects messages outside of the checked object.
|
139
|
+
|
137
140
|
Use of Contexts
|
138
141
|
---------------
|
139
142
|
|
@@ -155,14 +158,13 @@ fraud_transfer.validate! # => InvalidError
|
|
155
158
|
fraud_transfer.validate! :steal_of_money # => PASSES!
|
156
159
|
```
|
157
160
|
|
158
|
-
You can use the same validator several times with different contexts.
|
161
|
+
You can use the same validator several times with different contexts. They will be used independently from each other.
|
159
162
|
|
160
163
|
```ruby
|
161
164
|
class Transfer
|
162
165
|
# ...
|
163
166
|
|
164
|
-
|
165
|
-
validate :consistent, only: :fair_trade
|
167
|
+
validate :consistent, only: :fair_trade, :consistent
|
166
168
|
validate :consistent, only: :legal
|
167
169
|
|
168
170
|
end
|
@@ -183,7 +185,7 @@ ConsistentTransfer = Struct.new(:debet, :credit) do
|
|
183
185
|
end
|
184
186
|
```
|
185
187
|
|
186
|
-
Then use `validates` helper:
|
188
|
+
Then use `validates` helper (with an "s" at the end):
|
187
189
|
|
188
190
|
```ruby
|
189
191
|
class Transfer
|
@@ -204,7 +206,7 @@ class Transfer
|
|
204
206
|
end
|
205
207
|
```
|
206
208
|
|
207
|
-
The difference between `.validate :something` and `.validates :something`
|
209
|
+
The difference between `.validate :something` and `.validates :something` methods is that:
|
208
210
|
* `.validate` expects `#something` to make checks and raise error by itself
|
209
211
|
* `.validates` expects `#something` to respond to `#validate!`
|
210
212
|
|
@@ -299,6 +301,33 @@ Policy.not(valid_policy)
|
|
299
301
|
|
300
302
|
As before, you can use any number of policies (except for negation of a single policy) at any number of nesting.
|
301
303
|
|
304
|
+
RSpec helpers
|
305
|
+
-------------
|
306
|
+
|
307
|
+
In a RSpec tests you can use spies for valid and invalid objects:
|
308
|
+
|
309
|
+
* `valid_spy` is a spy that returns `nil` in response to `#validate!` and valid report in responce to `#validate`.
|
310
|
+
* `invalid_spy` raises on `#validate!` and returns invalid report in responce to `#validate` method call.
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
require "attestor/rspec"
|
314
|
+
|
315
|
+
describe "something" do
|
316
|
+
|
317
|
+
let(:valid_object) { valid_spy }
|
318
|
+
let(:invalid_object) { invalid_spy }
|
319
|
+
|
320
|
+
# ...
|
321
|
+
end
|
322
|
+
```
|
323
|
+
|
324
|
+
To check whether an arbitrary object is valid, simply use `#validate` method's result:
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
expect(object.validate).to be_valid
|
328
|
+
expect(object.validate).to be_invalid
|
329
|
+
```
|
330
|
+
|
302
331
|
Latest changes
|
303
332
|
--------------
|
304
333
|
|
@@ -308,6 +337,8 @@ Latest changes
|
|
308
337
|
|
309
338
|
2. Policies doesn't have `#valid?` and `#invalid?` methods any longer. Both the methods are removed to `#validate` report.
|
310
339
|
|
340
|
+
### Version 2.1.0
|
341
|
+
|
311
342
|
Compatibility
|
312
343
|
-------------
|
313
344
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rspec"
|
3
|
+
|
4
|
+
module Attestor
|
5
|
+
|
6
|
+
# Helpers for validations
|
7
|
+
module RSpec
|
8
|
+
include ::RSpec::Mocks::ExampleMethods
|
9
|
+
|
10
|
+
# Mocks a valid object
|
11
|
+
def valid_spy
|
12
|
+
object = spy
|
13
|
+
allow(object).to receive(:validate!)
|
14
|
+
allow(object).to receive(:validate) { Report.new(object) }
|
15
|
+
|
16
|
+
object
|
17
|
+
end
|
18
|
+
|
19
|
+
# Mocks an invalid object
|
20
|
+
def invalid_spy(messages = "invalid")
|
21
|
+
object = spy
|
22
|
+
error = InvalidError.new(object, messages)
|
23
|
+
allow(object).to receive(:validate!) { fail error }
|
24
|
+
allow(object).to receive(:validate) { Report.new(object, error) }
|
25
|
+
|
26
|
+
object
|
27
|
+
end
|
28
|
+
|
29
|
+
end # module RSpec
|
30
|
+
|
31
|
+
end # module Attestor
|
data/lib/attestor/version.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "attestor/rspec"
|
3
|
+
|
4
|
+
describe Attestor::RSpec do
|
5
|
+
|
6
|
+
let(:report_class) { Attestor::Report }
|
7
|
+
let(:invalid_error) { Attestor::InvalidError }
|
8
|
+
let(:double_class) { ::RSpec::Mocks::Double }
|
9
|
+
|
10
|
+
subject { Class.new.send(:include, described_class).new }
|
11
|
+
|
12
|
+
describe "#valid_spy" do
|
13
|
+
|
14
|
+
let(:valid_spy) { subject.valid_spy }
|
15
|
+
|
16
|
+
it "returns a spy" do
|
17
|
+
expect(valid_spy).to be_kind_of(double_class)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "doesn't raise on #validate!" do
|
21
|
+
expect { valid_spy.validate! }.not_to raise_error
|
22
|
+
expect(valid_spy.validate!).to be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns a valid report on #validate" do
|
26
|
+
report = valid_spy.validate
|
27
|
+
|
28
|
+
expect(report).to be_kind_of(report_class)
|
29
|
+
expect(report).to be_valid
|
30
|
+
expect(report.object).to eq valid_spy
|
31
|
+
end
|
32
|
+
|
33
|
+
end # describe #valid_spy
|
34
|
+
|
35
|
+
describe "#invalid_spy" do
|
36
|
+
|
37
|
+
context "without messages" do
|
38
|
+
|
39
|
+
let(:invalid_spy) { subject.invalid_spy }
|
40
|
+
|
41
|
+
it "returns a spy" do
|
42
|
+
expect(invalid_spy).to be_kind_of(double_class)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises InvalidError on #validate!" do
|
46
|
+
expect { invalid_spy.validate! }.to raise_error(invalid_error)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "adds itself to the exception on #validate!" do
|
50
|
+
begin
|
51
|
+
invalid_spy.validate!
|
52
|
+
rescue => error
|
53
|
+
expect(error.object).to eq invalid_spy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns a valid report on #validate" do
|
58
|
+
report = invalid_spy.validate
|
59
|
+
|
60
|
+
expect(report).to be_kind_of(report_class)
|
61
|
+
expect(report).to be_invalid
|
62
|
+
expect(report.object).to eq invalid_spy
|
63
|
+
end
|
64
|
+
|
65
|
+
it "adds an 'invalid' message to the exception" do
|
66
|
+
report = invalid_spy.validate
|
67
|
+
expect(report.messages).to eq ["invalid"]
|
68
|
+
end
|
69
|
+
|
70
|
+
end # context
|
71
|
+
|
72
|
+
context "with a message" do
|
73
|
+
|
74
|
+
let(:message) { "error" }
|
75
|
+
let(:invalid_spy) { subject.invalid_spy message }
|
76
|
+
|
77
|
+
it "adds the message to the exception" do
|
78
|
+
report = invalid_spy.validate
|
79
|
+
expect(report.messages).to eq [message]
|
80
|
+
end
|
81
|
+
|
82
|
+
end # context
|
83
|
+
|
84
|
+
context "with a list of messages" do
|
85
|
+
|
86
|
+
let(:messages) { %w(error exception) }
|
87
|
+
let(:invalid_spy) { subject.invalid_spy(messages) }
|
88
|
+
|
89
|
+
it "adds all the messages to the exception" do
|
90
|
+
report = invalid_spy.validate
|
91
|
+
expect(report.messages).to eq messages
|
92
|
+
end
|
93
|
+
|
94
|
+
end # context
|
95
|
+
|
96
|
+
end # describe #invalid_spy
|
97
|
+
|
98
|
+
end # describe Attestor::RSpec
|
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: 2.
|
4
|
+
version: 2.1.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-04-
|
11
|
+
date: 2015-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: extlib
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- lib/attestor/policy/or.rb
|
82
82
|
- lib/attestor/policy/xor.rb
|
83
83
|
- lib/attestor/report.rb
|
84
|
+
- lib/attestor/rspec.rb
|
84
85
|
- lib/attestor/validations.rb
|
85
86
|
- lib/attestor/validations/delegator.rb
|
86
87
|
- lib/attestor/validations/message.rb
|
@@ -101,6 +102,7 @@ files:
|
|
101
102
|
- spec/tests/policy/xor_spec.rb
|
102
103
|
- spec/tests/policy_spec.rb
|
103
104
|
- spec/tests/report_spec.rb
|
105
|
+
- spec/tests/rspec_spec.rb
|
104
106
|
- spec/tests/validations/delegator_spec.rb
|
105
107
|
- spec/tests/validations/message_spec.rb
|
106
108
|
- spec/tests/validations/reporter_spec.rb
|
@@ -127,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
129
|
version: '0'
|
128
130
|
requirements: []
|
129
131
|
rubyforge_project:
|
130
|
-
rubygems_version: 2.
|
132
|
+
rubygems_version: 2.4.6
|
131
133
|
signing_key:
|
132
134
|
specification_version: 4
|
133
135
|
summary: Validations for immutable Ruby objects
|
@@ -149,6 +151,7 @@ test_files:
|
|
149
151
|
- spec/tests/policy/negator_spec.rb
|
150
152
|
- spec/tests/policy/not_spec.rb
|
151
153
|
- spec/tests/policy/node_spec.rb
|
154
|
+
- spec/tests/rspec_spec.rb
|
152
155
|
- spec/features/example_spec.rb
|
153
156
|
- spec/support/policies.rb
|
154
157
|
has_rdoc:
|