mongomodel 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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