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,9 +1,9 @@
1
- module Remarkable
1
+ module Remarkable
2
2
  module ActiveRecord
3
3
 
4
4
  def self.after_include(target) #:nodoc:
5
5
  target.class_inheritable_reader :describe_subject_attributes, :default_subject_attributes
6
- target.send :include, Describe
6
+ target.send :include, Describe
7
7
  end
8
8
 
9
9
  # Overwrites describe to provide quick way to configure your subject:
@@ -14,7 +14,7 @@ module Remarkable
14
14
  # describe :published => true do
15
15
  # should_validate_presence_of :published_at
16
16
  # end
17
- # end
17
+ # end
18
18
  #
19
19
  # This is the same as:
20
20
  #
@@ -27,11 +27,11 @@ module Remarkable
27
27
  # end
28
28
  # end
29
29
  #
30
- # The string can be localized using I18n. An example yml file is:
31
- #
32
- # locale:
33
- # remarkable:
34
- # active_record:
30
+ # The string can be localized using I18n. An example yml file is:
31
+ #
32
+ # locale:
33
+ # remarkable:
34
+ # active_record:
35
35
  # describe:
36
36
  # each: "{{key}} is {{value}}"
37
37
  # prepend: "when "
@@ -67,7 +67,7 @@ module Remarkable
67
67
 
68
68
  def self.included(base) #:nodoc:
69
69
  base.extend ClassMethods
70
- end
70
+ end
71
71
 
72
72
  module ClassMethods
73
73
 
@@ -79,7 +79,7 @@ module Remarkable
79
79
  # describe :published => true do
80
80
  # should_validate_presence_of :published_at
81
81
  # end
82
- # end
82
+ # end
83
83
  #
84
84
  # This is the same as:
85
85
  #
@@ -92,11 +92,11 @@ module Remarkable
92
92
  # end
93
93
  # end
94
94
  #
95
- # The string can be localized using I18n. An example yml file is:
96
- #
97
- # locale:
98
- # remarkable:
99
- # active_record:
95
+ # The string can be localized using I18n. An example yml file is:
96
+ #
97
+ # locale:
98
+ # remarkable:
99
+ # active_record:
100
100
  # describe:
101
101
  # each: "{{key}} is {{value}}"
102
102
  # prepend: "when "
@@ -104,7 +104,7 @@ module Remarkable
104
104
  #
105
105
  # See also subject_attributes instance and class methods for more
106
106
  # information.
107
- #
107
+ #
108
108
  def describe(*args, &block)
109
109
  if described_class && args.first.is_a?(Hash)
110
110
  attributes = args.shift
@@ -133,16 +133,16 @@ module Remarkable
133
133
  description << pieces.join(connector)
134
134
  args.unshift(description)
135
135
 
136
- # Creates an example group, set the subject and eval the given block.
137
- #
136
+ # Creates an example group, set the subject and eval the given block.
137
+ #
138
138
  example_group = super(*args) do
139
- write_inheritable_hash(:describe_subject_attributes, attributes)
140
- set_described_subject!
141
- instance_eval(&block)
142
- end
143
- else
144
- super(*args, &block)
145
- end
139
+ write_inheritable_hash(:describe_subject_attributes, attributes)
140
+ set_described_subject!
141
+ instance_eval(&block)
142
+ end
143
+ else
144
+ super(*args, &block)
145
+ end
146
146
  end
147
147
 
148
148
  # Sets default attributes for the subject. You can use this to set up
@@ -195,5 +195,5 @@ module Remarkable
195
195
  end
196
196
 
197
197
  end
198
- end
199
- end
198
+ end
199
+ end
@@ -1,37 +1,37 @@
1
- if defined?(Spec)
2
- module Spec #:nodoc:
3
- module Example #:nodoc:
4
- module ExampleGroupMethods #:nodoc:
5
-
6
- # This allows "describe User" to use the I18n human name of User.
7
- #
8
- def self.build_description_with_i18n(*args)
9
- args.inject("") do |description, arg|
10
- arg = if arg.respond_to?(:human_name)
11
- arg.human_name(:locale => Remarkable.locale)
12
- else
13
- arg.to_s
14
- end
15
-
16
- description << " " unless (description == "" || arg =~ /^(\s|\.|#)/)
17
- description << arg
18
- end
19
- end
20
-
21
- # This is for rspec <= 1.1.12.
22
- #
23
- def self.description_text(*args)
24
- self.build_description_with_i18n(*args)
25
- end
26
-
27
- # This is for rspec >= 1.2.0.
28
- #
1
+ if defined?(Spec)
2
+ module Spec #:nodoc:
3
+ module Example #:nodoc:
4
+ module ExampleGroupMethods #:nodoc:
5
+
6
+ # This allows "describe User" to use the I18n human name of User.
7
+ #
8
+ def self.build_description_with_i18n(*args)
9
+ args.inject("") do |description, arg|
10
+ arg = if arg.respond_to?(:human_name)
11
+ arg.human_name(:locale => Remarkable.locale)
12
+ else
13
+ arg.to_s
14
+ end
15
+
16
+ description << " " unless (description == "" || arg =~ /^(\s|\.|#)/)
17
+ description << arg
18
+ end
19
+ end
20
+
21
+ # This is for rspec <= 1.1.12.
22
+ #
23
+ def self.description_text(*args)
24
+ self.build_description_with_i18n(*args)
25
+ end
26
+
27
+ # This is for rspec >= 1.2.0.
28
+ #
29
29
  def self.build_description_from(*args)
30
- text = ExampleGroupMethods.build_description_with_i18n(*args)
31
- text == "" ? nil : text
32
- end
33
-
34
- end
35
- end
36
- end
37
- end
30
+ text = ExampleGroupMethods.build_description_with_i18n(*args)
31
+ text == "" ? nil : text
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,19 +1,19 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
4
- class AcceptNestedAttributesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class AcceptNestedAttributesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
5
  arguments :collection => :associations, :as => :association
6
-
6
+
7
7
  collection_assertions :association_exists?, :is_autosave?, :responds_to_attributes?,
8
- :allows_destroy?, :accepts?, :rejects?
9
-
8
+ :allows_destroy?, :accepts?, :rejects?
9
+
10
10
  optionals :allow_destroy, :default => true
11
11
  optionals :accept, :reject, :splat => true
12
-
13
- protected
14
-
15
- def association_exists?
16
- reflection
12
+
13
+ protected
14
+
15
+ def association_exists?
16
+ reflection
17
17
  end
18
18
 
19
19
  def is_autosave?
@@ -59,8 +59,8 @@ module Remarkable
59
59
 
60
60
  private
61
61
 
62
- def reflection
63
- @reflection ||= subject_class.reflect_on_association(@association.to_sym)
62
+ def reflection
63
+ @reflection ||= subject_class.reflect_on_association(@association.to_sym)
64
64
  end
65
65
 
66
66
  def reflection_type
@@ -75,17 +75,17 @@ module Remarkable
75
75
  def reject_if_proc
76
76
  subject_class.reject_new_nested_attributes_procs[@association.to_sym]
77
77
  end
78
-
79
- end
80
-
78
+
79
+ end
80
+
81
81
  # Ensures that the model accepts nested attributes for the given associations.
82
- #
83
- # == Options
84
- #
82
+ #
83
+ # == Options
84
+ #
85
85
  # * <tt>allow_destroy</tt> - When true allows the association to be destroyed
86
86
  # * <tt>accept</tt> - attributes that should be accepted by the :reject_if proc
87
- # * <tt>reject</tt> - attributes that should be rejected by the :reject_if proc
88
- #
87
+ # * <tt>reject</tt> - attributes that should be rejected by the :reject_if proc
88
+ #
89
89
  # == Examples
90
90
  #
91
91
  # should_accept_nested_attributes_for :tasks
@@ -120,11 +120,11 @@ module Remarkable
120
120
  # m.reject :title => nil
121
121
  # m.reject :title => ''
122
122
  # end
123
- #
124
- def accept_nested_attributes_for(*args, &block)
125
- AcceptNestedAttributesForMatcher.new(*args, &block).spec(self)
126
- end
127
-
128
- end
129
- end
130
- end
123
+ #
124
+ def accept_nested_attributes_for(*args, &block)
125
+ AcceptNestedAttributesForMatcher.new(*args, &block).spec(self)
126
+ end
127
+
128
+ end
129
+ end
130
+ end
@@ -1,66 +1,66 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
4
  class AllowMassAssignmentOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
- include Remarkable::Negative
6
- arguments :collection => :attributes, :as => :attribute
7
-
8
- assertion :allows?
9
- collection_assertions :is_accessible?, :is_protected?
10
-
11
- protected
12
-
13
- # If no attribute is given, check if no attribute is being protected,
14
- # otherwise it fails.
15
- #
5
+ include Remarkable::Negative
6
+ arguments :collection => :attributes, :as => :attribute
7
+
8
+ assertion :allows?
9
+ collection_assertions :is_accessible?, :is_protected?
10
+
11
+ protected
12
+
13
+ # If no attribute is given, check if no attribute is being protected,
14
+ # otherwise it fails.
15
+ #
16
16
  def allows?
17
- return positive? unless @attributes.empty?
18
- protected_attributes.empty?
19
- end
20
-
21
- def is_protected?
22
- return positive? if protected_attributes.empty?
23
- !protected_attributes.include?(@attribute.to_s)
24
- end
25
-
17
+ return positive? unless @attributes.empty?
18
+ protected_attributes.empty?
19
+ end
20
+
26
21
  def is_accessible?
27
- return positive? if accessible_attributes.empty?
28
- accessible_attributes.include?(@attribute.to_s)
29
- end
30
-
31
- def interpolation_options
22
+ return positive? if accessible_attributes.empty?
23
+ accessible_attributes.include?(@attribute.to_s)
24
+ end
25
+
26
+ def is_protected?
27
+ return accessible_attributes.empty? || positive? if protected_attributes.empty?
28
+ !protected_attributes.include?(@attribute.to_s)
29
+ end
30
+
31
+ def interpolation_options
32
32
  if @subject
33
- if positive?
33
+ if positive?
34
34
  { :protected_attributes => array_to_sentence(protected_attributes.to_a, false, '[]') }
35
35
  else
36
36
  { :accessible_attributes => array_to_sentence(accessible_attributes.to_a, false, '[]') }
37
- end
38
- else
39
- {}
40
- end
41
- end
42
-
43
- private
44
-
45
- def accessible_attributes
46
- @accessible_attributes ||= subject_class.accessible_attributes || []
47
- end
48
-
49
- def protected_attributes
50
- @protected_attributes ||= subject_class.protected_attributes || []
51
- end
52
- end
53
-
54
- # Ensures that the attribute can be set on mass update.
55
- #
56
- # == Examples
57
- #
58
- # should_allow_mass_assignment_of :email, :name
59
- # it { should allow_mass_assignment_of(:email, :name) }
60
- #
61
- def allow_mass_assignment_of(*attributes, &block)
62
- AllowMassAssignmentOfMatcher.new(*attributes, &block).spec(self)
63
- end
64
- end
65
- end
66
- end
37
+ end
38
+ else
39
+ {}
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def accessible_attributes
46
+ @accessible_attributes ||= subject_class.accessible_attributes || []
47
+ end
48
+
49
+ def protected_attributes
50
+ @protected_attributes ||= subject_class.protected_attributes || []
51
+ end
52
+ end
53
+
54
+ # Ensures that the attribute can be set on mass update.
55
+ #
56
+ # == Examples
57
+ #
58
+ # should_allow_mass_assignment_of :email, :name
59
+ # it { should allow_mass_assignment_of(:email, :name) }
60
+ #
61
+ def allow_mass_assignment_of(*attributes, &block)
62
+ AllowMassAssignmentOfMatcher.new(*attributes, &block).spec(self)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,97 +1,88 @@
1
- module Remarkable
2
- module ActiveRecord
3
- module Matchers
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
4
  class AllowValuesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
- include Remarkable::Negative
6
- arguments :collection => :attributes, :as => :attribute
7
-
8
- optional :message
9
- optional :in, :splat => true
10
- optional :allow_nil, :allow_blank, :default => true
11
-
12
- collection_assertions :is_valid?, :is_invalid?, :allow_nil?, :allow_blank?
13
-
14
- default_options :message => :invalid
15
-
16
- before_assert do
17
- first_value = @options[:in].is_a?(Array) ? @options[:in].first : @options[:in]
18
- @in_range = first_value.is_a?(Range)
19
-
20
- @options[:in] = if @in_range
21
- first_value.to_a[0,2] + first_value.to_a[-2,2]
22
- else
23
- [*@options[:in]].compact
24
- end
25
-
26
- @options[:in].uniq!
27
- end
28
-
29
- protected
30
-
5
+ include Remarkable::Negative
6
+ arguments :collection => :attributes, :as => :attribute
7
+
8
+ optional :message
9
+ optional :in, :splat => true
10
+ optional :allow_nil, :allow_blank, :default => true
11
+
12
+ collection_assertions :is_valid?, :is_invalid?, :allow_nil?, :allow_blank?
13
+
14
+ default_options :message => /.*/
15
+
16
+ before_assert do
17
+ first_value = @options[:in].is_a?(Array) ? @options[:in].first : @options[:in]
18
+ @in_range = first_value.is_a?(Range)
19
+
20
+ @options[:in] = if @in_range
21
+ first_value.to_a[0,2] + first_value.to_a[-2,2]
22
+ else
23
+ [*@options[:in]].compact
24
+ end
25
+
26
+ @options[:in].uniq!
27
+ end
28
+
29
+ protected
30
+
31
31
  def is_valid?
32
- assert_collection :value, valid_values do |value|
33
- good?(value)
34
- end
35
- end
36
-
32
+ assert_collection :value, valid_values do |value|
33
+ good?(value)
34
+ end
35
+ end
36
+
37
37
  def is_invalid?
38
- assert_collection :value, invalid_values do |value|
39
- bad?(value)
40
- end
41
- end
42
-
43
- def valid_values
44
- @options[:in]
45
- end
46
-
47
- def invalid_values
48
- []
49
- end
50
-
51
- def interpolation_options
52
- options = if @in_range
53
- { :in => (@options[:in].first..@options[:in].last).inspect }
54
- elsif @options[:in].is_a?(Array)
55
- { :in => array_to_sentence(@options[:in], true, '[]') }
56
- else
57
- { :in => @options[:in].inspect }
58
- end
59
-
60
- options.merge!(:behavior => @behavior.to_s)
61
- end
62
-
63
- end
64
-
65
- # Ensures that the attribute can be set to the given values.
66
- #
67
- # == Options
68
- #
69
- # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
70
- # * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
71
- # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
72
- # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
73
- #
74
- # == Examples
75
- #
76
- # should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
77
- # it { should allow_values_for(:isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0") }
78
- #
79
- def allow_values_for(attribute, *args, &block)
80
- options = args.extract_options!
81
- AllowValuesForMatcher.new(attribute, options.merge!(:in => args), &block).spec(self)
82
- end
83
-
84
- # Deprecated. Use allow_values_for instead.
85
- #
86
- def validate_format_of(*args)
87
- if caller[0] =~ /\macros.rb/
88
- warn "[DEPRECATION] should_validate_format_of is deprecated, use should_allow_values_for instead."
89
- else
90
- warn "[DEPRECATION] validate_format_of is deprecated, use allow_values_for instead. Called from #{caller[0]}."
91
- end
92
- allow_values_for(*args)
93
- end
94
-
95
- end
96
- end
97
- end
38
+ assert_collection :value, invalid_values do |value|
39
+ bad?(value)
40
+ end
41
+ end
42
+
43
+ def valid_values
44
+ @options[:in]
45
+ end
46
+
47
+ def invalid_values
48
+ []
49
+ end
50
+
51
+ def interpolation_options
52
+ options = if @in_range
53
+ { :in => (@options[:in].first..@options[:in].last).inspect }
54
+ elsif @options[:in].is_a?(Array)
55
+ { :in => array_to_sentence(@options[:in], true, '[]') }
56
+ else
57
+ { :in => @options[:in].inspect }
58
+ end
59
+
60
+ options.merge!(:behavior => @behavior.to_s)
61
+ end
62
+
63
+ end
64
+
65
+ # Ensures that the attribute can be set to the given values. It checks
66
+ # for any message in the given attribute unless a :message is explicitely
67
+ # given.
68
+ #
69
+ # == Options
70
+ #
71
+ # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
72
+ # * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
73
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
74
+ # Regexp, string or symbol. Default = <tt>/.*/</tt>
75
+ #
76
+ # == Examples
77
+ #
78
+ # should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
79
+ # it { should allow_values_for(:isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0") }
80
+ #
81
+ def allow_values_for(attribute, *args, &block)
82
+ options = args.extract_options!
83
+ AllowValuesForMatcher.new(attribute, options.merge!(:in => args), &block).spec(self)
84
+ end
85
+
86
+ end
87
+ end
88
+ end