remarkable_activerecord 3.1.8 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
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