remarkable_activerecord 3.1.7 → 3.1.8
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.
- 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:
|