remarkable_activerecord 3.0.7 → 3.0.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,9 +1,15 @@
1
- * Allow all objects to be sent to have_scope (thanks to Szymon Nowak) [#53]
1
+ * Added accept_nested_attributes_for matcher [#39]
2
+
3
+ * Added have_default_scope matcher [#38]
4
+
5
+ * Allow :include, :join, :group and :having as quick accessors to have_scope matcher
6
+
7
+ * Allow all objects to be sent to have_scope (thanks to Szymon Nowak and Nolan Eakins) [#53]
2
8
 
3
9
  * Added support to sql options in association_matcher: select, conditions, include,
4
- group, having, order, limit and offset. [#48]
10
+ group, having, order, limit and offset, plus finder_sql and counter_sql. [#48]
5
11
 
6
- * :source and :source_type are not supported by association matcher [#47]
12
+ * :source and :source_type are now supported by association matcher [#47]
7
13
 
8
14
  * validate_inclusion_of became smarter since it now tests invalid values too [#36]
9
15
 
@@ -0,0 +1,121 @@
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class AcceptNestedAttributesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
+ arguments :collection => :associations, :as => :association
6
+
7
+ collection_assertions :association_exists?, :is_autosave?, :responds_to_attributes?,
8
+ :allows_destroy?, :accepts?, :rejects?
9
+
10
+ optionals :allow_destroy, :default => true
11
+ optionals :accept, :reject, :splat => true
12
+
13
+ protected
14
+
15
+ def association_exists?
16
+ reflection
17
+ end
18
+
19
+ def is_autosave?
20
+ reflection.options[:autosave] == true
21
+ end
22
+
23
+ def responds_to_attributes?
24
+ @subject.respond_to?(:"#{@association}_attributes=", true)
25
+ end
26
+
27
+ def allows_destroy?
28
+ return true unless @options.key?(:allow_destroy)
29
+
30
+ @subject.instance_eval <<-ALLOW_DESTROY
31
+ def assign_nested_attributes_for_#{reflection_type}_association(association, attrs, allow)
32
+ return allow
33
+ end
34
+ ALLOW_DESTROY
35
+
36
+ actual = @subject.send(:"#{@association}_attributes=", {})
37
+ return actual == @options[:allow_destroy], :actual => actual
38
+ end
39
+
40
+ def accepts?
41
+ return true unless @options.key?(:accept)
42
+
43
+ [@options[:accept]].flatten.each do |attributes|
44
+ return false, :attributes => attributes.inspect if reject_if_proc.call(attributes)
45
+ end
46
+
47
+ true
48
+ end
49
+
50
+ def rejects?
51
+ return true unless @options.key?(:reject)
52
+
53
+ [@options[:reject]].flatten.each do |attributes|
54
+ return false, :attributes => attributes.inspect unless reject_if_proc.call(attributes)
55
+ end
56
+
57
+ true
58
+ end
59
+
60
+ private
61
+
62
+ def reflection
63
+ @reflection ||= subject_class.reflect_on_association(@association.to_sym)
64
+ end
65
+
66
+ def reflection_type
67
+ case reflection.macro
68
+ when :has_one, :belongs_to
69
+ :one_to_one
70
+ when :has_many, :has_and_belongs_to_many
71
+ :collection
72
+ end
73
+ end
74
+
75
+ def reject_if_proc
76
+ subject_class.reject_new_nested_attributes_procs[@association.to_sym]
77
+ end
78
+
79
+ end
80
+
81
+ # Ensures that the model accepts nested attributes for the given associations.
82
+ #
83
+ # == Options
84
+ #
85
+ # * <tt>allow_destroy</tt> - When true allows the association to be destroyed
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
+ #
89
+ # == Examples
90
+ #
91
+ # should_accept_nested_attributes_for :tasks
92
+ # should_accept_nested_attributes_for :tasks, :allow_destroy => true
93
+ #
94
+ # :accept and :reject takes objects that are verified against the proc. So
95
+ # having a model:
96
+ #
97
+ # class Projects < ActiveRecord::Base
98
+ # has_many :tasks
99
+ # accepts_nested_attributes_for :tasks, :reject_if => proc { |a| a[:name].blank? }
100
+ # end
101
+ #
102
+ # You can have the following specs:
103
+ #
104
+ # should_accept_nested_attributes_for :tasks, :reject => { :name => '' } # Passes
105
+ # should_accept_nested_attributes_for :tasks, :accept => { :name => 'My task' } # Passes
106
+ #
107
+ # should_accept_nested_attributes_for :tasks, :accept => { :name => 'My task' },
108
+ # :reject => { :name => '' } # Passes
109
+ #
110
+ # should_accept_nested_attributes_for :tasks, :accept => { :name => '' } # Fail
111
+ # should_accept_nested_attributes_for :tasks, :reject => { :name => 'My task' } # Fail
112
+ #
113
+ # You can also give arrays to :accept and :reject to verify multiple attributes.
114
+ #
115
+ def accept_nested_attributes_for(*args)
116
+ AcceptNestedAttributesForMatcher.new(*args).spec(self)
117
+ end
118
+
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,67 @@
1
+ module Remarkable
2
+ module ActiveRecord
3
+ module Matchers
4
+ class HaveDefaultScopeMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
+ arguments
6
+ assertions :options_match?
7
+
8
+ optionals :select, :conditions, :join, :include, :group, :having, :order, :limit, :offset
9
+
10
+ protected
11
+
12
+ def options_match?
13
+ default_scope.include?(@options)
14
+ end
15
+
16
+ def default_scope
17
+ @default_scope ||= if @subject
18
+ scopes = subject_class.default_scoping || []
19
+ scopes.map!{ |s| s[:find] }
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def interpolation_options
26
+ { :options => @options.inspect, :actual => default_scope.inspect }
27
+ end
28
+
29
+ end
30
+
31
+ # Ensures that the model has a default scope with the given options.
32
+ #
33
+ # == Options
34
+ #
35
+ # All options that the default scope would pass on to find: select, conditions,
36
+ # join, include, group, having, order, limit e offset.
37
+ #
38
+ # == Examples
39
+ #
40
+ # it { should have_default_scope(:conditions => {:visible => true}) }
41
+ # it { should have_default_scope.conditions(:visible => true) }
42
+ #
43
+ # Passes for:
44
+ #
45
+ # default_scope :conditions => { :visible => true }
46
+ #
47
+ # If you set two different default scopes, you have to spec them
48
+ # separatedly. Given the scopes:
49
+ #
50
+ # default_scope :conditions => { :visible => true }
51
+ # default_scope :conditions => { :published => true }
52
+ #
53
+ # Then we have the matchers:
54
+ #
55
+ # should_have_default_scope :conditions => { :visible => true } # Passes
56
+ # should_have_default_scope :conditions => { :published => true } # Passes
57
+ #
58
+ # should_have_default_scope :conditions => { :published => true,
59
+ # :visible => true } # Fails
60
+ #
61
+ def have_default_scope(*args)
62
+ HaveDefaultScopeMatcher.new(*args).spec(self)
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -5,13 +5,18 @@ module Remarkable
5
5
  arguments :scope_name
6
6
  assertions :is_scope?, :options_match?
7
7
 
8
- optionals :with, :select, :conditions, :order, :limit, :offset
8
+ optionals :with, :splat => true
9
+ optionals :select, :conditions, :join, :include, :group, :having, :order, :limit, :offset
9
10
 
10
11
  protected
11
12
 
12
13
  def is_scope?
13
14
  @scope_object = if @options[:with]
14
- subject_class.send(@scope_name, @options[:with])
15
+ if @options[:with].is_a?(Array)
16
+ subject_class.send(@scope_name, *@options[:with])
17
+ else
18
+ subject_class.send(@scope_name, @options[:with])
19
+ end
15
20
  else
16
21
  subject_class.send(@scope_name)
17
22
  end
@@ -1,5 +1,40 @@
1
1
  module Remarkable
2
- module ActiveRecord
2
+ module ActiveRecord
3
+ # Holds ActiveRecord matchers.
4
+ #
5
+ # == Validations matchers
6
+ #
7
+ # Remarkable supports all ActiveRecord validations, and the only options
8
+ # not supported in those matchers is the :on options. So whenever you have
9
+ # to test that a validation runs on update, you have to do reproduce the
10
+ # state in your tests:
11
+ #
12
+ # describe Project do
13
+ # describe 'validations on create' do
14
+ # should_validate_presence_of :title
15
+ # end
16
+ #
17
+ # describe 'validations on update' do
18
+ # subject { Post.create!(@valid_attributes) }
19
+ # should_validate_presence_of :updated_at
20
+ # end
21
+ # end
22
+ #
23
+ # Another behavior in validations is the :message option. Whenever you change
24
+ # the message in your model, it must be given in your tests too:
25
+ #
26
+ # class Post < ActiveRecord::Base
27
+ # validates_presence_of :title, :message => 'must be filled'
28
+ # end
29
+ #
30
+ # describe Post do
31
+ # should_validate_presence_of :title #=> fails
32
+ # should_validate_presence_of :title, :message => 'must be filled'
33
+ # end
34
+ #
35
+ # However, if you change the title using the I18n API, you don't need to
36
+ # specify the message in your tests, because it's retrieved properly.
37
+ #
3
38
  module Matchers
4
39
  class ValidatePresenceOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
5
40
  arguments :collection => :attributes, :as => :attribute
@@ -165,7 +165,16 @@ module Remarkable
165
165
  #
166
166
  # Requires an existing record in the database. If you supply :allow_nil as
167
167
  # option, you need to have in the database a record which is not nil in the
168
- # given attributes. The same is required for allow_blank option.
168
+ # given attributes. The same is required for allow_blank option.
169
+ #
170
+ # Notice that the record being validate should not be the same as in the
171
+ # database. In other words, you can't do this:
172
+ #
173
+ # subject { Post.create!(@valid_attributes) }
174
+ # should_validate_uniquness_of :title
175
+ #
176
+ # But don't worry, if you eventually do that, a helpful error message
177
+ # will be raised.
169
178
  #
170
179
  # == Options
171
180
  #
data/locale/en.yml CHANGED
@@ -11,6 +11,20 @@ en:
11
11
  allow_blank:
12
12
  positive: "allowing blank values"
13
13
  negative: "not allowing blank values"
14
+
15
+ accept_nested_attributes_for:
16
+ description: "accept nested attributes for {{associations}}"
17
+ expectations:
18
+ association_exists: "{{subject_name}} to have association {{association}}, but does not"
19
+ is_autosave: "{{subject_name}} to have association {{association}} with autosave true, got false"
20
+ responds_to_attributes: "{{subject_name}} to respond to :{{association}}_attributes=, but does not"
21
+ allows_destroy: "{{subject_name}} with allow destroy equals to {{allow_destroy}}, got {{actual}}"
22
+ accepts: "{{subject_name}} to accept attributes {{attributes}} for {{association}}, but does not"
23
+ rejects: "{{subject_name}} to reject attributes {{attributes}} for {{association}}, but does not"
24
+ optionals:
25
+ allow_destroy:
26
+ positive: "allowing destroy"
27
+ negative: "not allowing destroy"
14
28
 
15
29
  allow_values_for:
16
30
  description: "allow {{in}} as values for {{attributes}}"
@@ -103,7 +117,12 @@ en:
103
117
  positive: "with default value {{inspect}}"
104
118
  negative: "with default value {{inspect}}"
105
119
  limit:
106
- positive: "with limit {{inspect}}"
120
+ positive: "with limit {{inspect}}"
121
+
122
+ have_default_scope:
123
+ description: "have a default scope with {{options}}"
124
+ expectations:
125
+ options_match: "default scope with {{options}}, got {{actual}}"
107
126
 
108
127
  have_index:
109
128
  description: "have index for column(s) {{columns}}"
@@ -0,0 +1,119 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ if RAILS_VERSION == '2.3.2'
4
+ describe 'accept_nested_attributes_for' do
5
+ include ModelBuilder
6
+
7
+ def define_and_validate(default=:category, options={})
8
+ @model = define_model :product do
9
+ has_one :category
10
+ has_many :orders
11
+ has_many :labels
12
+ has_many :tags, :autosave => true
13
+
14
+ accepts_nested_attributes_for :category, options
15
+ accepts_nested_attributes_for :orders, options
16
+ end
17
+
18
+ accept_nested_attributes_for *default
19
+ end
20
+
21
+ describe 'messages' do
22
+
23
+ it 'should contain a description' do
24
+ matcher = define_and_validate
25
+ matcher.description.should == 'accept nested attributes for category'
26
+
27
+ matcher.allow_destroy
28
+ matcher.description.should == 'accept nested attributes for category allowing destroy'
29
+ end
30
+
31
+ it 'should set association_match? message' do
32
+ matcher = define_and_validate(:nothing)
33
+ matcher.matches?(@model)
34
+ matcher.failure_message.should == 'Expected Product to have association nothing, but does not'
35
+ end
36
+
37
+ it 'should set is_autosave? message' do
38
+ matcher = define_and_validate(:labels)
39
+ matcher.matches?(@model)
40
+ matcher.failure_message.should == 'Expected Product to have association labels with autosave true, got false'
41
+ end
42
+
43
+ it 'should set responds_to_attributes? message' do
44
+ matcher = define_and_validate(:tags)
45
+ matcher.matches?(@model)
46
+ matcher.failure_message.should == 'Expected Product to respond to :tags_attributes=, but does not'
47
+ end
48
+
49
+ it 'should set allows_destroy? message' do
50
+ matcher = define_and_validate(:category, :allow_destroy => false)
51
+ matcher.allow_destroy.matches?(@model)
52
+ matcher.failure_message.should == 'Expected Product with allow destroy equals to true, got false'
53
+ end
54
+
55
+ it 'should set accepts? message' do
56
+ matcher = define_and_validate(:category, :reject_if => proc{|a| true })
57
+ matcher.accept({}).matches?(@model)
58
+ matcher.failure_message.should == 'Expected Product to accept attributes {} for category, but does not'
59
+ end
60
+
61
+ it 'should set rejects? message' do
62
+ matcher = define_and_validate(:category, :reject_if => proc{|a| false })
63
+ matcher.reject({}).matches?(@model)
64
+ matcher.failure_message.should == 'Expected Product to reject attributes {} for category, but does not'
65
+ end
66
+
67
+ end
68
+
69
+ describe 'matchers' do
70
+ it { should define_and_validate(:category) }
71
+ it { should define_and_validate(:orders) }
72
+
73
+ it { should_not define_and_validate(:nothing) }
74
+ it { should_not define_and_validate(:labels) }
75
+ it { should_not define_and_validate(:tags) }
76
+
77
+ describe 'with allow destroy as option' do
78
+ it { should define_and_validate(:category, :allow_destroy => true).allow_destroy }
79
+ it { should define_and_validate(:category, :allow_destroy => false).allow_destroy(false) }
80
+ it { should_not define_and_validate(:category, :allow_destroy => false).allow_destroy }
81
+ it { should_not define_and_validate(:category, :allow_destroy => true).allow_destroy(false) }
82
+
83
+ it { should define_and_validate(:orders, :allow_destroy => true).allow_destroy }
84
+ it { should define_and_validate(:orders, :allow_destroy => false).allow_destroy(false) }
85
+ it { should_not define_and_validate(:orders, :allow_destroy => false).allow_destroy }
86
+ it { should_not define_and_validate(:orders, :allow_destroy => true).allow_destroy(false) }
87
+ end
88
+
89
+ describe 'with accept as option' do
90
+ it { should define_and_validate(:category, :reject_if => proc{ |a| a[:name].blank? }).accept({ :name => 'Jose' }) }
91
+ it { should define_and_validate(:category, :reject_if => proc{ |a| a[:name].blank? }).accept({ :name => 'Jose' }, { :name => 'Maria' }) }
92
+ it { should_not define_and_validate(:category, :reject_if => proc{ |a| a[:name].blank? }).accept({ :name => '' }) }
93
+ end
94
+
95
+ describe 'with reject as option' do
96
+ it { should define_and_validate(:category, :reject_if => proc{ |a| !a[:name].blank? }).reject({ :name => 'Jose' }) }
97
+ it { should define_and_validate(:category, :reject_if => proc{ |a| !a[:name].blank? }).reject({ :name => 'Jose' }, { :name => 'Maria' }) }
98
+ it { should_not define_and_validate(:category, :reject_if => proc{ |a| !a[:name].blank? }).reject({ :name => '' }) }
99
+ end
100
+ end
101
+
102
+ describe 'macros' do
103
+ before(:each){ define_and_validate(:category, :allow_destroy => true, :reject_if => proc{ |a| a[:name].blank? }) }
104
+
105
+ should_accept_nested_attributes_for :category
106
+ should_accept_nested_attributes_for :category, :allow_destroy => true
107
+ should_accept_nested_attributes_for :category, :accept => { :name => 'Jose' }
108
+ should_accept_nested_attributes_for :category, :accept => [ { :name => 'Jose' }, { :name => 'Maria' } ]
109
+ should_accept_nested_attributes_for :category, :reject => [ { :name => '' } ]
110
+
111
+ should_not_accept_nested_attributes_for :nothing
112
+ should_not_accept_nested_attributes_for :labels
113
+ should_not_accept_nested_attributes_for :tags
114
+ should_not_accept_nested_attributes_for :category, :allow_destroy => false
115
+ should_not_accept_nested_attributes_for :category, :accept => [ { :name => '' } ]
116
+ should_not_accept_nested_attributes_for :category, :reject => [ { :name => 'Jose' }, { :name => 'Maria' } ]
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ if RAILS_VERSION == '2.3.2'
4
+ describe 'have_default_scope' do
5
+ include ModelBuilder
6
+
7
+ before(:each) do
8
+ @model = define_model :product, :published => :boolean do
9
+ default_scope :order => 'created_at DESC'
10
+ default_scope :conditions => { :published => true }
11
+ end
12
+ end
13
+
14
+ describe 'messages' do
15
+
16
+ it 'should contain a description' do
17
+ matcher = have_default_scope(:conditions => {:special => true})
18
+ matcher.description.should == 'have a default scope with {:conditions=>{:special=>true}}'
19
+ end
20
+
21
+ it 'should set options_match? message' do
22
+ matcher = have_default_scope(:conditions => {:special => true})
23
+ matcher.matches?(@model)
24
+ matcher.failure_message.should == 'Expected default scope with {:conditions=>{:special=>true}}, got [{:order=>"created_at DESC"}, {:conditions=>{:published=>true}}]'
25
+ end
26
+
27
+ end
28
+
29
+ describe 'matchers' do
30
+ it { should have_default_scope(:order => 'created_at DESC') }
31
+ it { should have_default_scope(:conditions => { :published => true }) }
32
+
33
+ it { should_not have_default_scope(:order => 'created_at ASC') }
34
+ it { should_not have_default_scope(:conditions => { :published => false }) }
35
+ it { should_not have_default_scope(:conditions => { :published => true }, :order => 'created_at DESC') }
36
+
37
+ describe 'when the model has no default scope' do
38
+ before(:each){ @model = define_model(:task) }
39
+ it { @model.should_not have_default_scope }
40
+ end
41
+ end
42
+
43
+ describe 'macros' do
44
+ should_have_default_scope :order => 'created_at DESC'
45
+ should_have_default_scope :conditions => { :published => true }
46
+
47
+ should_not_have_default_scope :order => 'created_at ASC'
48
+ should_not_have_default_scope :conditions => { :published => false }
49
+ should_not_have_default_scope :conditions => { :published => true }, :order => 'created_at DESC'
50
+ end
51
+ end
52
+ end
@@ -8,6 +8,7 @@ describe 'have_scope' do
8
8
  named_scope :recent, :order => 'created_at DESC'
9
9
  named_scope :latest, lambda {|c| {:limit => c}}
10
10
  named_scope :since, lambda {|t| {:conditions => ['created_at > ?', t]}}
11
+ named_scope :between, lambda { |a, b| { :conditions => [ 'created_at > ? and created_at < ?', a, b ] } }
11
12
 
12
13
  def self.beginning(c)
13
14
  scoped(:offset => c)
@@ -22,23 +23,23 @@ describe 'have_scope' do
22
23
  describe 'messages' do
23
24
 
24
25
  it 'should contain a description' do
25
- @matcher = have_scope(:title)
26
- @matcher.description.should == 'have to scope itself to {} when :title is called'
26
+ matcher = have_scope(:title)
27
+ matcher.description.should == 'have to scope itself to {} when :title is called'
27
28
 
28
- @matcher.with(1)
29
- @matcher.description.should == 'have to scope itself to {} when :title is called with 1 as argument'
29
+ matcher.with(1)
30
+ matcher.description.should == 'have to scope itself to {} when :title is called with [1] as argument'
30
31
  end
31
32
 
32
33
  it 'should set is_scope? message' do
33
- @matcher = have_scope(:null)
34
- @matcher.matches?(@model)
35
- @matcher.failure_message.should == 'Expected :null when called on Product return an instance of ActiveRecord::NamedScope::Scope'
34
+ matcher = have_scope(:null)
35
+ matcher.matches?(@model)
36
+ matcher.failure_message.should == 'Expected :null when called on Product return an instance of ActiveRecord::NamedScope::Scope'
36
37
  end
37
38
 
38
39
  it 'should set options_match? message' do
39
- @matcher = have_scope(:recent, :conditions => {:special => true})
40
- @matcher.matches?(@model)
41
- @matcher.failure_message.should == 'Expected :recent when called on Product scope to {:conditions=>{:special=>true}}, got {:order=>"created_at DESC"}'
40
+ matcher = have_scope(:recent, :conditions => {:special => true})
41
+ matcher.matches?(@model)
42
+ matcher.failure_message.should == 'Expected :recent when called on Product scope to {:conditions=>{:special=>true}}, got {:order=>"created_at DESC"}'
42
43
  end
43
44
 
44
45
  end
@@ -47,14 +48,16 @@ describe 'have_scope' do
47
48
  it { should have_scope(:recent) }
48
49
  it { should have_scope(:recent, :order => 'created_at DESC') }
49
50
 
50
- it { should have_scope(:latest, :with => 10, :limit => 10) }
51
- it { should have_scope(:beginning, :with => 10, :offset => 10) }
52
- it { should have_scope(:since, :with => Time.at(0), :conditions => ["created_at > ?", Time.at(0)]) }
51
+ it { should have_scope(:latest).with(10).limit(10) }
52
+ it { should have_scope(:beginning).with(10).offset(10) }
53
+ it { should have_scope(:since).with(Time.at(0)).conditions(["created_at > ?", Time.at(0)]) }
54
+ it { should have_scope(:between).with(2, 10).conditions(["created_at > ? and created_at < ?", 2, 10]) }
53
55
 
54
- it { should_not have_scope(:null) }
55
- it { should_not have_scope(:latest, :with => 5, :limit => 10) }
56
- it { should_not have_scope(:beginning, :with => 5, :offset => 10) }
57
- it { should_not have_scope(:since, :with => Time.at(0), :conditions => ["created_at > ?", Time.at(1)]) }
56
+ it { should_not have_scope(:null) }
57
+ it { should_not have_scope(:latest).with(5).limit(10) }
58
+ it { should_not have_scope(:beginning).with(5).offset(10) }
59
+ it { should_not have_scope(:since).with(Time.at(0)).conditions(["created_at > ?", Time.at(1)]) }
60
+ it { should_not have_scope(:between).with(2, 10).conditions(["updated_at > ? and updated_at < ?", 2, 10]) }
58
61
  end
59
62
 
60
63
  describe 'macros' do
@@ -64,10 +67,12 @@ describe 'have_scope' do
64
67
  should_have_scope :latest, :with => 10, :limit => 10
65
68
  should_have_scope :beginning, :with => 10, :offset => 10
66
69
  should_have_scope :since, :with => Time.at(0), :conditions => ["created_at > ?", Time.at(0)]
70
+ should_have_scope :between, :with => [ 2, 10 ], :conditions => [ "created_at > ? and created_at < ?", 2, 10 ]
67
71
 
68
72
  should_not_have_scope :null
69
73
  should_not_have_scope :latest, :with => 5, :limit => 10
70
74
  should_not_have_scope :beginning, :with => 5, :offset => 10
71
75
  should_not_have_scope :since, :with => Time.at(0), :conditions => ["created_at > ?", Time.at(1)]
76
+ should_not_have_scope :between, :with => [ 2, 10 ], :conditions => [ "updated_at > ? and updated_at < ?", 2, 10 ]
72
77
  end
73
78
  end
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.0.7
4
+ version: 3.0.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-04-22 00:00:00 +02:00
14
+ date: 2009-04-24 00:00:00 +02:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 3.0.7
25
+ version: 3.0.8
26
26
  version:
27
27
  description: "Remarkable ActiveRecord: collection of matchers and macros with I18n for ActiveRecord"
28
28
  email:
@@ -41,13 +41,13 @@ files:
41
41
  - README
42
42
  - LICENSE
43
43
  - CHANGELOG
44
- - lib/remarkable_activerecord
45
44
  - lib/remarkable_activerecord/base.rb
46
45
  - lib/remarkable_activerecord/human_names.rb
47
- - lib/remarkable_activerecord/matchers
48
46
  - lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb
49
47
  - lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb
48
+ - lib/remarkable_activerecord/matchers/have_default_scope_matcher.rb
50
49
  - lib/remarkable_activerecord/matchers/have_readonly_attributes_matcher.rb
50
+ - lib/remarkable_activerecord/matchers/accept_nested_attributes_for_matcher.rb
51
51
  - lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb
52
52
  - lib/remarkable_activerecord/matchers/validate_associated_matcher.rb
53
53
  - lib/remarkable_activerecord/matchers/have_column_matcher.rb
@@ -65,6 +65,8 @@ files:
65
65
  - locale/en.yml
66
66
  has_rdoc: true
67
67
  homepage: http://github.com/carlosbrando/remarkable
68
+ licenses: []
69
+
68
70
  post_install_message:
69
71
  rdoc_options: []
70
72
 
@@ -85,9 +87,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  requirements: []
86
88
 
87
89
  rubyforge_project: remarkable
88
- rubygems_version: 1.3.1
90
+ rubygems_version: 1.3.2
89
91
  signing_key:
90
- specification_version: 2
92
+ specification_version: 3
91
93
  summary: "Remarkable ActiveRecord: collection of matchers and macros with I18n for ActiveRecord"
92
94
  test_files:
93
95
  - spec/validate_associated_matcher_spec.rb
@@ -95,6 +97,7 @@ test_files:
95
97
  - spec/rcov.opts
96
98
  - spec/spec_helper.rb
97
99
  - spec/validate_acceptance_of_matcher_spec.rb
100
+ - spec/accept_nested_attributes_for_matcher_spec.rb
98
101
  - spec/allow_mass_assignment_of_matcher_spec.rb
99
102
  - spec/have_scope_matcher_spec.rb
100
103
  - spec/validate_inclusion_of_matcher_spec.rb
@@ -104,6 +107,7 @@ test_files:
104
107
  - spec/allow_values_for_matcher_spec.rb
105
108
  - spec/validate_uniqueness_of_matcher_spec.rb
106
109
  - spec/have_column_matcher_spec.rb
110
+ - spec/have_default_scope_matcher_spec.rb
107
111
  - spec/have_index_matcher_spec.rb
108
112
  - spec/association_matcher_spec.rb
109
113
  - spec/validate_exclusion_of_matcher_spec.rb