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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b4d9f6dfa1931f69062623223fafaf32ec4d158
4
- data.tar.gz: a18709a18446af9c58a71287eb9b3d923c125aed
3
+ metadata.gz: 0ed10bee06c2caea561384393fd3c3a09d8548aa
4
+ data.tar.gz: 4a808081721ac3ce602ebcb26c1a733878189112
5
5
  SHA512:
6
- metadata.gz: fadf072439c8efa450e86ff37f7dd5778c67ce7a087eaea4e012e0267d9dce2b877283b76c04b1434b1ab0d17b7a00a48317ddeee766304d7ff08ebb02c66109
7
- data.tar.gz: 0c5fccf30fe0cfc574d71b3235da77acc904c3f537f4d9ffb4887184925d42c57d82736f99d0af0954fe000c0bc141cc1793bd15911275485bfcfc648bb235c6
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 the block (called in the scope of instance):
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 in a current class scope and raises an exception with that method.
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 run validations use the `#validate!` instance method:
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
- Another option is to use the safe version `#validate`. It rescues from the exception and returns results in a separate report object:
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
- # validate :consistent, only: [:fair_trade, :legal]
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` class methods is that:
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
@@ -4,6 +4,6 @@ module Attestor
4
4
 
5
5
  # The semantic version of the module.
6
6
  # @see http://semver.org/ Semantic versioning 2.0
7
- VERSION = "2.0.0".freeze
7
+ VERSION = "2.1.0".freeze
8
8
 
9
9
  end # module Attestor
@@ -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.0.0
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-05 00:00:00.000000000 Z
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.2.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: