tram-policy 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +76 -19
- data/bin/tram-policy +1 -1
- data/lib/tram/policy.rb +10 -5
- data/lib/tram/policy/generator.rb +30 -11
- data/lib/tram/policy/generator/policy.erb +11 -4
- data/lib/tram/policy/generator/policy_spec.erb +17 -8
- data/lib/tram/policy/{matchers.rb → rspec.rb} +25 -6
- data/lib/tram/policy/validator.rb +17 -0
- data/spec/spec_helper.rb +3 -6
- data/spec/tram/policy/{matchers_spec.rb → rspec_spec.rb} +9 -1
- data/spec/tram/policy_spec.rb +23 -1
- data/tram-policy.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d61d4df530a82fdee0fffa4c5129421348d60c18
|
4
|
+
data.tar.gz: e129c65a0019df533cad7e2b90981c332572a6be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e11195f58b75868feaacb300a57377dbb5ba1d5955709c6ee589d8729bc7304a685cfe2db9c48f6e0f1a7ffb47c0746def0c9331c262199853662cdf8b6624e
|
7
|
+
data.tar.gz: f3d07ca8653f883a72052abc0c3430845ad4c1d88177a8f266ca02f0c73a4b0e31e367cd658955ea6a129d0668b1d22695bd249926780080a9b7d3bba1caba95
|
data/CHANGELOG.md
CHANGED
@@ -6,8 +6,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.0.2] - [2017-04-25]
|
10
|
+
The gem is battle-tested for production (in a real commertial project).
|
11
|
+
|
12
|
+
### Removed
|
13
|
+
- `.validate` with several keys for several validators at once (@nepalez)
|
14
|
+
|
15
|
+
Use a multiline version instead of `validate :foo, :bar`:
|
16
|
+
|
17
|
+
```
|
18
|
+
validate :foo
|
19
|
+
validate :bar
|
20
|
+
```
|
21
|
+
|
22
|
+
### Added
|
23
|
+
- `.validate` supports option `stop_on_failure` (@nepalez)
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
- Minor bugs in generators (@nepalez)
|
27
|
+
|
9
28
|
## [0.0.1] - [2017-04-18]
|
10
29
|
This is a first public release (@nepalez, @charlie-wasp, @JewelSam, @sergey-chechaev)
|
11
30
|
|
12
31
|
[Unreleased]: https://github.com/tram-rb/tram-policy
|
13
32
|
[0.0.1]: https://github.com/tram-rb/tram-policy/releases/tag/v0.0.1
|
33
|
+
[0.0.2]: https://github.com/tram-rb/tram-policy/compare/v0.0.1...v0.0.2
|
data/README.md
CHANGED
@@ -172,6 +172,36 @@ rescue Tram::Policy::ValidationError => error
|
|
172
172
|
end
|
173
173
|
```
|
174
174
|
|
175
|
+
## Additional options
|
176
|
+
|
177
|
+
Class method `.validate` supports several options:
|
178
|
+
|
179
|
+
### `stop_on_faiure`
|
180
|
+
|
181
|
+
If a selected validation will fail (adds an error to the collection), the following validations won't be executed.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
require "tram-policy"
|
185
|
+
|
186
|
+
class Article::ReadinessPolicy < Tram::Policy
|
187
|
+
# required param for article to validate
|
188
|
+
param :article
|
189
|
+
|
190
|
+
validate :title_presence, stop_on_failure: true
|
191
|
+
validate :title_valid # not executed if title is absent
|
192
|
+
|
193
|
+
# ...
|
194
|
+
end
|
195
|
+
```
|
196
|
+
|
197
|
+
### `if`
|
198
|
+
|
199
|
+
[WIP] Not implemented (coming soon in v0.1.0)
|
200
|
+
|
201
|
+
### `unless`
|
202
|
+
|
203
|
+
[WIP] Not implemented (coming soon in v0.1.0)
|
204
|
+
|
175
205
|
## RSpec matchers
|
176
206
|
|
177
207
|
RSpec matchers defined in a file `tram-policy/matcher` (not loaded in runtime).
|
@@ -197,7 +227,7 @@ end
|
|
197
227
|
|
198
228
|
```ruby
|
199
229
|
# spec/spec_helper.rb
|
200
|
-
require "tram
|
230
|
+
require "tram/policy/rspec"
|
201
231
|
```
|
202
232
|
|
203
233
|
```ruby
|
@@ -217,14 +247,14 @@ RSpec.describe User::ReadinessPolicy do
|
|
217
247
|
end
|
218
248
|
```
|
219
249
|
|
220
|
-
**Notice** that you have to wrap policy into block `{ policy }`. This is because matcher checks not only presence of an error, but also ensures its message is translated to all available locales (`I18n.available_locales`). The block containing a policy will be executed separately for every such language.
|
250
|
+
**Notice** that you have to wrap policy into block `{ policy }`. This is because the matcher checks not only presence of an error, but also ensures its message is translated to all available locales (`I18n.available_locales`). The block containing a policy will be executed separately for every such language.
|
221
251
|
|
222
252
|
## Generators
|
223
253
|
|
224
254
|
The gem provides simple tool for scaffolding new policy along with RSpec test template.
|
225
255
|
|
226
256
|
```shell
|
227
|
-
$ tram-policy user/readiness_policy -p user -o admin -v name_present email_present
|
257
|
+
$ tram-policy user/readiness_policy -p user -o admin -v name_present:blank_name email_present:blank_email
|
228
258
|
```
|
229
259
|
|
230
260
|
This will generate a policy class with specification compatible to both [RSpec][rspec] and [FactoryGirl][factory-girl]:
|
@@ -232,7 +262,13 @@ This will generate a policy class with specification compatible to both [RSpec][
|
|
232
262
|
|
233
263
|
```ruby
|
234
264
|
# app/policies/user/readiness_policy.rb
|
265
|
+
|
266
|
+
# TODO: describe the policy, its subject and context
|
235
267
|
class User::ReadinessPolicy < Tram::Policy
|
268
|
+
# TODO: add default values (default: -> { ... }),
|
269
|
+
# coercers (type: proc(&:to_s)),
|
270
|
+
# and optional arguments (optional: true)
|
271
|
+
# when necessary
|
236
272
|
param :user
|
237
273
|
option :admin
|
238
274
|
|
@@ -242,13 +278,17 @@ class User::ReadinessPolicy < Tram::Policy
|
|
242
278
|
private
|
243
279
|
|
244
280
|
def name_present
|
245
|
-
|
246
|
-
|
281
|
+
# TODO: define a condition
|
282
|
+
return if true
|
283
|
+
# TODO: add necessary tags
|
284
|
+
errors.add :blank_name
|
247
285
|
end
|
248
286
|
|
249
287
|
def email_present
|
250
|
-
|
251
|
-
|
288
|
+
# TODO: define a condition
|
289
|
+
return if true
|
290
|
+
# TODO: add necessary tags
|
291
|
+
errors.add :blank_email
|
252
292
|
end
|
253
293
|
end
|
254
294
|
```
|
@@ -258,32 +298,46 @@ end
|
|
258
298
|
---
|
259
299
|
en:
|
260
300
|
user/readiness_policy:
|
261
|
-
|
262
|
-
|
301
|
+
blank_name: translation missing
|
302
|
+
blank_email: translation missing
|
263
303
|
```
|
264
304
|
|
265
305
|
```ruby
|
266
306
|
# spec/policies/user/readiness_policy_spec.rb
|
267
|
-
|
268
|
-
|
307
|
+
require "spec_helper"
|
308
|
+
# TODO: move it to spec_helper
|
309
|
+
require "tram/policy/rspec"
|
269
310
|
|
270
|
-
|
311
|
+
RSpec.describe User::ReadinessPolicy, ".[]" do
|
312
|
+
# TODO: either remove this line, or set another source for locales to check
|
313
|
+
let(:available_locales) { I18n.available_locales }
|
314
|
+
let(:user) { FactoryGirl.build :user }
|
271
315
|
|
272
|
-
it
|
316
|
+
it "is valid with proper arguments" do
|
317
|
+
expect { described_class[user] }.to be_valid
|
318
|
+
end
|
273
319
|
|
320
|
+
# TODO: check the description
|
274
321
|
it "is invalid when not name_present" do
|
275
|
-
|
276
|
-
|
322
|
+
# TODO: modify some arguments
|
323
|
+
user = nil
|
324
|
+
# TODO: add necessary tags to focus the condition
|
325
|
+
expect { described_class[user] }.to be_invalid_at
|
277
326
|
end
|
278
327
|
|
328
|
+
# TODO: check the description
|
279
329
|
it "is invalid when not email_present" do
|
280
|
-
|
281
|
-
|
330
|
+
# TODO: modify some arguments
|
331
|
+
user = nil
|
332
|
+
# TODO: add necessary tags to focus the condition
|
333
|
+
expect { described_class[user] }.to be_invalid_at
|
282
334
|
end
|
283
335
|
end
|
284
336
|
```
|
285
337
|
|
286
|
-
|
338
|
+
Then you should go through all TODO-s and add necessary details.
|
339
|
+
|
340
|
+
Later you can copy-paste examples to provide more edge case for testing your policies.
|
287
341
|
|
288
342
|
Notice that RSpec matcher `be_invalid_at` checks at once:
|
289
343
|
|
@@ -291,7 +345,10 @@ Notice that RSpec matcher `be_invalid_at` checks at once:
|
|
291
345
|
- that the error has given tags
|
292
346
|
- that the error is translated to every available locale
|
293
347
|
|
294
|
-
|
348
|
+
Its negation (`not_to be_invalid_at`) checks that no errors added with given tags.
|
349
|
+
When called without tags, it checks that the policy is valid as a whole.
|
350
|
+
|
351
|
+
Both matchers provide a full description for the essence of the failure.
|
295
352
|
|
296
353
|
## To Recap
|
297
354
|
|
data/bin/tram-policy
CHANGED
data/lib/tram/policy.rb
CHANGED
@@ -8,6 +8,7 @@ module Tram
|
|
8
8
|
require_relative "policy/inflector"
|
9
9
|
require_relative "policy/error"
|
10
10
|
require_relative "policy/errors"
|
11
|
+
require_relative "policy/validator"
|
11
12
|
|
12
13
|
extend Dry::Initializer
|
13
14
|
|
@@ -17,8 +18,8 @@ module Tram
|
|
17
18
|
# @param [#to_sym, Array<#to_sym>] names
|
18
19
|
# @return [self]
|
19
20
|
#
|
20
|
-
def validate(
|
21
|
-
|
21
|
+
def validate(name, **opts)
|
22
|
+
validators[name.to_sym] = opts
|
22
23
|
self
|
23
24
|
end
|
24
25
|
|
@@ -34,12 +35,12 @@ module Tram
|
|
34
35
|
private
|
35
36
|
|
36
37
|
def validators
|
37
|
-
@validators ||=
|
38
|
+
@validators ||= {}
|
38
39
|
end
|
39
40
|
|
40
41
|
def inherited(klass)
|
41
42
|
super
|
42
|
-
klass.validate
|
43
|
+
validators.each { |name, opts| klass.validate name, opts }
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
@@ -107,7 +108,11 @@ module Tram
|
|
107
108
|
def initialize(*)
|
108
109
|
super
|
109
110
|
@__scope__ = Inflector.underscore(self.class.name)
|
110
|
-
self.class.send(:validators).each
|
111
|
+
self.class.send(:validators).each do |name, opts|
|
112
|
+
size = errors.count
|
113
|
+
send(name)
|
114
|
+
break if (errors.count > size) && opts[:stop_on_failure]
|
115
|
+
end
|
111
116
|
end
|
112
117
|
end
|
113
118
|
end
|
@@ -25,11 +25,25 @@ module Tram
|
|
25
25
|
default: [],
|
26
26
|
aliases: "-v",
|
27
27
|
banner: "validator[ validator]"
|
28
|
+
class_option :locales, desc: "list of available_locales",
|
29
|
+
type: :array,
|
30
|
+
default: [],
|
31
|
+
aliases: "-l",
|
32
|
+
banner: "en[ ru]"
|
28
33
|
|
29
34
|
def self.source_root
|
30
35
|
File.dirname(__FILE__)
|
31
36
|
end
|
32
37
|
|
38
|
+
def set_available_locales
|
39
|
+
@available_locales = \
|
40
|
+
if Array(options[:locales]).any?
|
41
|
+
options[:locales]
|
42
|
+
else
|
43
|
+
ask("Enter available locales for translation:").scan(/\w{2}/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
33
47
|
def generate_class
|
34
48
|
template "generator/policy.erb", "app/policies/#{file}.rb"
|
35
49
|
end
|
@@ -39,7 +53,8 @@ module Tram
|
|
39
53
|
@locale = locale
|
40
54
|
add_locale
|
41
55
|
localize_policy
|
42
|
-
parsed_validators.
|
56
|
+
parsed_validators.sort_by { |v| v[:key] }
|
57
|
+
.each { |validator| localize_validator(validator) }
|
43
58
|
end
|
44
59
|
end
|
45
60
|
|
@@ -48,6 +63,10 @@ module Tram
|
|
48
63
|
end
|
49
64
|
|
50
65
|
no_tasks do
|
66
|
+
def available_locales
|
67
|
+
@available_locales ||= []
|
68
|
+
end
|
69
|
+
|
51
70
|
def klass
|
52
71
|
@klass ||= Inflector.camelize name
|
53
72
|
end
|
@@ -65,17 +84,17 @@ module Tram
|
|
65
84
|
end
|
66
85
|
|
67
86
|
def parsed_validators
|
68
|
-
@parsed_validators ||= options[:validators].map
|
87
|
+
@parsed_validators ||= options[:validators].map do |str|
|
88
|
+
name, key = str.downcase.split(":")
|
89
|
+
{ name: name, key: key || name }
|
90
|
+
end
|
69
91
|
end
|
70
92
|
|
71
93
|
def policy_signature
|
72
|
-
@policy_signature ||=
|
94
|
+
@policy_signature ||= (
|
73
95
|
parsed_params + \
|
74
96
|
parsed_options.map { |option| "#{option}: #{option}" }
|
75
|
-
|
76
|
-
|
77
|
-
def available_locales
|
78
|
-
ask("What locales should be used for translation?").scan(/\w{2}/)
|
97
|
+
).join(", ")
|
79
98
|
end
|
80
99
|
|
81
100
|
def locale_file
|
@@ -90,8 +109,8 @@ module Tram
|
|
90
109
|
@locale_group ||= " #{file}:\n"
|
91
110
|
end
|
92
111
|
|
93
|
-
def locale_line(
|
94
|
-
" #{
|
112
|
+
def locale_line(key)
|
113
|
+
" #{key}: translation missing\n"
|
95
114
|
end
|
96
115
|
|
97
116
|
def add_locale
|
@@ -102,8 +121,8 @@ module Tram
|
|
102
121
|
append_to_file(locale_file, locale_group)
|
103
122
|
end
|
104
123
|
|
105
|
-
def localize_validator(
|
106
|
-
insert_into_file locale_file, locale_line(
|
124
|
+
def localize_validator(key:, **)
|
125
|
+
insert_into_file locale_file, locale_line(key), after: locale_group
|
107
126
|
end
|
108
127
|
end
|
109
128
|
end
|
@@ -1,4 +1,9 @@
|
|
1
|
+
# TODO: describe the policy, its subject and context
|
1
2
|
class <%= klass %> < Tram::Policy
|
3
|
+
# TODO: add default values (default: -> { ... }),
|
4
|
+
# coercers (type: proc(&:to_s)),
|
5
|
+
# and optional arguments (optional: true)
|
6
|
+
# when necessary
|
2
7
|
<% parsed_params.each do |param| -%>
|
3
8
|
param :<%= param %>
|
4
9
|
<% end -%>
|
@@ -7,14 +12,16 @@ class <%= klass %> < Tram::Policy
|
|
7
12
|
<% end -%>
|
8
13
|
|
9
14
|
<% parsed_validators.each do |validator| -%>
|
10
|
-
validate :<%= validator %>
|
15
|
+
validate :<%= validator[:name] %>
|
11
16
|
<% end -%>
|
12
17
|
|
13
18
|
private
|
14
19
|
<% parsed_validators.each do |validator| %>
|
15
|
-
def <%= validator %>
|
16
|
-
|
17
|
-
|
20
|
+
def <%= validator[:name] %>
|
21
|
+
# TODO: define a condition
|
22
|
+
return if true
|
23
|
+
# TODO: add necessary tags
|
24
|
+
errors.add :<%= validator[:key] %>
|
18
25
|
end
|
19
26
|
<% end -%>
|
20
27
|
end
|
@@ -1,17 +1,26 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
# TODO: move it to spec_helper
|
3
|
+
require "tram/policy/rspec"
|
2
4
|
|
3
|
-
RSpec.describe <%= klass %>, "
|
4
|
-
|
5
|
-
|
5
|
+
RSpec.describe <%= klass %>, ".[]" do
|
6
|
+
# TODO: either remove this line, or set another source for available locales
|
7
|
+
let(:available_locales) { I18n.available_locales }
|
6
8
|
<% (parsed_params + parsed_options).each do |name| -%>
|
7
9
|
let(:<%= name %>) { FactoryGirl.build :<%= name %> }
|
8
10
|
<% end -%>
|
9
11
|
|
10
|
-
it
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
it "is valid with proper arguments" do
|
13
|
+
expect { described_class[<%= policy_signature %>] }.not_to be_invalid_at
|
14
|
+
end
|
15
|
+
<% parsed_validators.each do |v| %>
|
16
|
+
# TODO: fix default description
|
17
|
+
it "is invalid when <%= "not " if v[:key] == v[:name] %><%= v[:key] %>" do
|
18
|
+
# TODO: modify some arguments
|
19
|
+
<% (parsed_params + parsed_options).each do |name| -%>
|
20
|
+
<%= name %> = nil
|
21
|
+
<% end -%>
|
22
|
+
# TODO: add necessary tags to focus the condition
|
23
|
+
expect { described_class[<%= policy_signature %>] }.to be_invalid_at
|
15
24
|
end
|
16
25
|
<% end -%>
|
17
26
|
end
|
@@ -36,9 +36,13 @@ RSpec::Matchers.define :be_invalid_at do |**tags|
|
|
36
36
|
|
37
37
|
# Runs block in every available locale
|
38
38
|
def in_available_locales
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
locales = if respond_to?(:available_locales)
|
40
|
+
available_locales
|
41
|
+
else
|
42
|
+
I18n.available_locales
|
43
|
+
end
|
44
|
+
|
45
|
+
locales.flat_map { |locale| I18n.with_locale(locale) { yield } }
|
42
46
|
end
|
43
47
|
|
44
48
|
# Collects results for the current locale
|
@@ -67,7 +71,7 @@ RSpec::Matchers.define :be_invalid_at do |**tags|
|
|
67
71
|
# Checks if all collected errors are translated
|
68
72
|
def translated?
|
69
73
|
texts = errors.values.flatten.map(&:message)
|
70
|
-
texts.select { |text| text.start_with?("translation missing
|
74
|
+
texts.select { |text| text.start_with?("translation missing") }.empty?
|
71
75
|
end
|
72
76
|
|
73
77
|
def report_errors
|
@@ -89,7 +93,8 @@ RSpec::Matchers.define :be_invalid_at do |**tags|
|
|
89
93
|
end
|
90
94
|
|
91
95
|
failure_message do |_|
|
92
|
-
text = "
|
96
|
+
text = "The policy: #{policy}\n"
|
97
|
+
text << "should have had errors with tags: #{tags}, "
|
93
98
|
text << "whose messages are translated in all available locales.\n"
|
94
99
|
text << report_errors
|
95
100
|
text
|
@@ -105,8 +110,22 @@ RSpec::Matchers.define :be_invalid_at do |**tags|
|
|
105
110
|
end
|
106
111
|
|
107
112
|
failure_message_when_negated do |_|
|
108
|
-
text = "#{policy}
|
113
|
+
text = "#{policy}\nshould not have had any error with tags: #{tags}.\n"
|
109
114
|
text << report_errors
|
110
115
|
text
|
111
116
|
end
|
112
117
|
end
|
118
|
+
|
119
|
+
RSpec.shared_examples :invalid_policy do |condition = nil, **tags|
|
120
|
+
constraint = "with tags: #{tags}" if tags.any?
|
121
|
+
it ["is invalid", condition, constraint].compact.join(" ") do
|
122
|
+
expect { subject }.to be_invalid_at(tags)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
RSpec.shared_examples :valid_policy do |condition = nil, **tags|
|
127
|
+
constraint = "with tags: #{tags}" if tags.any?
|
128
|
+
it ["is valid", condition, constraint].compact.join(" ") do
|
129
|
+
expect { subject }.not_to be_invalid_at(tags)
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Tram::Policy
|
2
|
+
# Describes a validator
|
3
|
+
class Validator
|
4
|
+
attr_reader :name, :stop_on_failure
|
5
|
+
|
6
|
+
def ==(other)
|
7
|
+
other.is_a?(self.class) && other.name == name
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def initialize(name, stop_on_failure: false)
|
13
|
+
@name = name.to_sym
|
14
|
+
@stop_on_failure = stop_on_failure
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,7 @@ rescue
|
|
5
5
|
end
|
6
6
|
require "bundler/setup"
|
7
7
|
require "tram/policy"
|
8
|
-
require "tram/policy/
|
8
|
+
require "tram/policy/rspec"
|
9
9
|
require "rspec/its"
|
10
10
|
|
11
11
|
RSpec.configure do |config|
|
@@ -19,9 +19,6 @@ RSpec.configure do |config|
|
|
19
19
|
config.run_all_when_everything_filtered = true
|
20
20
|
|
21
21
|
# Prepare the Test namespace for constants defined in specs
|
22
|
-
config.
|
23
|
-
|
24
|
-
example.run
|
25
|
-
Object.send :remove_const, :Test
|
26
|
-
end
|
22
|
+
config.before(:each) { Test = Class.new(Module) }
|
23
|
+
config.after(:each) { Object.send :remove_const, :Test }
|
27
24
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
RSpec.describe "RSpec
|
1
|
+
RSpec.describe "RSpec support:" do
|
2
2
|
subject { Test::UserPolicy[name: nil] }
|
3
3
|
|
4
4
|
before do
|
@@ -67,4 +67,12 @@ RSpec.describe "RSpec matchers:" do
|
|
67
67
|
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
describe "shared examples" do
|
72
|
+
it_behaves_like :invalid_policy
|
73
|
+
it_behaves_like :invalid_policy, field: "name" do
|
74
|
+
before { I18n.available_locales = %i[en ru] }
|
75
|
+
end
|
76
|
+
it_behaves_like :valid_policy, field: "email"
|
77
|
+
end
|
70
78
|
end
|
data/spec/tram/policy_spec.rb
CHANGED
@@ -5,7 +5,9 @@ RSpec.describe Tram::Policy do
|
|
5
5
|
class Test::UserPolicy < Tram::Policy
|
6
6
|
param :user
|
7
7
|
|
8
|
-
validate :name
|
8
|
+
validate :name
|
9
|
+
validate "email"
|
10
|
+
validate "name"
|
9
11
|
|
10
12
|
private
|
11
13
|
|
@@ -53,6 +55,26 @@ RSpec.describe Tram::Policy do
|
|
53
55
|
|
54
56
|
Test::AdminPolicy.new(user)
|
55
57
|
end
|
58
|
+
|
59
|
+
context "when :stop_on_failure is set" do
|
60
|
+
before { Test::UserPolicy.validate :name, stop_on_failure: true }
|
61
|
+
|
62
|
+
it "stops validation after failure" do
|
63
|
+
expect(user).to receive(:name).once
|
64
|
+
expect(user).not_to receive(:email)
|
65
|
+
|
66
|
+
Test::UserPolicy.new(user)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "continues validation after success" do
|
70
|
+
user = double :user, name: "Andy", email: nil, login: nil
|
71
|
+
|
72
|
+
expect(user).to receive(:name).once.ordered
|
73
|
+
expect(user).to receive(:email).once.ordered
|
74
|
+
|
75
|
+
Test::UserPolicy.new(user)
|
76
|
+
end
|
77
|
+
end
|
56
78
|
end
|
57
79
|
|
58
80
|
describe "#inspect" do
|
data/tram-policy.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "tram-policy"
|
3
|
-
gem.version = "0.0.
|
3
|
+
gem.version = "0.0.2"
|
4
4
|
gem.author = ["Viktor Sokolov (gzigzigzeo)", "Andrew Kozin (nepalez)"]
|
5
5
|
gem.email = ["andrew.kozin@gmail.com"]
|
6
6
|
gem.homepage = "https://github.com/tram/tram-policy"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tram-policy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Viktor Sokolov (gzigzigzeo)
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-04-
|
12
|
+
date: 2017-04-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dry-initializer
|
@@ -138,13 +138,14 @@ files:
|
|
138
138
|
- lib/tram/policy/generator/policy.erb
|
139
139
|
- lib/tram/policy/generator/policy_spec.erb
|
140
140
|
- lib/tram/policy/inflector.rb
|
141
|
-
- lib/tram/policy/
|
141
|
+
- lib/tram/policy/rspec.rb
|
142
142
|
- lib/tram/policy/validation_error.rb
|
143
|
+
- lib/tram/policy/validator.rb
|
143
144
|
- spec/spec_helper.rb
|
144
145
|
- spec/tram/policy/error_spec.rb
|
145
146
|
- spec/tram/policy/errors_spec.rb
|
146
147
|
- spec/tram/policy/inflector_spec.rb
|
147
|
-
- spec/tram/policy/
|
148
|
+
- spec/tram/policy/rspec_spec.rb
|
148
149
|
- spec/tram/policy/validation_error_spec.rb
|
149
150
|
- spec/tram/policy_spec.rb
|
150
151
|
- tram-policy.gemspec
|
@@ -177,6 +178,6 @@ test_files:
|
|
177
178
|
- spec/tram/policy/error_spec.rb
|
178
179
|
- spec/tram/policy/errors_spec.rb
|
179
180
|
- spec/tram/policy/inflector_spec.rb
|
180
|
-
- spec/tram/policy/
|
181
|
+
- spec/tram/policy/rspec_spec.rb
|
181
182
|
- spec/tram/policy/validation_error_spec.rb
|
182
183
|
- spec/tram/policy_spec.rb
|