remarkable_activerecord 3.0.7 → 3.0.8

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