remarkable_activerecord 3.1.7 → 3.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/lib/remarkable_activerecord/base.rb +15 -19
- data/lib/remarkable_activerecord/matchers/allow_mass_assignment_of_matcher.rb +19 -24
- data/lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb +9 -22
- data/lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb +5 -4
- data/lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb +7 -6
- data/locale/en.yml +7 -3
- data/spec/allow_mass_assignment_of_matcher_spec.rb +18 -1
- data/spec/allow_values_for_matcher_spec.rb +10 -0
- data/spec/validate_inclusion_of_matcher_spec.rb +3 -0
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
* Allow booleans to be given to validate_inclusion_of [#89]
|
2
|
+
|
3
|
+
* Allow allow_values_for and allow_mass_assignment_of matchers to be executed in
|
4
|
+
the negative form by including Remarkable::Negative module [#85]
|
5
|
+
|
1
6
|
* Ensure quick subject bypass protected attributes [#87]
|
2
7
|
|
3
8
|
* Added :token and :separator to deal with :tokenizer in validates_length_of [#77]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Remarkable
|
2
2
|
module ActiveRecord
|
3
|
-
class Base < Remarkable::Base
|
3
|
+
class Base < Remarkable::Base
|
4
4
|
I18N_COLLECTION = [ :attributes, :associations ]
|
5
5
|
|
6
6
|
# Provides a way to send options to all ActiveRecord matchers.
|
@@ -25,14 +25,12 @@ module Remarkable
|
|
25
25
|
# and an @options key where the message to search for is.
|
26
26
|
#
|
27
27
|
def assert_bad_or_good_if_key(key, value, message_key=:message) #:nodoc:
|
28
|
-
return
|
28
|
+
return positive? unless @options.key?(key)
|
29
29
|
|
30
30
|
if @options[key]
|
31
|
-
return
|
32
|
-
return false, :not => not_word
|
31
|
+
return bad?(value, message_key), :not => not_word
|
33
32
|
else
|
34
|
-
return
|
35
|
-
return false, :not => ''
|
33
|
+
return good?(value, message_key), :not => ''
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
@@ -43,14 +41,12 @@ module Remarkable
|
|
43
41
|
# and an @options key where the message to search for is.
|
44
42
|
#
|
45
43
|
def assert_good_or_bad_if_key(key, value, message_key=:message) #:nodoc:
|
46
|
-
return
|
44
|
+
return positive? unless @options.key?(key)
|
47
45
|
|
48
46
|
if @options[key]
|
49
|
-
return
|
50
|
-
return false, :not => ''
|
47
|
+
return good?(value, message_key), :not => ''
|
51
48
|
else
|
52
|
-
return
|
53
|
-
return false, :not => not_word
|
49
|
+
return bad?(value, message_key), :not => not_word
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
@@ -212,8 +208,8 @@ module Remarkable
|
|
212
208
|
|
213
209
|
collection_name = self.class.matcher_arguments[:collection].to_sym
|
214
210
|
if collection = instance_variable_get("@#{collection_name}")
|
215
|
-
collection = collection.map do |attr|
|
216
|
-
described_class.human_attribute_name(attr.to_s, :locale => Remarkable.locale).downcase
|
211
|
+
collection = collection.map do |attr|
|
212
|
+
described_class.human_attribute_name(attr.to_s, :locale => Remarkable.locale).downcase
|
217
213
|
end
|
218
214
|
options[collection_name] = array_to_sentence(collection)
|
219
215
|
end
|
@@ -228,12 +224,12 @@ module Remarkable
|
|
228
224
|
else
|
229
225
|
super
|
230
226
|
end
|
231
|
-
end
|
232
|
-
|
233
|
-
# Returns true if the given collection should be translated.
|
234
|
-
#
|
235
|
-
def i18n_collection? #:nodoc:
|
236
|
-
RAILS_I18N && I18N_COLLECTION.include?(self.class.matcher_arguments[:collection])
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns true if the given collection should be translated.
|
230
|
+
#
|
231
|
+
def i18n_collection? #:nodoc:
|
232
|
+
RAILS_I18N && I18N_COLLECTION.include?(self.class.matcher_arguments[:collection])
|
237
233
|
end
|
238
234
|
|
239
235
|
end
|
@@ -1,32 +1,40 @@
|
|
1
1
|
module Remarkable
|
2
2
|
module ActiveRecord
|
3
3
|
module Matchers
|
4
|
-
class AllowMassAssignmentOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
4
|
+
class AllowMassAssignmentOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
+
include Remarkable::Negative
|
5
6
|
arguments :collection => :attributes, :as => :attribute
|
6
7
|
|
7
8
|
assertion :allows?
|
8
|
-
collection_assertions :
|
9
|
+
collection_assertions :is_accessible?, :is_protected?
|
9
10
|
|
10
11
|
protected
|
11
12
|
|
12
13
|
# If no attribute is given, check if no attribute is being protected,
|
13
14
|
# otherwise it fails.
|
14
15
|
#
|
15
|
-
def allows?
|
16
|
-
|
16
|
+
def allows?
|
17
|
+
return positive? unless @attributes.empty?
|
18
|
+
protected_attributes.empty?
|
17
19
|
end
|
18
20
|
|
19
|
-
def is_protected?
|
20
|
-
|
21
|
+
def is_protected?
|
22
|
+
return positive? if protected_attributes.empty?
|
23
|
+
!protected_attributes.include?(@attribute.to_s)
|
21
24
|
end
|
22
25
|
|
23
|
-
def is_accessible?
|
24
|
-
|
26
|
+
def is_accessible?
|
27
|
+
return positive? if accessible_attributes.empty?
|
28
|
+
accessible_attributes.include?(@attribute.to_s)
|
25
29
|
end
|
26
30
|
|
27
31
|
def interpolation_options
|
28
|
-
if @subject
|
29
|
-
|
32
|
+
if @subject
|
33
|
+
if positive?
|
34
|
+
{ :protected_attributes => array_to_sentence(protected_attributes.to_a, false, '[]') }
|
35
|
+
else
|
36
|
+
{ :accessible_attributes => array_to_sentence(accessible_attributes.to_a, false, '[]') }
|
37
|
+
end
|
30
38
|
else
|
31
39
|
{}
|
32
40
|
end
|
@@ -43,20 +51,7 @@ module Remarkable
|
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
|
-
# Ensures that the attribute can be set on mass update.
|
47
|
-
#
|
48
|
-
# Beware that when used in the negative form, this matcher fails if any of
|
49
|
-
# the values fail. For example, let's assume we have a accessible and a
|
50
|
-
# protected attribute called :accessible and :protected. The following
|
51
|
-
# assertion WILL pass:
|
52
|
-
#
|
53
|
-
# should_not_allow_mass_assignment_of :protected, :accessible
|
54
|
-
#
|
55
|
-
# If you want to assert that all values fail, you have to do:
|
56
|
-
#
|
57
|
-
# %w(first_protected second_protected).each do |protected|
|
58
|
-
# should_not_allow_mass_assignment_of protected
|
59
|
-
# end
|
54
|
+
# Ensures that the attribute can be set on mass update.
|
60
55
|
#
|
61
56
|
# == Examples
|
62
57
|
#
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Remarkable
|
2
2
|
module ActiveRecord
|
3
3
|
module Matchers
|
4
|
-
class AllowValuesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
4
|
+
class AllowValuesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
+
include Remarkable::Negative
|
5
6
|
arguments :collection => :attributes, :as => :attribute
|
6
7
|
|
7
8
|
optional :message
|
@@ -27,18 +28,16 @@ module Remarkable
|
|
27
28
|
|
28
29
|
protected
|
29
30
|
|
30
|
-
def is_valid?
|
31
|
-
valid_values
|
32
|
-
|
31
|
+
def is_valid?
|
32
|
+
assert_collection :value, valid_values do |value|
|
33
|
+
good?(value)
|
33
34
|
end
|
34
|
-
true
|
35
35
|
end
|
36
36
|
|
37
|
-
def is_invalid?
|
38
|
-
invalid_values
|
39
|
-
|
37
|
+
def is_invalid?
|
38
|
+
assert_collection :value, invalid_values do |value|
|
39
|
+
bad?(value)
|
40
40
|
end
|
41
|
-
true
|
42
41
|
end
|
43
42
|
|
44
43
|
def valid_values
|
@@ -63,19 +62,7 @@ module Remarkable
|
|
63
62
|
|
64
63
|
end
|
65
64
|
|
66
|
-
# Ensures that the attribute can be set to the given values.
|
67
|
-
#
|
68
|
-
# Beware that when used in the negative form, this matcher fails if any of
|
69
|
-
# the values fail. For example, let's assume we have a valid and invalid
|
70
|
-
# value called "valid" and "invalid". The following assertion WILL pass:
|
71
|
-
#
|
72
|
-
# should_not_allow_values_for :attribute, "valid", "invalid"
|
73
|
-
#
|
74
|
-
# If you want to assert that all values fail, you have to do:
|
75
|
-
#
|
76
|
-
# %w(first_invalid second_invalid).each do |invalid|
|
77
|
-
# should_not_allow_values_for invalid
|
78
|
-
# end
|
65
|
+
# Ensures that the attribute can be set to the given values.
|
79
66
|
#
|
80
67
|
# == Options
|
81
68
|
#
|
@@ -4,6 +4,8 @@ module Remarkable
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Matchers
|
6
6
|
class ValidateExclusionOfMatcher < AllowValuesForMatcher #:nodoc:
|
7
|
+
# Don't allow it to behave in the negative way.
|
8
|
+
undef_method :does_not_match?
|
7
9
|
|
8
10
|
default_options :message => :exclusion
|
9
11
|
|
@@ -12,10 +14,9 @@ module Remarkable
|
|
12
14
|
def valid_values
|
13
15
|
if @in_range
|
14
16
|
[ @options[:in].first - 1, @options[:in].last + 1 ]
|
15
|
-
|
16
|
-
[]
|
17
|
-
|
18
|
-
[ @options[:in].map(&:to_s).max.to_s.next ]
|
17
|
+
else
|
18
|
+
value = @options[:in].select{ |i| i.is_a?(String) }.max
|
19
|
+
value ? [ value.next ] : []
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -4,8 +4,10 @@ module Remarkable
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Matchers
|
6
6
|
class ValidateInclusionOfMatcher < AllowValuesForMatcher #:nodoc:
|
7
|
-
|
8
|
-
|
7
|
+
# Don't allow it to behave in the negative way.
|
8
|
+
undef_method :does_not_match?
|
9
|
+
|
10
|
+
default_options :message => :inclusion
|
9
11
|
|
10
12
|
protected
|
11
13
|
|
@@ -16,10 +18,9 @@ module Remarkable
|
|
16
18
|
def invalid_values
|
17
19
|
if @in_range
|
18
20
|
[ @options[:in].first - 1, @options[:in].last + 1 ]
|
19
|
-
|
20
|
-
[]
|
21
|
-
|
22
|
-
[ @options[:in].map(&:to_s).max.to_s.next ]
|
21
|
+
else
|
22
|
+
value = @options[:in].select{ |i| i.is_a?(String) }.max
|
23
|
+
value ? [ value.next ] : []
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
data/locale/en.yml
CHANGED
@@ -7,7 +7,7 @@ en:
|
|
7
7
|
connector: " and "
|
8
8
|
expectations:
|
9
9
|
allow_nil: "{{subject_name}} to {{not}}allow nil values for {{attribute}}"
|
10
|
-
allow_blank: "{{subject_name}} to {{not}}allow blank values for {{attribute}}"
|
10
|
+
allow_blank: "{{subject_name}} to {{not}}allow blank values for {{attribute}}"
|
11
11
|
optionals:
|
12
12
|
allow_nil:
|
13
13
|
positive: "allowing nil values"
|
@@ -37,14 +37,18 @@ en:
|
|
37
37
|
allow_values_for:
|
38
38
|
description: "allow {{in}} as values for {{attributes}}"
|
39
39
|
expectations:
|
40
|
-
is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
|
40
|
+
is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
|
41
41
|
|
42
42
|
allow_mass_assignment_of:
|
43
43
|
description: "allow mass assignment of {{attributes}}"
|
44
44
|
expectations:
|
45
45
|
allows: "{{subject_name}} to allow mass assignment ({{subject_name}} is protecting {{protected_attributes}})"
|
46
46
|
is_protected: "{{subject_name}} to allow mass assignment of {{attribute}} ({{subject_name}} is protecting {{attribute}})"
|
47
|
-
is_accessible: "{{subject_name}} to allow mass assignment of {{attribute}} ({{subject_name}} has not made {{attribute}} accessible)"
|
47
|
+
is_accessible: "{{subject_name}} to allow mass assignment of {{attribute}} ({{subject_name}} has not made {{attribute}} accessible)"
|
48
|
+
negative_expectations:
|
49
|
+
allows: "{{subject_name}} to allow mass assignment ({{subject_name}} made {{accessible_attributes}} accessible)"
|
50
|
+
is_protected: "{{subject_name}} to allow mass assignment of {{attribute}} ({{subject_name}} is not protecting {{attribute}})"
|
51
|
+
is_accessible: "{{subject_name}} to allow mass assignment of {{attribute}} ({{subject_name}} has made {{attribute}} accessible)"
|
48
52
|
|
49
53
|
association:
|
50
54
|
belongs_to: belong to
|
@@ -75,7 +75,24 @@ describe 'allow_mass_assignment_of' do
|
|
75
75
|
should_allow_mass_assignment_of :title, :category
|
76
76
|
|
77
77
|
should_not_allow_mass_assignment_of :another
|
78
|
-
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'failures' do
|
81
|
+
it "should fail if not all attributes are accessible on should not" do
|
82
|
+
define_and_validate(:accessible => true)
|
83
|
+
|
84
|
+
lambda {
|
85
|
+
should_not allow_mass_assignment_of :title, :another
|
86
|
+
}.should raise_error(Spec::Expectations::ExpectationNotMetError, /Product has made title accessible/)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should fail if accessible when protecting" do
|
90
|
+
define_and_validate(:accessible => true)
|
91
|
+
|
92
|
+
lambda {
|
93
|
+
should_not allow_mass_assignment_of
|
94
|
+
}.should raise_error(Spec::Expectations::ExpectationNotMetError, /Product made category and title accessible/)
|
95
|
+
end
|
79
96
|
end
|
80
97
|
end
|
81
98
|
|
@@ -56,6 +56,16 @@ describe 'allow_values_for' do
|
|
56
56
|
it { should validate_format_of(:title, 'X') }
|
57
57
|
should_not_validate_format_of :title, 'A'
|
58
58
|
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'failures' do
|
62
|
+
it "should fail if any of the values are valid on invalid cases" do
|
63
|
+
define_and_validate(:with => /X|Y|Z/)
|
64
|
+
|
65
|
+
lambda {
|
66
|
+
should_not allow_values_for :title, 'A', 'X', 'B'
|
67
|
+
}.should raise_error(Spec::Expectations::ExpectationNotMetError, /Did not expect Product to be valid/)
|
68
|
+
end
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
@@ -49,6 +49,9 @@ describe 'validate_inclusion_of' do
|
|
49
49
|
it { should_not define_and_validate(:in => ['X', 'Y', 'Z']).in('X', 'Y') }
|
50
50
|
it { should_not define_and_validate(:in => ['X', 'Y', 'Z']).in('A') }
|
51
51
|
|
52
|
+
it { should define_and_validate(:in => [true, false]).in(true, false) }
|
53
|
+
it { should_not define_and_validate(:in => [true, false]).in('A') }
|
54
|
+
|
52
55
|
it { should define_and_validate(:in => 2..3).in(2..3) }
|
53
56
|
it { should define_and_validate(:in => 2..20).in(2..20) }
|
54
57
|
it { should_not define_and_validate(:in => 2..20).in(1..20) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remarkable_activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Brando
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-07-
|
14
|
+
date: 2009-07-16 00:00:00 +02:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - ">="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 3.1.
|
35
|
+
version: 3.1.8
|
36
36
|
version:
|
37
37
|
description: "Remarkable ActiveRecord: collection of matchers and macros with I18n for ActiveRecord"
|
38
38
|
email:
|