remarkable_activerecord 3.1.8 → 3.1.9

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.
Files changed (48) hide show
  1. data/CHANGELOG +140 -138
  2. data/LICENSE +20 -20
  3. data/README +80 -80
  4. data/lib/remarkable_activerecord.rb +29 -29
  5. data/lib/remarkable_activerecord/base.rb +248 -237
  6. data/lib/remarkable_activerecord/describe.rb +27 -27
  7. data/lib/remarkable_activerecord/human_names.rb +36 -36
  8. data/lib/remarkable_activerecord/matchers/accept_nested_attributes_for_matcher.rb +30 -30
  9. data/lib/remarkable_activerecord/matchers/allow_mass_assignment_of_matcher.rb +59 -59
  10. data/lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb +85 -94
  11. data/lib/remarkable_activerecord/matchers/association_matcher.rb +283 -283
  12. data/lib/remarkable_activerecord/matchers/have_column_matcher.rb +68 -68
  13. data/lib/remarkable_activerecord/matchers/have_default_scope_matcher.rb +38 -38
  14. data/lib/remarkable_activerecord/matchers/have_index_matcher.rb +73 -73
  15. data/lib/remarkable_activerecord/matchers/have_readonly_attributes_matcher.rb +30 -30
  16. data/lib/remarkable_activerecord/matchers/have_scope_matcher.rb +85 -85
  17. data/lib/remarkable_activerecord/matchers/validate_acceptance_of_matcher.rb +50 -50
  18. data/lib/remarkable_activerecord/matchers/validate_associated_matcher.rb +97 -97
  19. data/lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb +44 -44
  20. data/lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb +53 -53
  21. data/lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb +52 -52
  22. data/lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb +150 -150
  23. data/lib/remarkable_activerecord/matchers/validate_numericality_of_matcher.rb +181 -181
  24. data/lib/remarkable_activerecord/matchers/validate_presence_of_matcher.rb +29 -29
  25. data/lib/remarkable_activerecord/matchers/validate_uniqueness_of_matcher.rb +233 -233
  26. data/locale/en.yml +261 -261
  27. data/spec/accept_nested_attributes_for_matcher_spec.rb +1 -1
  28. data/spec/allow_mass_assignment_of_matcher_spec.rb +90 -82
  29. data/spec/allow_values_for_matcher_spec.rb +72 -63
  30. data/spec/association_matcher_spec.rb +612 -612
  31. data/spec/describe_spec.rb +3 -3
  32. data/spec/have_column_matcher_spec.rb +73 -73
  33. data/spec/have_default_scope_matcher_spec.rb +1 -1
  34. data/spec/have_index_matcher_spec.rb +87 -87
  35. data/spec/have_readonly_attributes_matcher_spec.rb +47 -47
  36. data/spec/have_scope_matcher_spec.rb +77 -77
  37. data/spec/model_builder.rb +101 -101
  38. data/spec/rcov.opts +1 -1
  39. data/spec/spec.opts +4 -4
  40. data/spec/spec_helper.rb +27 -27
  41. data/spec/validate_acceptance_of_matcher_spec.rb +68 -68
  42. data/spec/validate_associated_matcher_spec.rb +121 -121
  43. data/spec/validate_confirmation_of_matcher_spec.rb +58 -58
  44. data/spec/validate_length_of_matcher_spec.rb +218 -218
  45. data/spec/validate_numericality_of_matcher_spec.rb +179 -179
  46. data/spec/validate_presence_of_matcher_spec.rb +56 -56
  47. data/spec/validate_uniqueness_of_matcher_spec.rb +164 -164
  48. metadata +5 -5
@@ -1,50 +1,50 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
4
- class ValidateAcceptanceOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
- arguments :collection => :attributes, :as => :attribute
6
-
7
- optional :accept, :message
8
- optional :allow_nil, :default => true
9
-
10
- collection_assertions :requires_acceptance?, :accept_is_valid?, :allow_nil?
11
-
12
- default_options :message => :accepted
13
-
14
- protected
15
-
16
- def requires_acceptance?
17
- bad?(false)
18
- end
19
-
20
- def accept_is_valid?
21
- return true unless @options.key?(:accept)
22
- good?(@options[:accept])
23
- end
24
-
25
- end
26
-
27
- # Ensures that the model cannot be saved if one of the attributes listed is not accepted.
28
- #
29
- # == Options
30
- #
31
- # * <tt>:accept</tt> - the expected value to be accepted.
32
- # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
33
- # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
34
- # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
35
- #
36
- # == Examples
37
- #
38
- # should_validate_acceptance_of :eula, :terms
39
- # should_validate_acceptance_of :eula, :terms, :accept => true
40
- #
41
- # it { should validate_acceptance_of(:eula, :terms) }
42
- # it { should validate_acceptance_of(:eula, :terms, :accept => true) }
43
- #
44
- def validate_acceptance_of(*attributes, &block)
45
- ValidateAcceptanceOfMatcher.new(*attributes, &block).spec(self)
46
- end
47
-
48
- end
49
- end
50
- end
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class ValidateAcceptanceOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
+ arguments :collection => :attributes, :as => :attribute
6
+
7
+ optional :accept, :message
8
+ optional :allow_nil, :default => true
9
+
10
+ collection_assertions :requires_acceptance?, :accept_is_valid?, :allow_nil?
11
+
12
+ default_options :message => :accepted
13
+
14
+ protected
15
+
16
+ def requires_acceptance?
17
+ bad?(false)
18
+ end
19
+
20
+ def accept_is_valid?
21
+ return true unless @options.key?(:accept)
22
+ good?(@options[:accept])
23
+ end
24
+
25
+ end
26
+
27
+ # Ensures that the model cannot be saved if one of the attributes listed is not accepted.
28
+ #
29
+ # == Options
30
+ #
31
+ # * <tt>:accept</tt> - the expected value to be accepted.
32
+ # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
33
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
34
+ # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
35
+ #
36
+ # == Examples
37
+ #
38
+ # should_validate_acceptance_of :eula, :terms
39
+ # should_validate_acceptance_of :eula, :terms, :accept => true
40
+ #
41
+ # it { should validate_acceptance_of(:eula, :terms) }
42
+ # it { should validate_acceptance_of(:eula, :terms, :accept => true) }
43
+ #
44
+ def validate_acceptance_of(*attributes, &block)
45
+ ValidateAcceptanceOfMatcher.new(*attributes, &block).spec(self)
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -1,103 +1,103 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
4
- class ValidateAssociatedMatcher < Remarkable::ActiveRecord::Base #:nodoc:
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class ValidateAssociatedMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
5
  arguments :collection => :associations, :as => :association, :block => true
6
-
6
+
7
7
  optional :message
8
- optional :builder, :block => true
9
-
10
- collection_assertions :find_association?, :is_valid?
11
- default_options :message => :invalid
12
-
13
- protected
14
-
15
- def find_association?
16
- reflection = @subject.class.reflect_on_association(@association)
17
-
18
- raise ScriptError, "Could not find association #{@association} on #{subject_class}." unless reflection
19
-
20
- associated_object = if builder = @options[:builder] || @block
21
- builder.call(@subject)
22
- elsif [:belongs_to, :has_one].include?(reflection.macro)
23
- @subject.send(:"build_#{@association}") rescue nil
24
- else
25
- @subject.send(@association).build rescue nil
26
- end
27
-
28
- raise ScriptError, "The association object #{@association} could not be built. You can give me " <<
29
- ":builder as option or a block which returns an association." unless associated_object
30
-
31
- raise ScriptError, "The associated object #{@association} is not invalid. You can give me " <<
32
- ":builder as option or a block which returns an invalid association." if associated_object.save
33
-
34
- return true
35
- end
36
-
37
- def is_valid?
38
- return false if @subject.valid?
39
-
40
- error_message_to_expect = error_message_from_model(@subject, :base, @options[:message])
41
-
42
- # In Rails 2.1.2, the error on association returns a symbol (:invalid)
43
- # instead of the message, so we check this case here.
44
- @subject.errors.on(@association) == @options[:message] ||
45
- assert_contains(@subject.errors.on(@association), error_message_to_expect)
46
- end
47
- end
48
-
49
- # Ensures that the model is invalid if one of the associations given is
50
- # invalid. It tries to build the association automatically. In has_one
51
- # and belongs_to cases, it will build it like this:
52
- #
53
- # @model.build_association
54
- # @project.build_manager
55
- #
56
- # In has_many and has_and_belongs_to_many to cases it will build it like
57
- # this:
58
- #
59
- # @model.association.build
60
- # @project.tasks.build
61
- #
62
- # The object returned MUST be invalid and it's likely the case, since the
63
- # associated object is empty when calling build. However, if the associated
64
- # object has to be manipulated to be invalid, you will have to give :builder
65
- # as option or a block to manipulate it:
66
- #
67
- # should_validate_associated(:tasks) do |project|
68
- # project.tasks.build(:captcha => 'i_am_a_bot')
69
- # end
70
- #
71
- # In the case above, the associated object task is only invalid when the
72
- # captcha attribute is set. So we give a block to the matcher that tell
73
- # exactly how to build an invalid object.
74
- #
75
- # The example above can also be written as:
76
- #
77
- # should_validate_associated :tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }
78
- #
79
- # == Options
80
- #
81
- # * <tt>:builder</tt> - a proc to build the association
82
- #
83
- # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
84
- # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
85
- #
86
- # == Examples
87
- #
88
- # should_validate_associated :tasks
8
+ optional :builder, :block => true
9
+
10
+ collection_assertions :find_association?, :is_valid?
11
+ default_options :message => :invalid
12
+
13
+ protected
14
+
15
+ def find_association?
16
+ reflection = @subject.class.reflect_on_association(@association)
17
+
18
+ raise ScriptError, "Could not find association #{@association} on #{subject_class}." unless reflection
19
+
20
+ associated_object = if builder = @options[:builder] || @block
21
+ builder.call(@subject)
22
+ elsif [:belongs_to, :has_one].include?(reflection.macro)
23
+ @subject.send(:"build_#{@association}") rescue nil
24
+ else
25
+ @subject.send(@association).build rescue nil
26
+ end
27
+
28
+ raise ScriptError, "The association object #{@association} could not be built. You can give me " <<
29
+ ":builder as option or a block which returns an association." unless associated_object
30
+
31
+ raise ScriptError, "The associated object #{@association} is not invalid. You can give me " <<
32
+ ":builder as option or a block which returns an invalid association." if associated_object.save
33
+
34
+ return true
35
+ end
36
+
37
+ def is_valid?
38
+ return false if @subject.valid?
39
+
40
+ error_message_to_expect = error_message_from_model(@subject, :base, @options[:message])
41
+
42
+ # In Rails 2.1.2, the error on association returns a symbol (:invalid)
43
+ # instead of the message, so we check this case here.
44
+ @subject.errors.on(@association) == @options[:message] ||
45
+ assert_contains(@subject.errors.on(@association), error_message_to_expect)
46
+ end
47
+ end
48
+
49
+ # Ensures that the model is invalid if one of the associations given is
50
+ # invalid. It tries to build the association automatically. In has_one
51
+ # and belongs_to cases, it will build it like this:
52
+ #
53
+ # @model.build_association
54
+ # @project.build_manager
55
+ #
56
+ # In has_many and has_and_belongs_to_many to cases it will build it like
57
+ # this:
58
+ #
59
+ # @model.association.build
60
+ # @project.tasks.build
61
+ #
62
+ # The object returned MUST be invalid and it's likely the case, since the
63
+ # associated object is empty when calling build. However, if the associated
64
+ # object has to be manipulated to be invalid, you will have to give :builder
65
+ # as option or a block to manipulate it:
66
+ #
67
+ # should_validate_associated(:tasks) do |project|
68
+ # project.tasks.build(:captcha => 'i_am_a_bot')
69
+ # end
70
+ #
71
+ # In the case above, the associated object task is only invalid when the
72
+ # captcha attribute is set. So we give a block to the matcher that tell
73
+ # exactly how to build an invalid object.
74
+ #
75
+ # The example above can also be written as:
76
+ #
77
+ # should_validate_associated :tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }
78
+ #
79
+ # == Options
80
+ #
81
+ # * <tt>:builder</tt> - a proc to build the association
82
+ #
83
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
84
+ # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
85
+ #
86
+ # == Examples
87
+ #
88
+ # should_validate_associated :tasks
89
89
  # should_validate_associated :tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }
90
90
  #
91
91
  # should_validate_associated :tasks do |m|
92
92
  # m.builder { |p| p.tasks.build(:captcha => 'i_am_a_bot') }
93
- # end
94
- #
95
- # it { should validate_associated(:tasks) }
96
- # it { should validate_associated(:tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }) }
97
- #
98
- def validate_associated(*args, &block)
99
- ValidateAssociatedMatcher.new(*args, &block).spec(self)
100
- end
101
- end
102
- end
103
- end
93
+ # end
94
+ #
95
+ # it { should validate_associated(:tasks) }
96
+ # it { should validate_associated(:tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }) }
97
+ #
98
+ def validate_associated(*args, &block)
99
+ ValidateAssociatedMatcher.new(*args, &block).spec(self)
100
+ end
101
+ end
102
+ end
103
+ end
@@ -1,44 +1,44 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
4
- class ValidateConfirmationOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
- arguments :collection => :attributes, :as => :attribute
6
-
7
- optional :message
8
- collection_assertions :responds_to_confirmation?, :confirms?
9
-
10
- default_options :message => :confirmation
11
-
12
- protected
13
-
14
- def responds_to_confirmation?
15
- @subject.respond_to?(:"#{@attribute}_confirmation=")
16
- end
17
-
18
- def confirms?
19
- @subject.send(:"#{@attribute}_confirmation=", 'something')
20
- bad?('different')
21
- end
22
-
23
- end
24
-
25
- # Ensures that the model cannot be saved if one of the attributes is not confirmed.
26
- #
27
- # == Options
28
- #
29
- # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
30
- # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.confirmation')</tt>
31
- #
32
- # == Examples
33
- #
34
- # should_validate_confirmation_of :email, :password
35
- #
36
- # it { should validate_confirmation_of(:email, :password) }
37
- #
38
- def validate_confirmation_of(*attributes, &block)
39
- ValidateConfirmationOfMatcher.new(*attributes, &block).spec(self)
40
- end
41
-
42
- end
43
- end
44
- end
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class ValidateConfirmationOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
+ arguments :collection => :attributes, :as => :attribute
6
+
7
+ optional :message
8
+ collection_assertions :responds_to_confirmation?, :confirms?
9
+
10
+ default_options :message => :confirmation
11
+
12
+ protected
13
+
14
+ def responds_to_confirmation?
15
+ @subject.respond_to?(:"#{@attribute}_confirmation=")
16
+ end
17
+
18
+ def confirms?
19
+ @subject.send(:"#{@attribute}_confirmation=", 'something')
20
+ bad?('different')
21
+ end
22
+
23
+ end
24
+
25
+ # Ensures that the model cannot be saved if one of the attributes is not confirmed.
26
+ #
27
+ # == Options
28
+ #
29
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
30
+ # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.confirmation')</tt>
31
+ #
32
+ # == Examples
33
+ #
34
+ # should_validate_confirmation_of :email, :password
35
+ #
36
+ # it { should validate_confirmation_of(:email, :password) }
37
+ #
38
+ def validate_confirmation_of(*attributes, &block)
39
+ ValidateConfirmationOfMatcher.new(*attributes, &block).spec(self)
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -1,57 +1,57 @@
1
- require File.join(File.dirname(__FILE__), 'allow_values_for_matcher')
2
-
3
- module Remarkable
4
- module ActiveRecord
5
- module Matchers
6
- class ValidateExclusionOfMatcher < AllowValuesForMatcher #:nodoc:
1
+ require File.join(File.dirname(__FILE__), 'allow_values_for_matcher')
2
+
3
+ module Remarkable
4
+ module ActiveRecord
5
+ module Matchers
6
+ class ValidateExclusionOfMatcher < AllowValuesForMatcher #:nodoc:
7
7
  # Don't allow it to behave in the negative way.
8
8
  undef_method :does_not_match?
9
-
10
- default_options :message => :exclusion
11
-
12
- protected
13
-
14
- def valid_values
15
- if @in_range
16
- [ @options[:in].first - 1, @options[:in].last + 1 ]
9
+
10
+ default_options :message => :exclusion
11
+
12
+ protected
13
+
14
+ def valid_values
15
+ if @in_range
16
+ [ @options[:in].first - 1, @options[:in].last + 1 ]
17
17
  else
18
18
  value = @options[:in].select{ |i| i.is_a?(String) }.max
19
- value ? [ value.next ] : []
20
- end
21
- end
22
-
23
- def invalid_values
24
- @options[:in]
25
- end
26
-
27
- end
28
-
29
- # Ensures that given values are not valid for the attribute. If a range
30
- # is given, ensures that the attribute is not valid in the given range.
31
- #
32
- # If you give that :username does not accept ["admin", "user"], it will
33
- # test that "uses" (the next of the array max value) is allowed.
34
- #
35
- # == Options
36
- #
37
- # * <tt>:in</tt> - values to test exclusion.
38
- # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
39
- # * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
40
- # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
41
- # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.exclusion')</tt>
42
- #
43
- # == Examples
44
- #
45
- # it { should validate_exclusion_of(:username, :in => ["admin", "user"]) }
46
- # it { should validate_exclusion_of(:age, :in => 30..60) }
47
- #
48
- # should_validate_exclusion_of :username, :in => ["admin", "user"]
49
- # should_validate_exclusion_of :age, :in => 30..60
50
- #
51
- def validate_exclusion_of(*args, &block)
52
- ValidateExclusionOfMatcher.new(*args, &block).spec(self)
53
- end
54
-
55
- end
56
- end
57
- end
19
+ value ? [ value.next ] : []
20
+ end
21
+ end
22
+
23
+ def invalid_values
24
+ @options[:in]
25
+ end
26
+
27
+ end
28
+
29
+ # Ensures that given values are not valid for the attribute. If a range
30
+ # is given, ensures that the attribute is not valid in the given range.
31
+ #
32
+ # If you give that :username does not accept ["admin", "user"], it will
33
+ # test that "uses" (the next of the array max value) is allowed.
34
+ #
35
+ # == Options
36
+ #
37
+ # * <tt>:in</tt> - values to test exclusion.
38
+ # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
39
+ # * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
40
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
41
+ # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.exclusion')</tt>
42
+ #
43
+ # == Examples
44
+ #
45
+ # it { should validate_exclusion_of(:username, :in => ["admin", "user"]) }
46
+ # it { should validate_exclusion_of(:age, :in => 30..60) }
47
+ #
48
+ # should_validate_exclusion_of :username, :in => ["admin", "user"]
49
+ # should_validate_exclusion_of :age, :in => 30..60
50
+ #
51
+ def validate_exclusion_of(*args, &block)
52
+ ValidateExclusionOfMatcher.new(*args, &block).spec(self)
53
+ end
54
+
55
+ end
56
+ end
57
+ end