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 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 true unless @options.key?(key)
28
+ return positive? unless @options.key?(key)
29
29
 
30
30
  if @options[key]
31
- return true if bad?(value, message_key)
32
- return false, :not => not_word
31
+ return bad?(value, message_key), :not => not_word
33
32
  else
34
- return true if good?(value, message_key)
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 true unless @options.key?(key)
44
+ return positive? unless @options.key?(key)
47
45
 
48
46
  if @options[key]
49
- return true if good?(value, message_key)
50
- return false, :not => ''
47
+ return good?(value, message_key), :not => ''
51
48
  else
52
- return true if bad?(value, message_key)
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 :is_protected?, :is_accessible?
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
- !@attributes.empty? || protected_attributes.empty?
16
+ def allows?
17
+ return positive? unless @attributes.empty?
18
+ protected_attributes.empty?
17
19
  end
18
20
 
19
- def is_protected?
20
- protected_attributes.empty? || !protected_attributes.include?(@attribute.to_s)
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
- accessible_attributes.empty? || accessible_attributes.include?(@attribute.to_s)
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
- { :protected_attributes => array_to_sentence(protected_attributes.to_a, false, '[]') }
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.each do |value|
32
- return false, :value => value.inspect unless good?(value)
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.each do |value|
39
- return false, :value => value.inspect unless bad?(value)
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
- elsif @options[:in].empty?
16
- []
17
- else
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
- default_options :message => :inclusion
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
- elsif @options[:in].empty?
20
- []
21
- else
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
- should_not_allow_mass_assignment_of :title, :another
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.7
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-05 00:00:00 +02:00
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.7
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: