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,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