mongomodel 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +23 -11
  3. data/gemfiles/rails-3.2.gemfile +2 -2
  4. data/gemfiles/rails-4-observers.gemfile +1 -1
  5. data/gemfiles/rails-4.1.gemfile +2 -2
  6. data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
  7. data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
  8. data/gemfiles/rails-5.1.gemfile +10 -0
  9. data/gemfiles/rails-5.2.gemfile +10 -0
  10. data/lib/mongomodel.rb +15 -15
  11. data/lib/mongomodel/attributes/mongo.rb +7 -7
  12. data/lib/mongomodel/attributes/store.rb +4 -4
  13. data/lib/mongomodel/attributes/typecasting.rb +7 -7
  14. data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
  15. data/lib/mongomodel/compatibility/mongoid.rb +3 -3
  16. data/lib/mongomodel/concerns/abstract_class.rb +3 -3
  17. data/lib/mongomodel/concerns/activemodel.rb +4 -4
  18. data/lib/mongomodel/concerns/associations.rb +8 -8
  19. data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
  20. data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
  21. data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
  22. data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
  23. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
  24. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
  25. data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
  26. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
  27. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
  28. data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
  29. data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
  30. data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
  31. data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
  32. data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
  33. data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
  34. data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
  35. data/lib/mongomodel/concerns/attributes.rb +18 -18
  36. data/lib/mongomodel/concerns/callbacks.rb +7 -7
  37. data/lib/mongomodel/concerns/document_parent.rb +2 -2
  38. data/lib/mongomodel/concerns/logging.rb +2 -2
  39. data/lib/mongomodel/concerns/map_reduce.rb +11 -11
  40. data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
  41. data/lib/mongomodel/concerns/properties.rb +18 -18
  42. data/lib/mongomodel/concerns/record_status.rb +9 -13
  43. data/lib/mongomodel/concerns/serialization.rb +4 -4
  44. data/lib/mongomodel/concerns/timestamps.rb +4 -4
  45. data/lib/mongomodel/concerns/translation.rb +2 -2
  46. data/lib/mongomodel/concerns/validations.rb +5 -5
  47. data/lib/mongomodel/concerns/validations/associated.rb +1 -1
  48. data/lib/mongomodel/document.rb +6 -6
  49. data/lib/mongomodel/document/callbacks.rb +15 -21
  50. data/lib/mongomodel/document/collection_modifiers.rb +5 -5
  51. data/lib/mongomodel/document/dynamic_finders.rb +1 -1
  52. data/lib/mongomodel/document/indexes.rb +19 -19
  53. data/lib/mongomodel/document/optimistic_locking.rb +7 -7
  54. data/lib/mongomodel/document/persistence.rb +23 -23
  55. data/lib/mongomodel/document/scopes.rb +20 -20
  56. data/lib/mongomodel/document/validations.rb +6 -6
  57. data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
  58. data/lib/mongomodel/embedded_document.rb +11 -11
  59. data/lib/mongomodel/locale/en.yml +0 -1
  60. data/lib/mongomodel/log_subscriber.rb +5 -5
  61. data/lib/mongomodel/railtie.rb +13 -13
  62. data/lib/mongomodel/support/collection.rb +31 -31
  63. data/lib/mongomodel/support/configuration.rb +11 -11
  64. data/lib/mongomodel/support/core_extensions.rb +1 -1
  65. data/lib/mongomodel/support/dynamic_finder.rb +12 -12
  66. data/lib/mongomodel/support/exceptions.rb +6 -6
  67. data/lib/mongomodel/support/instrumented_collection.rb +20 -20
  68. data/lib/mongomodel/support/map.rb +33 -33
  69. data/lib/mongomodel/support/mongo_operator.rb +6 -6
  70. data/lib/mongomodel/support/mongo_options.rb +18 -18
  71. data/lib/mongomodel/support/mongo_order.rb +16 -16
  72. data/lib/mongomodel/support/paginator.rb +8 -8
  73. data/lib/mongomodel/support/reference.rb +10 -10
  74. data/lib/mongomodel/support/scope.rb +37 -37
  75. data/lib/mongomodel/support/scope/array_methods.rb +1 -1
  76. data/lib/mongomodel/support/scope/batches.rb +1 -1
  77. data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
  78. data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
  79. data/lib/mongomodel/support/scope/load_methods.rb +1 -1
  80. data/lib/mongomodel/support/scope/pagination.rb +1 -1
  81. data/lib/mongomodel/support/scope/query_methods.rb +6 -6
  82. data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
  83. data/lib/mongomodel/support/types.rb +2 -2
  84. data/lib/mongomodel/support/types/array.rb +1 -1
  85. data/lib/mongomodel/support/types/boolean.rb +3 -3
  86. data/lib/mongomodel/support/types/custom.rb +3 -3
  87. data/lib/mongomodel/support/types/date.rb +2 -2
  88. data/lib/mongomodel/support/types/date_time.rb +6 -16
  89. data/lib/mongomodel/support/types/float.rb +1 -1
  90. data/lib/mongomodel/support/types/hash.rb +1 -1
  91. data/lib/mongomodel/support/types/integer.rb +13 -10
  92. data/lib/mongomodel/support/types/object.rb +5 -5
  93. data/lib/mongomodel/support/types/rational.rb +3 -3
  94. data/lib/mongomodel/support/types/time.rb +2 -2
  95. data/lib/mongomodel/version.rb +1 -1
  96. data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
  97. data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
  98. data/mongomodel.gemspec +5 -4
  99. data/spec/mongomodel/attributes/store_spec.rb +21 -21
  100. data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
  101. data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
  102. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
  103. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
  104. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
  105. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
  106. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
  107. data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
  108. data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
  109. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
  110. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
  111. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
  112. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
  113. data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
  114. data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
  115. data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
  116. data/spec/mongomodel/concerns/logging_spec.rb +5 -3
  117. data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
  118. data/spec/mongomodel/concerns/observing_spec.rb +3 -3
  119. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
  120. data/spec/mongomodel/concerns/properties_spec.rb +11 -11
  121. data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
  122. data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
  123. data/spec/mongomodel/concerns/validations_spec.rb +41 -38
  124. data/spec/mongomodel/document/callbacks_spec.rb +20 -16
  125. data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
  126. data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
  127. data/spec/mongomodel/document/finders_spec.rb +15 -15
  128. data/spec/mongomodel/document/indexes_spec.rb +29 -29
  129. data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
  130. data/spec/mongomodel/document/persistence_spec.rb +39 -39
  131. data/spec/mongomodel/document/scopes_spec.rb +17 -17
  132. data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
  133. data/spec/mongomodel/document/validations_spec.rb +35 -35
  134. data/spec/mongomodel/document_spec.rb +19 -19
  135. data/spec/mongomodel/embedded_document_spec.rb +19 -19
  136. data/spec/mongomodel/mongomodel_spec.rb +7 -6
  137. data/spec/mongomodel/support/collection_spec.rb +54 -54
  138. data/spec/mongomodel/support/configuration_spec.rb +1 -1
  139. data/spec/mongomodel/support/map_spec.rb +66 -66
  140. data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
  141. data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
  142. data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
  143. data/spec/mongomodel/support/paginator_spec.rb +15 -15
  144. data/spec/mongomodel/support/property_spec.rb +29 -23
  145. data/spec/mongomodel/support/scope_spec.rb +205 -204
  146. data/spec/spec_helper.rb +13 -2
  147. data/spec/support/callbacks.rb +3 -8
  148. data/spec/support/helpers/define_class.rb +7 -7
  149. data/spec/support/helpers/document_finder_stubs.rb +6 -6
  150. data/spec/support/helpers/specs_for.rb +1 -1
  151. data/spec/support/helpers/validations.rb +1 -1
  152. data/spec/support/matchers/find_with.rb +8 -8
  153. data/spec/support/matchers/respond_to_boolean.rb +3 -3
  154. data/spec/support/matchers/run_callbacks.rb +6 -9
  155. data/spec/support/models.rb +5 -5
  156. metadata +23 -7
@@ -5,66 +5,66 @@ module MongoModel
5
5
  def c(field, order)
6
6
  MongoOrder::Clause.new(field, order)
7
7
  end
8
-
8
+
9
9
  subject { MongoOrder.new(c(:name, :ascending), c(:age, :descending)) }
10
-
10
+
11
11
  it "converts to string" do
12
12
  subject.to_s.should == "name ascending, age descending"
13
13
  end
14
-
14
+
15
15
  describe "#to_sort" do
16
16
  it "converts to mongo sort array" do
17
17
  model = double('model', :properties => double('properties', :[] => nil))
18
18
  subject.to_sort(model).should == [['name', :ascending], ['age', :descending]]
19
19
  end
20
20
  end
21
-
21
+
22
22
  it "is reversable" do
23
23
  subject.reverse.should == MongoOrder.new(c(:name, :descending), c(:age, :ascending))
24
24
  end
25
-
25
+
26
26
  it "equals another order object with identical clauses" do
27
27
  subject.should == MongoOrder.new(c(:name, :ascending), c(:age, :descending))
28
28
  end
29
-
29
+
30
30
  it "equals another order object with different clauses" do
31
31
  subject.should_not == MongoOrder.new(c(:name, :ascending))
32
32
  subject.should_not == MongoOrder.new(c(:age, :ascending), c(:name, :ascending))
33
33
  end
34
-
34
+
35
35
  describe "#parse" do
36
36
  it "does not change a MongoOrder" do
37
37
  MongoOrder.parse(subject).should == subject
38
38
  end
39
-
39
+
40
40
  it "converts individual clause to MongoOrder" do
41
41
  MongoOrder.parse(c(:name, :ascending)).should == MongoOrder.new(c(:name, :ascending))
42
42
  end
43
-
43
+
44
44
  it "converts symbol to MongoOrder" do
45
45
  MongoOrder.parse(:name).should == MongoOrder.new(c(:name, :ascending))
46
46
  end
47
-
47
+
48
48
  it "converts array of clauses to MongoOrder" do
49
49
  MongoOrder.parse([c(:name, :ascending), c(:age, :descending)]).should == MongoOrder.new(c(:name, :ascending), c(:age, :descending))
50
50
  end
51
-
51
+
52
52
  it "converts array of symbols to MongoOrder" do
53
53
  MongoOrder.parse([:name, :age]).should == MongoOrder.new(c(:name, :ascending), c(:age, :ascending))
54
54
  end
55
-
55
+
56
56
  it "converts array of strings to MongoOrder" do
57
57
  MongoOrder.parse(['name ASC', 'age DESC']).should == MongoOrder.new(c(:name, :ascending), c(:age, :descending))
58
58
  end
59
-
59
+
60
60
  it "converts string (no order specified) to MongoOrder" do
61
61
  MongoOrder.parse('name').should == MongoOrder.new(c(:name, :ascending))
62
62
  end
63
-
63
+
64
64
  it "converts string (single order) to MongoOrder" do
65
65
  MongoOrder.parse('name DESC').should == MongoOrder.new(c(:name, :descending))
66
66
  end
67
-
67
+
68
68
  it "converts string (multiple orders) to MongoOrder" do
69
69
  MongoOrder.parse('name DESC, age ASC').should == MongoOrder.new(c(:name, :descending), c(:age, :ascending))
70
70
  end
@@ -73,24 +73,24 @@ module MongoModel
73
73
 
74
74
  describe MongoOrder::Clause do
75
75
  subject { MongoOrder::Clause.new(:name, :ascending) }
76
-
76
+
77
77
  it "converts to string" do
78
78
  subject.to_s.should == "name ascending"
79
79
  end
80
-
80
+
81
81
  it "equals another clause with the same field and order" do
82
82
  subject.should == MongoOrder::Clause.new(:name, :ascending)
83
83
  end
84
-
84
+
85
85
  it "equals another clause with a different field or order" do
86
86
  subject.should_not == MongoOrder::Clause.new(:age, :ascending)
87
87
  subject.should_not == MongoOrder::Clause.new(:name, :descending)
88
88
  end
89
-
89
+
90
90
  it "is reversable" do
91
91
  subject.reverse.should == MongoOrder::Clause.new(:name, :descending)
92
92
  end
93
-
93
+
94
94
  describe "#to_sort" do
95
95
  context "given property" do
96
96
  it "uses property as value to convert to mongo sort" do
@@ -98,22 +98,22 @@ module MongoModel
98
98
  subject.to_sort(property).should == ['_name', :ascending]
99
99
  end
100
100
  end
101
-
101
+
102
102
  context "given nil" do
103
103
  it "converts to mongo sort" do
104
104
  subject.to_sort(nil).should == ['name', :ascending]
105
105
  end
106
106
  end
107
107
  end
108
-
108
+
109
109
  describe "#parse" do
110
110
  let(:asc) { MongoOrder::Clause.new(:name, :ascending) }
111
111
  let(:desc) { MongoOrder::Clause.new(:name, :descending) }
112
-
112
+
113
113
  it "creates Clause from string (no order)" do
114
114
  MongoOrder::Clause.parse('name').should == asc
115
115
  end
116
-
116
+
117
117
  it "creates Clause from string (with order)" do
118
118
  MongoOrder::Clause.parse('name ASC').should == asc
119
119
  MongoOrder::Clause.parse('name asc').should == asc
@@ -6,50 +6,50 @@ module MongoModel
6
6
  let(:scope) { double(:count => 35, :limit => entries).as_null_object }
7
7
  let(:page) { 2 }
8
8
  let(:per_page) { 10 }
9
-
9
+
10
10
  subject { Paginator.new(scope, page, per_page) }
11
-
11
+
12
12
  it { should be_a_kind_of(Array) }
13
-
13
+
14
14
  its(:total_entries) { should == 35 }
15
15
  its(:total_pages) { should == 4 }
16
-
16
+
17
17
  its(:current_page) { should == 2 }
18
18
  its(:previous_page) { should == 1 }
19
19
  its(:next_page) { should == 3 }
20
20
  its(:offset) { should == 10 }
21
-
21
+
22
22
  its(:size) { should == 10 }
23
-
23
+
24
24
  it { should_not be_out_of_bounds }
25
-
25
+
26
26
  context "first page" do
27
27
  let(:page) { 1 }
28
-
28
+
29
29
  its(:previous_page) { should be_nil }
30
30
  its(:next_page) { should == 2 }
31
31
  its(:offset) { should == 0 }
32
32
  end
33
-
33
+
34
34
  context "last page" do
35
35
  let(:entries) { [double] * 5 }
36
36
  before { scope.stub(:count => nil) }
37
-
37
+
38
38
  let(:page) { 4 }
39
-
39
+
40
40
  its(:previous_page) { should == 3 }
41
41
  its(:next_page) { should be_nil }
42
42
  end
43
-
43
+
44
44
  context "no entries" do
45
45
  before { scope.stub(:count => 0) }
46
-
46
+
47
47
  its(:total_pages) { should == 1 }
48
48
  end
49
-
49
+
50
50
  context "out of bounds" do
51
51
  let(:page) { 5 }
52
-
52
+
53
53
  it { should be_out_of_bounds }
54
54
  end
55
55
  end
@@ -5,93 +5,99 @@ module MongoModel
5
5
  describe Property do
6
6
  context "no options" do
7
7
  subject { Property.new(:name, String) }
8
-
8
+
9
9
  it "sets property name" do
10
10
  subject.name.should == :name
11
11
  end
12
-
12
+
13
13
  it "sets property type" do
14
14
  subject.type.should == String
15
15
  end
16
-
16
+
17
17
  it "sets default as value from name" do
18
18
  subject.as.should == 'name'
19
19
  end
20
-
20
+
21
21
  it "defaults to nil" do
22
22
  subject.default(double('document instance')).should be_nil
23
23
  end
24
-
24
+
25
25
  it "equals a property with the same name and type" do
26
26
  subject.should == Property.new(:name, String)
27
27
  end
28
-
28
+
29
29
  it "does not equal properties with different name, type and options" do
30
30
  subject.should_not == Property.new(:address, String)
31
31
  subject.should_not == Property.new(:name, Float)
32
32
  subject.should_not == Property.new(:name, String, :default => 'Anonymous')
33
33
  end
34
-
34
+
35
35
  it { should_not be_internal }
36
36
  end
37
-
37
+
38
38
  context "with options" do
39
39
  subject { Property.new(:age, Integer, :as => '_record_age', :default => 21) }
40
-
40
+
41
41
  it "sets property options" do
42
42
  subject.options.should == { :as => '_record_age', :default => 21 }
43
43
  end
44
-
44
+
45
45
  it "sets custom as value" do
46
46
  subject.as.should == '_record_age'
47
47
  end
48
-
48
+
49
49
  it "defaults to custom default" do
50
50
  subject.default(double('document instance')).should == 21
51
51
  end
52
-
52
+
53
53
  it "equals a property with the same name, type and options" do
54
54
  subject.should == Property.new(:age, Integer, :as => '_record_age', :default => 21)
55
55
  end
56
-
56
+
57
57
  it "does not equal properties with different name, type and options" do
58
58
  subject.should_not == Property.new(:address, String)
59
59
  subject.should_not == Property.new(:name, Float)
60
60
  subject.should_not == Property.new(:name, String, :default => 'Anonymous')
61
61
  end
62
-
62
+
63
63
  context "with callable default" do
64
64
  let(:document) { double('document instance', :answer => 42) }
65
-
65
+
66
66
  it "calls the proc yielding the instance" do
67
67
  property = Property.new(:age, Integer, :default => lambda { |doc| doc.answer })
68
68
  property.default(document).should == 42
69
69
  end
70
-
70
+
71
71
  it "calls the proc in the context of the instance" do
72
72
  property = Property.new(:age, Integer, :default => proc { answer })
73
73
  property.default(document).should == 42
74
74
  end
75
75
  end
76
-
76
+
77
77
  context "with internal option" do
78
78
  subject { Property.new(:age, Integer, :internal => true) }
79
79
  it { should be_internal }
80
80
  end
81
-
81
+
82
82
  context "with internal property name" do
83
83
  subject { Property.new(:age, Integer, :as => '_age') }
84
84
  it { should be_internal }
85
85
  end
86
86
  end
87
-
87
+
88
88
  it "does not validate if options[:validate] is false" do
89
- Property.new(:age, Integer, :validate => false).validate?.should be_false
89
+ Property.new(:age, Integer, :validate => false).validate?.should be false
90
90
  end
91
-
91
+
92
92
  it "validates when options[:validate] is true or not provided" do
93
- Property.new(:age, Integer, :validate => true).validate?.should be_true
94
- Property.new(:age, Integer).validate?.should be_true
93
+ Property.new(:age, Integer, :validate => true).validate?.should be true
94
+ Property.new(:age, Integer).validate?.should be true
95
+ end
96
+
97
+ context "with type Integer" do
98
+ it "correctly converts type from mongo representation" do
99
+ Property.new(:age, Integer).from_mongo(15.0).should be_a_kind_of(Integer)
100
+ end
95
101
  end
96
102
  end
97
103
  end
@@ -8,68 +8,68 @@ module MongoModel
8
8
  property :author, String
9
9
  property :date, Time
10
10
  end
11
-
11
+
12
12
  let(:basic_scope) { Scope.new(Post) }
13
13
  let(:posts) { (1..5).map { Post.new } }
14
-
14
+
15
15
  subject { Scope.new(Post) }
16
-
16
+
17
17
  MongoModel::Document.extend(DocumentFinderStubs)
18
-
19
-
18
+
19
+
20
20
  def self.subject_loaded(&block)
21
21
  context "when loaded" do
22
22
  before(:each) { subject.to_a }
23
23
  class_eval(&block)
24
24
  end
25
25
  end
26
-
26
+
27
27
  def self.subject_not_loaded(&block)
28
28
  context "when not loaded", &block
29
29
  end
30
-
30
+
31
31
  def self.always(&block)
32
32
  subject_loaded(&block)
33
33
  subject_not_loaded(&block)
34
34
  end
35
-
36
-
35
+
36
+
37
37
  shared_examples_for "all scopes" do
38
38
  def finder_conditions
39
39
  finder_options[:conditions] || {}
40
40
  end
41
-
41
+
42
42
  describe "#to_a" do
43
43
  it "finds and return documents matching conditions" do
44
44
  model.should_find(finder_options, posts) do
45
45
  subject.to_a.should == posts
46
46
  end
47
47
  end
48
-
48
+
49
49
  it "loads the scope" do
50
50
  subject.to_a
51
51
  subject.should be_loaded
52
52
  end
53
-
53
+
54
54
  it "caches the documents" do
55
55
  subject.to_a
56
56
  model.should_not_find { subject.to_a }
57
57
  end
58
58
  end
59
-
59
+
60
60
  describe "#as_json" do
61
61
  it "delegates to #to_a" do
62
62
  subject.as_json.should == subject.to_a.as_json
63
63
  end
64
64
  end
65
-
65
+
66
66
  describe "#count" do
67
67
  it "counts documents matching conditions and return the result" do
68
68
  model.should_count(finder_options, 4) do
69
69
  subject.count
70
70
  end
71
71
  end
72
-
72
+
73
73
  it "does not cache the result" do
74
74
  subject.count
75
75
  model.should_count(finder_options, 4) do
@@ -77,25 +77,25 @@ module MongoModel
77
77
  end
78
78
  end
79
79
  end
80
-
80
+
81
81
  describe "#size" do
82
82
  before(:each) { model.stub_find(posts) }
83
-
83
+
84
84
  subject_loaded do
85
85
  it "returns the number of matching documents" do
86
86
  subject.size.should == 5
87
87
  end
88
-
88
+
89
89
  it "does not perform a count on the collection" do
90
90
  model.should_not_count { subject.size }
91
91
  end
92
92
  end
93
-
93
+
94
94
  subject_not_loaded do
95
95
  it "returns the number of matching documents" do
96
96
  subject.size.should == 5
97
97
  end
98
-
98
+
99
99
  it "performs a count on the collection" do
100
100
  model.should_count(finder_options, 9) do
101
101
  subject.size.should == 9
@@ -103,42 +103,42 @@ module MongoModel
103
103
  end
104
104
  end
105
105
  end
106
-
106
+
107
107
  describe "#empty?" do
108
108
  context "when no matching documents exist" do
109
109
  before(:each) { model.stub_find([]) }
110
-
110
+
111
111
  always do
112
112
  it { should be_empty }
113
113
  end
114
114
  end
115
-
115
+
116
116
  context "when matching documents exist" do
117
117
  before(:each) { model.stub_find(posts) }
118
-
118
+
119
119
  always do
120
120
  it { should_not be_empty }
121
121
  end
122
122
  end
123
-
123
+
124
124
  subject_loaded do
125
125
  it "does not perform a count on the collection" do
126
126
  model.should_not_count { subject.empty? }
127
127
  end
128
128
  end
129
129
  end
130
-
130
+
131
131
  describe "#any?" do
132
132
  context "when no block given" do
133
133
  it "performs a count on the collection" do
134
134
  model.should_count(finder_options, 1) { subject.any? }
135
135
  end
136
-
136
+
137
137
  context "when no matching documents exist" do
138
138
  before(:each) { model.stub_find([]) }
139
139
 
140
140
  always do
141
- specify { subject.any?.should be_false }
141
+ specify { subject.any?.should be false }
142
142
  end
143
143
  end
144
144
 
@@ -146,20 +146,21 @@ module MongoModel
146
146
  before(:each) { model.stub_find(posts) }
147
147
 
148
148
  always do
149
- specify { subject.any?.should be_true }
149
+ specify { subject.any?.should be true }
150
150
  end
151
151
  end
152
152
  end
153
-
153
+
154
154
  context "when block given" do
155
155
  it "delegates block to to_a" do
156
- blk = lambda { |*args| true }
157
- subject.to_a.should_receive(:any?).with(&blk)
158
- subject.any?(&blk)
156
+ result = double
157
+ blk = lambda {}
158
+ subject.to_a.should_receive(:any?).and_return(result)
159
+ subject.any?(&blk).should == result
159
160
  end
160
161
  end
161
162
  end
162
-
163
+
163
164
  describe "#reset" do
164
165
  always do
165
166
  it "returns itself" do
@@ -172,7 +173,7 @@ module MongoModel
172
173
  end
173
174
  end
174
175
  end
175
-
176
+
176
177
  describe "#reload" do
177
178
  always do
178
179
  it "returns itself" do
@@ -183,7 +184,7 @@ module MongoModel
183
184
  subject.reload
184
185
  subject.should be_loaded
185
186
  end
186
-
187
+
187
188
  it "resets its finder options" do
188
189
  old_finder_options = subject.finder_options
189
190
  subject.reload.finder_options.should_not equal(old_finder_options)
@@ -195,10 +196,10 @@ module MongoModel
195
196
  end
196
197
  end
197
198
  end
198
-
199
+
199
200
  describe "#==" do
200
201
  before(:each) { model.stub_find(posts) }
201
-
202
+
202
203
  it "is equal to an array with matching results" do
203
204
  subject.should == posts
204
205
  end
@@ -207,7 +208,7 @@ module MongoModel
207
208
  subject.should_not == []
208
209
  end
209
210
  end
210
-
211
+
211
212
  describe "array methods" do
212
213
  it "forwards [] to to_a" do
213
214
  subject.to_a.should_receive(:[]).with(0)
@@ -215,181 +216,181 @@ module MongoModel
215
216
  end
216
217
 
217
218
  it "forwards each to to_a" do
218
- blk = lambda { |*args| true }
219
- subject.to_a.should_receive(:each).with(&blk)
220
- subject.each(&blk)
219
+ blk = lambda {}
220
+ subject.to_a.should_receive(:each).and_return([1, 2, 3])
221
+ subject.each(&blk).should eq [1, 2, 3]
221
222
  end
222
223
  end
223
-
224
+
224
225
  describe "#where" do
225
226
  it "returns a new scope" do
226
227
  subject.where(:author => "Sam").should be_an_instance_of(Scope)
227
228
  end
228
-
229
+
229
230
  it "is not loaded" do
230
231
  subject.to_a
231
232
  subject.where(:author => "Sam").should_not be_loaded
232
233
  end
233
-
234
+
234
235
  it "adds individual where values" do
235
236
  where_scope = subject.where(:author => "Sam")
236
237
  where_scope.where_values.should == subject.where_values + [{ :author => "Sam" }]
237
238
  end
238
-
239
+
239
240
  it "adds multiple where values" do
240
241
  where_scope = subject.where({ :author => "Sam" }, { :published => false })
241
242
  where_scope.where_values.should == subject.where_values + [{ :author => "Sam" }, { :published => false }]
242
243
  end
243
244
  end
244
-
245
+
245
246
  describe "#where!" do
246
247
  it "overwrites where values" do
247
248
  where_scope = subject.where!(:author => "Sam")
248
249
  where_scope.where_values.should == [{ :author => "Sam" }]
249
250
  end
250
251
  end
251
-
252
+
252
253
  describe "#order" do
253
254
  it "returns a new scope" do
254
255
  subject.order(:author.asc).should be_an_instance_of(Scope)
255
256
  end
256
-
257
+
257
258
  it "is not loaded" do
258
259
  subject.to_a
259
260
  subject.order(:author.asc).should_not be_loaded
260
261
  end
261
-
262
+
262
263
  it "adds individual order values" do
263
264
  order_scope = subject.order(:author.asc)
264
265
  order_scope.order_values.should == subject.order_values + [:author.asc]
265
266
  end
266
-
267
+
267
268
  it "adds multiple order values" do
268
269
  order_scope = subject.order(:author.asc, :published.desc)
269
270
  order_scope.order_values.should == subject.order_values + [:author.asc, :published.desc]
270
271
  end
271
272
  end
272
-
273
+
273
274
  describe "#order!" do
274
275
  it "overwrites order values" do
275
276
  order_scope = subject.order!(:author.asc)
276
277
  order_scope.order_values.should == [:author.asc]
277
278
  end
278
279
  end
279
-
280
+
280
281
  describe "#select" do
281
282
  context "when no block is given" do
282
283
  it "returns a new scope" do
283
284
  subject.select(:author).should be_an_instance_of(Scope)
284
285
  end
285
-
286
+
286
287
  it "is not loaded" do
287
288
  subject.to_a
288
289
  subject.select(:author).should_not be_loaded
289
290
  end
290
-
291
+
291
292
  it "adds individual select values" do
292
293
  select_scope = subject.select(:author)
293
294
  select_scope.select_values.should == subject.select_values + [:author]
294
295
  end
295
-
296
+
296
297
  it "adds multiple select values" do
297
298
  select_scope = subject.select(:author, :published)
298
299
  select_scope.select_values.should == subject.select_values + [:author, :published]
299
300
  end
300
301
  end
301
-
302
+
302
303
  context "when a block given" do
303
304
  it "passed block to to_a#select" do
304
- blk = lambda { |*args| true }
305
- subject.to_a.should_receive(:select).with(&blk)
306
- subject.select(&blk)
305
+ blk = lambda {}
306
+ subject.to_a.should_receive(:select).and_return([1, 2, 3])
307
+ subject.select(&blk).should eq [1, 2, 3]
307
308
  end
308
309
  end
309
310
  end
310
-
311
+
311
312
  describe "#select!" do
312
313
  it "overwrites select values" do
313
314
  select_scope = subject.select!(:author)
314
315
  select_scope.select_values.should == [:author]
315
316
  end
316
317
  end
317
-
318
+
318
319
  describe "#limit" do
319
320
  it "returns a new scope" do
320
321
  subject.limit(10).should be_an_instance_of(Scope)
321
322
  end
322
-
323
+
323
324
  it "is not loaded" do
324
325
  subject.limit(10).should_not be_loaded
325
326
  end
326
-
327
+
327
328
  it "overrides previous limit value" do
328
329
  subject.limit(10).limit_value.should == 10
329
330
  end
330
331
  end
331
-
332
+
332
333
  describe "#offset" do
333
334
  it "returns a new scope" do
334
335
  subject.offset(10).should be_an_instance_of(Scope)
335
336
  end
336
-
337
+
337
338
  it "is not loaded" do
338
339
  subject.offset(10).should_not be_loaded
339
340
  end
340
-
341
+
341
342
  it "overrides previous offset value" do
342
343
  subject.offset(10).offset_value.should == 10
343
344
  end
344
345
  end
345
-
346
+
346
347
  describe "#from" do
347
348
  define_class(:NotAPost, Document)
348
-
349
+
349
350
  it "returns a new scope" do
350
351
  subject.from(NotAPost.collection).should be_an_instance_of(Scope)
351
352
  end
352
-
353
+
353
354
  it "is not loaded" do
354
355
  subject.from(NotAPost.collection).should_not be_loaded
355
356
  end
356
-
357
+
357
358
  it "overrides collection" do
358
359
  subject.from(NotAPost.collection).collection.should == NotAPost.collection
359
360
  end
360
-
361
+
361
362
  it "allows collection to be set using string" do
362
363
  subject.from(NotAPost.collection.name).collection.name.should == NotAPost.collection.name
363
364
  end
364
365
  end
365
-
366
+
366
367
  describe "#first" do
367
368
  context "with count argument" do
368
369
  context "when no matching documents exist" do
369
370
  before(:each) { model.stub_find([]) }
370
-
371
+
371
372
  always do
372
373
  it "returns an empty array" do
373
374
  subject.first(3).should == []
374
375
  end
375
376
  end
376
-
377
+
377
378
  subject_loaded do
378
379
  it "does not perform a find" do
379
380
  model.should_not_find { subject.first(3) }
380
381
  end
381
382
  end
382
-
383
+
383
384
  subject_not_loaded do
384
385
  it "finds with a limit of 3" do
385
386
  model.should_find(finder_options.merge(:limit => 3), []) { subject.first(3) }
386
387
  end
387
388
  end
388
389
  end
389
-
390
+
390
391
  context "when matching documents exist" do
391
392
  before(:each) { model.stub_find([posts[0], posts[1], posts[2]]) }
392
-
393
+
393
394
  always do
394
395
  it "returns the first documents in an array" do
395
396
  subject.first(3).should == [posts[0], posts[1], posts[2]]
@@ -397,33 +398,33 @@ module MongoModel
397
398
  end
398
399
  end
399
400
  end
400
-
401
+
401
402
  context "with no argument" do
402
403
  context "when no matching documents exist" do
403
404
  before(:each) { model.stub_find([]) }
404
-
405
+
405
406
  always do
406
407
  it "returns nil" do
407
408
  subject.first.should be_nil
408
409
  end
409
410
  end
410
-
411
+
411
412
  subject_loaded do
412
413
  it "does not perform a find" do
413
414
  model.should_not_find { subject.first }
414
415
  end
415
416
  end
416
-
417
+
417
418
  subject_not_loaded do
418
419
  it "finds with a limit of 1" do
419
420
  model.should_find(finder_options.merge(:limit => 1), []) { subject.first }
420
421
  end
421
422
  end
422
423
  end
423
-
424
+
424
425
  context "when matching documents exist" do
425
426
  before(:each) { model.stub_find([posts[0]]) }
426
-
427
+
427
428
  always do
428
429
  it "returns the first document" do
429
430
  subject.first.should == posts[0]
@@ -432,39 +433,39 @@ module MongoModel
432
433
  end
433
434
  end
434
435
  end
435
-
436
+
436
437
  describe "#last" do
437
438
  def reversed_finder_options
438
439
  order = MongoModel::MongoOrder.parse(finder_options[:order] || [:id.asc])
439
440
  finder_options.merge(:order => order.reverse.to_a)
440
441
  end
441
-
442
+
442
443
  context "with count argument" do
443
444
  context "when no matching documents exist" do
444
445
  before(:each) { model.stub_find([]) }
445
-
446
+
446
447
  always do
447
448
  it "returns an empty array" do
448
449
  subject.last(2).should == []
449
450
  end
450
451
  end
451
-
452
+
452
453
  subject_loaded do
453
454
  it "does not perform a find" do
454
455
  model.should_not_find { subject.last(2) }
455
456
  end
456
457
  end
457
-
458
+
458
459
  subject_not_loaded do
459
460
  it "finds with a limit of 2" do
460
461
  model.should_find(reversed_finder_options.merge(:limit => 2), []) { subject.last(2) }
461
462
  end
462
463
  end
463
464
  end
464
-
465
+
465
466
  context "when matching documents exist" do
466
467
  before(:each) { model.stub_find([posts[0], posts[1]]) }
467
-
468
+
468
469
  always do
469
470
  it "returns the last documents in an array" do
470
471
  subject.last(2).should == [posts[0], posts[1]]
@@ -472,34 +473,34 @@ module MongoModel
472
473
  end
473
474
  end
474
475
  end
475
-
476
+
476
477
  context "with no argument" do
477
478
  context "when no matching documents exist" do
478
479
  before(:each) { model.stub_find([]) }
479
-
480
+
480
481
  always do
481
482
  it "returns nil" do
482
483
  subject.last.should be_nil
483
484
  end
484
485
  end
485
-
486
+
486
487
  subject_loaded do
487
488
  it "does not perform a find" do
488
489
  model.should_not_find { subject.last }
489
490
  end
490
491
  end
491
-
492
+
492
493
  subject_not_loaded do
493
494
  it "finds with a limit of 1" do
494
495
  model.should_find(reversed_finder_options.merge(:limit => 1), []) { subject.last }
495
496
  end
496
497
  end
497
498
  end
498
-
499
+
499
500
  context "when matching documents exist" do
500
501
  let(:post) { posts.last }
501
502
  before(:each) { model.stub_find([post]) }
502
-
503
+
503
504
  always do
504
505
  it "returns the last document" do
505
506
  subject.last.should == post
@@ -508,7 +509,7 @@ module MongoModel
508
509
  end
509
510
  end
510
511
  end
511
-
512
+
512
513
  describe "#all" do
513
514
  it "returns all documents" do
514
515
  model.should_find(finder_options, posts) do
@@ -516,20 +517,20 @@ module MongoModel
516
517
  end
517
518
  end
518
519
  end
519
-
520
+
520
521
  describe "#find" do
521
522
  context "with single id" do
522
523
  let(:post) { posts.first }
523
-
524
+
524
525
  it "performs find on collection" do
525
526
  model.should_find(finder_options.deep_merge(:conditions => { :id => post.id }, :limit => 1), [post]) do
526
527
  subject.find(post.id)
527
528
  end
528
529
  end
529
-
530
+
530
531
  context "when document exists" do
531
532
  before(:each) { model.stub_find([post]) }
532
-
533
+
533
534
  it "finds and return document" do
534
535
  subject.find(post.id).should == post
535
536
  end
@@ -537,7 +538,7 @@ module MongoModel
537
538
 
538
539
  context "when document does not exist" do
539
540
  before(:each) { model.stub_find([]) }
540
-
541
+
541
542
  it "raises a DocumentNotFound exception" do
542
543
  lambda {
543
544
  subject.find('missing')
@@ -549,24 +550,24 @@ module MongoModel
549
550
  context "by multiple ids" do
550
551
  let(:post1) { posts.first }
551
552
  let(:post2) { posts.last }
552
-
553
+
553
554
  it "performs find on collection" do
554
555
  model.should_find(finder_options.deep_merge(:conditions => { :id.in => [post2.id, post1.id] }), [post1, post2]) do
555
556
  subject.find(post2.id, post1.id)
556
557
  end
557
558
  end
558
-
559
+
559
560
  context "when all documents exist" do
560
561
  before(:each) { model.stub_find([post2, post1]) }
561
-
562
+
562
563
  it "returns documents in order given" do
563
564
  subject.find(post2.id, post1.id).should == [post2, post1]
564
565
  end
565
566
  end
566
-
567
+
567
568
  context "when some documents do not exist" do
568
569
  before(:each) { model.stub_find([post1]) }
569
-
570
+
570
571
  it "raises a DocumentNotFound exception" do
571
572
  lambda {
572
573
  subject.find(post1.id, 'missing')
@@ -575,7 +576,7 @@ module MongoModel
575
576
  end
576
577
  end
577
578
  end
578
-
579
+
579
580
  describe "#exists?" do
580
581
  let(:post) { posts.first }
581
582
 
@@ -587,28 +588,28 @@ module MongoModel
587
588
 
588
589
  context "when the document exists" do
589
590
  before(:each) { model.stub_find([post])}
590
-
591
+
591
592
  it "returns true" do
592
- subject.exists?(post.id).should be_true
593
+ subject.exists?(post.id).should be true
593
594
  end
594
595
  end
595
596
 
596
597
  context "when the document does not exist" do
597
598
  before(:each) { model.stub_find([])}
598
-
599
+
599
600
  it "returns false" do
600
- subject.exists?('missing').should be_false
601
+ subject.exists?('missing').should be false
601
602
  end
602
603
  end
603
604
  end
604
-
605
+
605
606
  describe "#delete_all" do
606
607
  it "removes all matching documents from collection" do
607
608
  model.should_delete(finder_conditions) do
608
609
  subject.delete_all
609
610
  end
610
611
  end
611
-
612
+
612
613
  subject_loaded do
613
614
  it "resets the scope" do
614
615
  subject.delete_all
@@ -616,7 +617,7 @@ module MongoModel
616
617
  end
617
618
  end
618
619
  end
619
-
620
+
620
621
  describe "#delete" do
621
622
  context "by single id" do
622
623
  it "removes the document from the collection" do
@@ -624,7 +625,7 @@ module MongoModel
624
625
  subject.delete("the-id")
625
626
  end
626
627
  end
627
-
628
+
628
629
  subject_loaded do
629
630
  it "resets the scope" do
630
631
  subject.delete("the-id")
@@ -632,14 +633,14 @@ module MongoModel
632
633
  end
633
634
  end
634
635
  end
635
-
636
+
636
637
  context "by multiple ids" do
637
638
  it "removes the document from the collection" do
638
639
  model.should_delete(finder_conditions.merge(:id.in => ["first-id", "second-id"])) do
639
640
  subject.delete("first-id", "second-id")
640
641
  end
641
642
  end
642
-
643
+
643
644
  subject_loaded do
644
645
  it "resets the scope" do
645
646
  subject.delete("first-id", "second-id")
@@ -648,19 +649,19 @@ module MongoModel
648
649
  end
649
650
  end
650
651
  end
651
-
652
+
652
653
  describe "#destroy_all" do
653
654
  let(:post1) { posts.first }
654
655
  let(:post2) { posts.last }
655
-
656
+
656
657
  before(:each) { model.stub_find([post1, post2]) }
657
-
658
+
658
659
  it "destroys all matching documents individually" do
659
660
  Post.should_delete(:id => post1.id)
660
661
  Post.should_delete(:id => post2.id)
661
662
  subject.destroy_all
662
663
  end
663
-
664
+
664
665
  subject_loaded do
665
666
  it "resets the scope" do
666
667
  subject.destroy_all
@@ -668,18 +669,18 @@ module MongoModel
668
669
  end
669
670
  end
670
671
  end
671
-
672
+
672
673
  describe "#destroy" do
673
674
  context "by single id" do
674
675
  let(:post) { posts.first }
675
-
676
+
676
677
  before(:each) { model.stub_find([post]) }
677
-
678
+
678
679
  it "destroys the retrieved document" do
679
680
  Post.should_delete(:id => post.id)
680
681
  subject.destroy(post.id)
681
682
  end
682
-
683
+
683
684
  subject_loaded do
684
685
  it "resets the scope" do
685
686
  subject.destroy(post.id)
@@ -687,19 +688,19 @@ module MongoModel
687
688
  end
688
689
  end
689
690
  end
690
-
691
+
691
692
  context "by multiple ids" do
692
693
  let(:post1) { posts.first }
693
694
  let(:post2) { posts.last }
694
-
695
+
695
696
  before(:each) { model.stub_find([post1, post2]) }
696
-
697
+
697
698
  it "destroys the documents individually" do
698
699
  Post.should_delete(:id => post1.id)
699
700
  Post.should_delete(:id => post2.id)
700
701
  subject.destroy(post1.id, post2.id)
701
702
  end
702
-
703
+
703
704
  subject_loaded do
704
705
  it "resets the scope" do
705
706
  subject.destroy(post1.id, post2.id)
@@ -708,13 +709,13 @@ module MongoModel
708
709
  end
709
710
  end
710
711
  end
711
-
712
+
712
713
  describe "#update_all" do
713
714
  it "updates all matching documents" do
714
715
  model.should_update(finder_conditions, { :name => "New name" })
715
716
  subject.update_all(:name => "New name")
716
717
  end
717
-
718
+
718
719
  subject_loaded do
719
720
  it "resets the scope" do
720
721
  subject.update_all(:name => "New name")
@@ -722,16 +723,16 @@ module MongoModel
722
723
  end
723
724
  end
724
725
  end
725
-
726
+
726
727
  describe "#update" do
727
728
  context "by single id" do
728
729
  let(:post) { posts.first }
729
-
730
+
730
731
  it "updates the document with the given id" do
731
732
  model.should_update(finder_conditions.merge(:id => post.id), { :name => "New name" })
732
733
  subject.update(post.id, :name => "New name")
733
734
  end
734
-
735
+
735
736
  subject_loaded do
736
737
  it "resets the scope" do
737
738
  subject.update(post.id, {})
@@ -739,16 +740,16 @@ module MongoModel
739
740
  end
740
741
  end
741
742
  end
742
-
743
+
743
744
  context "by multiple ids" do
744
745
  let(:post1) { posts.first }
745
746
  let(:post2) { posts.last }
746
-
747
+
747
748
  it "updates the documents with the given ids" do
748
749
  model.should_update(finder_conditions.merge(:id.in => [post1.id, post2.id]), { :name => "New name" })
749
750
  subject.update([post1.id, post2.id], :name => "New name")
750
751
  end
751
-
752
+
752
753
  subject_loaded do
753
754
  it "resets the scope" do
754
755
  subject.update([post1.id, post2.id], {})
@@ -757,55 +758,55 @@ module MongoModel
757
758
  end
758
759
  end
759
760
  end
760
-
761
+
761
762
  describe "#paginate" do
762
763
  it "loads the first page of results by default" do
763
764
  model.should_find(finder_options.merge(:offset => 0, :limit => 20), posts) {
764
765
  subject.paginate
765
766
  }
766
767
  end
767
-
768
+
768
769
  it "loads a specified page of results" do
769
770
  model.should_find(finder_options.merge(:offset => 40, :limit => 20), posts) {
770
771
  subject.paginate(:page => 3)
771
772
  }
772
773
  end
773
-
774
+
774
775
  it "allows the per_page option to be set" do
775
776
  model.should_find(finder_options.merge(:offset => 7, :limit => 7), posts) {
776
777
  subject.paginate(:per_page => 7, :page => 2)
777
778
  }
778
779
  end
779
-
780
+
780
781
  it "auto s-detect total entries where possible" do
781
782
  paginator = nil
782
-
783
+
783
784
  model.should_find(finder_options.merge(:offset => 0, :limit => 20), posts) {
784
785
  paginator = subject.paginate
785
786
  }
786
-
787
+
787
788
  paginator.total_entries.should == 5
788
789
  end
789
-
790
+
790
791
  it "loads total entries using count when auto-detection not possible" do
791
792
  paginator = nil
792
-
793
+
793
794
  subject.stub(:count).and_return(57)
794
795
  model.should_find(finder_options.merge(:offset => 0, :limit => 5), posts) {
795
796
  paginator = subject.paginate(:per_page => 5)
796
797
  }
797
-
798
+
798
799
  paginator.total_entries.should == 57
799
800
  end
800
801
  end
801
-
802
+
802
803
  describe "#in_batches" do
803
804
  it "yields documents in groups of given size" do
804
805
  model.should_find(finder_options.merge(:offset => 0, :limit => 3), posts.first(3))
805
806
  model.should_find(finder_options.merge(:offset => 3, :limit => 3), posts.last(2))
806
-
807
+
807
808
  expected_size = 3
808
-
809
+
809
810
  subject.in_batches(3) do |docs|
810
811
  docs.size.should == expected_size
811
812
  expected_size = 2
@@ -813,34 +814,34 @@ module MongoModel
813
814
  end
814
815
  end
815
816
  end
816
-
817
-
817
+
818
+
818
819
  context "without criteria" do
819
820
  subject { basic_scope }
820
-
821
+
821
822
  context "when initialized" do
822
823
  it { should_not be_loaded }
823
824
  end
824
-
825
+
825
826
  context "when loaded" do
826
827
  before(:each) { subject.to_a }
827
828
  its(:clone) { should_not be_loaded }
828
829
  end
829
-
830
+
830
831
  def model
831
832
  Post
832
833
  end
833
-
834
+
834
835
  def finder_options
835
836
  {}
836
837
  end
837
-
838
+
838
839
  it_should_behave_like "all scopes"
839
-
840
+
840
841
  it "uses collection from class" do
841
842
  subject.collection.should == Post.collection
842
843
  end
843
-
844
+
844
845
  describe "#inspect" do
845
846
  before(:each) { Post.stub_find(posts) }
846
847
 
@@ -848,10 +849,10 @@ module MongoModel
848
849
  subject.inspect.should == posts.inspect
849
850
  end
850
851
  end
851
-
852
+
852
853
  describe "#==" do
853
854
  define_class(:NotAPost, Document)
854
-
855
+
855
856
  it "is equal to a new scope for the same class" do
856
857
  subject.should == Scope.new(Post)
857
858
  end
@@ -860,69 +861,69 @@ module MongoModel
860
861
  subject.should_not == Scope.new(NotAPost)
861
862
  end
862
863
  end
863
-
864
+
864
865
  describe "#reverse_order" do
865
866
  subject { basic_scope.reverse_order }
866
-
867
+
867
868
  it "returns a new scope" do
868
869
  subject.should be_an_instance_of(Scope)
869
870
  end
870
-
871
+
871
872
  it "is not loaded" do
872
873
  basic_scope.to_a # Load parent scope
873
874
  subject.should_not be_loaded
874
875
  end
875
-
876
+
876
877
  it "sets the order value to descending by id" do
877
878
  subject.order_values.should == [:id.desc]
878
879
  end
879
880
  end
880
-
881
+
881
882
  describe "#build" do
882
883
  it "returns a new document" do
883
884
  subject.build.should be_an_instance_of(Post)
884
885
  end
885
-
886
+
886
887
  it "is aliased as #new" do
887
888
  subject.new(:id => '123').should == subject.build(:id => '123')
888
889
  end
889
890
  end
890
-
891
+
891
892
  describe "#create" do
892
893
  it "returns a new document" do
893
894
  subject.create.should be_an_instance_of(Post)
894
895
  end
895
-
896
+
896
897
  it "saves the document" do
897
898
  subject.create.should_not be_a_new_record
898
899
  end
899
900
  end
900
-
901
+
901
902
  describe "#apply_finder_options" do
902
903
  it "returns a new scope" do
903
904
  subject.apply_finder_options({}).should be_an_instance_of(Scope)
904
905
  end
905
-
906
+
906
907
  it "sets where values from options" do
907
908
  scope = subject.apply_finder_options({ :conditions => { :author => "John" } })
908
909
  scope.where_values.should == [{ :author => "John" }]
909
910
  end
910
-
911
+
911
912
  it "sets order values from options" do
912
913
  scope = subject.apply_finder_options({ :order => :author.desc })
913
914
  scope.order_values.should == [:author.desc]
914
915
  end
915
-
916
+
916
917
  it "sets select values from options" do
917
918
  scope = subject.apply_finder_options({ :select => [:id, :author] })
918
919
  scope.select_values.should == [:id, :author]
919
920
  end
920
-
921
+
921
922
  it "sets offset value from options" do
922
923
  scope = subject.apply_finder_options({ :offset => 40 })
923
924
  scope.offset_value.should == 40
924
925
  end
925
-
926
+
926
927
  it "sets limit value from options" do
927
928
  scope = subject.apply_finder_options({ :limit => 50 })
928
929
  scope.limit_value.should == 50
@@ -930,10 +931,10 @@ module MongoModel
930
931
  end
931
932
  end
932
933
 
933
-
934
+
934
935
  context "with criteria" do
935
936
  define_class(:OtherPost, Document)
936
-
937
+
937
938
  let(:timestamp) { Time.now }
938
939
  let(:scoped) do
939
940
  basic_scope.where(:author => "Sam").
@@ -947,17 +948,17 @@ module MongoModel
947
948
  limit(7).
948
949
  from(OtherPost.collection)
949
950
  end
950
-
951
+
951
952
  subject { scoped }
952
-
953
+
953
954
  def truncate_timestamp(time)
954
955
  time.change(:usec => (time.usec / 1000.0).floor * 1000)
955
956
  end
956
-
957
+
957
958
  def model
958
959
  OtherPost
959
960
  end
960
-
961
+
961
962
  def finder_options
962
963
  {
963
964
  :conditions => { "author" => "Sam", "published" => true, "date" => { "$lt" => truncate_timestamp(timestamp.utc) } },
@@ -967,35 +968,35 @@ module MongoModel
967
968
  :limit => 7
968
969
  }
969
970
  end
970
-
971
+
971
972
  it_should_behave_like "all scopes"
972
-
973
+
973
974
  describe "#build" do
974
975
  it "uses equality where conditions as attributes" do
975
976
  doc = subject.build
976
977
  doc.author.should == "Sam"
977
- doc.published.should be_true
978
+ doc.published.should be true
978
979
  doc.date.should be_nil
979
980
  end
980
981
  end
981
-
982
+
982
983
  describe "#create" do
983
984
  it "uses equality where conditions as attributes" do
984
985
  doc = subject.create
985
986
  doc.author.should == "Sam"
986
- doc.published.should be_true
987
+ doc.published.should be true
987
988
  doc.date.should be_nil
988
989
  end
989
990
  end
990
-
991
+
991
992
  describe "#reverse_order" do
992
993
  subject { scoped.reverse_order }
993
-
994
+
994
995
  it "sets the order values to the reverse order" do
995
996
  subject.order_values.should == MongoOrder.parse([:author.desc, :published.asc]).to_a
996
997
  end
997
998
  end
998
-
999
+
999
1000
  describe "#except" do
1000
1001
  context "given :where" do
1001
1002
  it "returns a new scope without where values" do
@@ -1069,7 +1070,7 @@ module MongoModel
1069
1070
  end
1070
1071
  end
1071
1072
  end
1072
-
1073
+
1073
1074
  describe "#merge" do
1074
1075
  let(:on_load_proc) { proc {} }
1075
1076
  let(:merged) do
@@ -1079,7 +1080,7 @@ module MongoModel
1079
1080
  on_load(&on_load_proc)
1080
1081
  end
1081
1082
  let(:result) { subject.merge(merged) }
1082
-
1083
+
1083
1084
  it "combines where values from scopes" do
1084
1085
  result.where_values.should == [
1085
1086
  { :author => "Sam" },
@@ -1088,51 +1089,51 @@ module MongoModel
1088
1089
  { :date.gt => timestamp-1.year }
1089
1090
  ]
1090
1091
  end
1091
-
1092
+
1092
1093
  it "combines order values from scopes" do
1093
1094
  result.order_values.should == [:author.asc, :published.desc, :date.desc]
1094
1095
  end
1095
-
1096
+
1096
1097
  it "combines select values from scopes" do
1097
1098
  result.select_values.should == [:author, :published, :date]
1098
1099
  end
1099
-
1100
+
1100
1101
  it "preserves on load proc" do
1101
1102
  result.on_load_proc.should == on_load_proc
1102
1103
  end
1103
-
1104
+
1104
1105
  context "merged scope has offset value" do
1105
1106
  let(:merged) { basic_scope.offset(10) }
1106
-
1107
+
1107
1108
  it "uses offset value from merged scope" do
1108
1109
  result.offset_value.should == 10
1109
1110
  end
1110
1111
  end
1111
-
1112
+
1112
1113
  context "merged scope has no offset value set" do
1113
1114
  let(:merged) { basic_scope }
1114
-
1115
+
1115
1116
  it "uses offset value from original scope" do
1116
1117
  result.offset_value.should == 15
1117
1118
  end
1118
1119
  end
1119
-
1120
+
1120
1121
  context "merged scope has limit value" do
1121
1122
  let(:merged) { basic_scope.limit(50) }
1122
-
1123
+
1123
1124
  it "uses limit value from merged scope" do
1124
1125
  result.limit_value.should == 50
1125
1126
  end
1126
1127
  end
1127
-
1128
+
1128
1129
  context "merged scope has no limit value set" do
1129
1130
  let(:merged) { basic_scope }
1130
-
1131
+
1131
1132
  it "uses limit value from original scope" do
1132
1133
  result.limit_value.should == 7
1133
1134
  end
1134
1135
  end
1135
-
1136
+
1136
1137
  it "uses from value (collection) from merged scope" do
1137
1138
  merged = basic_scope.from(Post.collection)
1138
1139
  subject.merge(merged).collection.should == Post.collection