humanoid 1.2.7

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 (210) hide show
  1. data/.gitignore +6 -0
  2. data/.watchr +29 -0
  3. data/HISTORY +342 -0
  4. data/MIT_LICENSE +20 -0
  5. data/README.rdoc +56 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/caliper.yml +4 -0
  9. data/humanoid.gemspec +374 -0
  10. data/lib/humanoid.rb +111 -0
  11. data/lib/humanoid/associations.rb +258 -0
  12. data/lib/humanoid/associations/belongs_to.rb +64 -0
  13. data/lib/humanoid/associations/belongs_to_related.rb +62 -0
  14. data/lib/humanoid/associations/has_many.rb +180 -0
  15. data/lib/humanoid/associations/has_many_related.rb +109 -0
  16. data/lib/humanoid/associations/has_one.rb +95 -0
  17. data/lib/humanoid/associations/has_one_related.rb +81 -0
  18. data/lib/humanoid/associations/options.rb +57 -0
  19. data/lib/humanoid/associations/proxy.rb +31 -0
  20. data/lib/humanoid/attributes.rb +184 -0
  21. data/lib/humanoid/callbacks.rb +23 -0
  22. data/lib/humanoid/collection.rb +118 -0
  23. data/lib/humanoid/collections/cyclic_iterator.rb +34 -0
  24. data/lib/humanoid/collections/master.rb +28 -0
  25. data/lib/humanoid/collections/mimic.rb +46 -0
  26. data/lib/humanoid/collections/operations.rb +41 -0
  27. data/lib/humanoid/collections/slaves.rb +44 -0
  28. data/lib/humanoid/commands.rb +182 -0
  29. data/lib/humanoid/commands/create.rb +21 -0
  30. data/lib/humanoid/commands/delete.rb +16 -0
  31. data/lib/humanoid/commands/delete_all.rb +23 -0
  32. data/lib/humanoid/commands/deletion.rb +18 -0
  33. data/lib/humanoid/commands/destroy.rb +19 -0
  34. data/lib/humanoid/commands/destroy_all.rb +23 -0
  35. data/lib/humanoid/commands/save.rb +27 -0
  36. data/lib/humanoid/components.rb +24 -0
  37. data/lib/humanoid/config.rb +84 -0
  38. data/lib/humanoid/contexts.rb +25 -0
  39. data/lib/humanoid/contexts/enumerable.rb +117 -0
  40. data/lib/humanoid/contexts/ids.rb +25 -0
  41. data/lib/humanoid/contexts/mongo.rb +224 -0
  42. data/lib/humanoid/contexts/paging.rb +42 -0
  43. data/lib/humanoid/criteria.rb +259 -0
  44. data/lib/humanoid/criterion/complex.rb +21 -0
  45. data/lib/humanoid/criterion/exclusion.rb +65 -0
  46. data/lib/humanoid/criterion/inclusion.rb +91 -0
  47. data/lib/humanoid/criterion/optional.rb +128 -0
  48. data/lib/humanoid/cursor.rb +82 -0
  49. data/lib/humanoid/document.rb +300 -0
  50. data/lib/humanoid/enslavement.rb +38 -0
  51. data/lib/humanoid/errors.rb +77 -0
  52. data/lib/humanoid/extensions.rb +84 -0
  53. data/lib/humanoid/extensions/array/accessors.rb +17 -0
  54. data/lib/humanoid/extensions/array/aliasing.rb +4 -0
  55. data/lib/humanoid/extensions/array/assimilation.rb +26 -0
  56. data/lib/humanoid/extensions/array/conversions.rb +29 -0
  57. data/lib/humanoid/extensions/array/parentization.rb +13 -0
  58. data/lib/humanoid/extensions/boolean/conversions.rb +16 -0
  59. data/lib/humanoid/extensions/date/conversions.rb +15 -0
  60. data/lib/humanoid/extensions/datetime/conversions.rb +17 -0
  61. data/lib/humanoid/extensions/float/conversions.rb +16 -0
  62. data/lib/humanoid/extensions/hash/accessors.rb +38 -0
  63. data/lib/humanoid/extensions/hash/assimilation.rb +30 -0
  64. data/lib/humanoid/extensions/hash/conversions.rb +15 -0
  65. data/lib/humanoid/extensions/hash/criteria_helpers.rb +20 -0
  66. data/lib/humanoid/extensions/hash/scoping.rb +12 -0
  67. data/lib/humanoid/extensions/integer/conversions.rb +16 -0
  68. data/lib/humanoid/extensions/nil/assimilation.rb +13 -0
  69. data/lib/humanoid/extensions/object/conversions.rb +33 -0
  70. data/lib/humanoid/extensions/proc/scoping.rb +12 -0
  71. data/lib/humanoid/extensions/string/conversions.rb +15 -0
  72. data/lib/humanoid/extensions/string/inflections.rb +97 -0
  73. data/lib/humanoid/extensions/symbol/inflections.rb +36 -0
  74. data/lib/humanoid/extensions/time/conversions.rb +18 -0
  75. data/lib/humanoid/factory.rb +19 -0
  76. data/lib/humanoid/field.rb +39 -0
  77. data/lib/humanoid/fields.rb +62 -0
  78. data/lib/humanoid/finders.rb +224 -0
  79. data/lib/humanoid/identity.rb +39 -0
  80. data/lib/humanoid/indexes.rb +30 -0
  81. data/lib/humanoid/matchers.rb +36 -0
  82. data/lib/humanoid/matchers/all.rb +11 -0
  83. data/lib/humanoid/matchers/default.rb +26 -0
  84. data/lib/humanoid/matchers/exists.rb +13 -0
  85. data/lib/humanoid/matchers/gt.rb +11 -0
  86. data/lib/humanoid/matchers/gte.rb +11 -0
  87. data/lib/humanoid/matchers/in.rb +11 -0
  88. data/lib/humanoid/matchers/lt.rb +11 -0
  89. data/lib/humanoid/matchers/lte.rb +11 -0
  90. data/lib/humanoid/matchers/ne.rb +11 -0
  91. data/lib/humanoid/matchers/nin.rb +11 -0
  92. data/lib/humanoid/matchers/size.rb +11 -0
  93. data/lib/humanoid/memoization.rb +27 -0
  94. data/lib/humanoid/named_scope.rb +40 -0
  95. data/lib/humanoid/scope.rb +75 -0
  96. data/lib/humanoid/timestamps.rb +30 -0
  97. data/lib/humanoid/versioning.rb +28 -0
  98. data/perf/benchmark.rb +77 -0
  99. data/spec/integration/humanoid/associations_spec.rb +301 -0
  100. data/spec/integration/humanoid/attributes_spec.rb +22 -0
  101. data/spec/integration/humanoid/commands_spec.rb +216 -0
  102. data/spec/integration/humanoid/contexts/enumerable_spec.rb +33 -0
  103. data/spec/integration/humanoid/criteria_spec.rb +224 -0
  104. data/spec/integration/humanoid/document_spec.rb +587 -0
  105. data/spec/integration/humanoid/extensions_spec.rb +26 -0
  106. data/spec/integration/humanoid/finders_spec.rb +119 -0
  107. data/spec/integration/humanoid/inheritance_spec.rb +137 -0
  108. data/spec/integration/humanoid/named_scope_spec.rb +46 -0
  109. data/spec/models/address.rb +39 -0
  110. data/spec/models/animal.rb +6 -0
  111. data/spec/models/comment.rb +8 -0
  112. data/spec/models/country_code.rb +6 -0
  113. data/spec/models/employer.rb +5 -0
  114. data/spec/models/game.rb +6 -0
  115. data/spec/models/inheritance.rb +56 -0
  116. data/spec/models/location.rb +5 -0
  117. data/spec/models/mixed_drink.rb +4 -0
  118. data/spec/models/name.rb +13 -0
  119. data/spec/models/namespacing.rb +11 -0
  120. data/spec/models/patient.rb +4 -0
  121. data/spec/models/person.rb +98 -0
  122. data/spec/models/pet.rb +7 -0
  123. data/spec/models/pet_owner.rb +6 -0
  124. data/spec/models/phone.rb +7 -0
  125. data/spec/models/post.rb +15 -0
  126. data/spec/models/translation.rb +5 -0
  127. data/spec/models/vet_visit.rb +5 -0
  128. data/spec/spec.opts +3 -0
  129. data/spec/spec_helper.rb +31 -0
  130. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +141 -0
  131. data/spec/unit/mongoid/associations/belongs_to_spec.rb +193 -0
  132. data/spec/unit/mongoid/associations/has_many_related_spec.rb +387 -0
  133. data/spec/unit/mongoid/associations/has_many_spec.rb +471 -0
  134. data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
  135. data/spec/unit/mongoid/associations/has_one_spec.rb +282 -0
  136. data/spec/unit/mongoid/associations/options_spec.rb +191 -0
  137. data/spec/unit/mongoid/associations_spec.rb +545 -0
  138. data/spec/unit/mongoid/attributes_spec.rb +484 -0
  139. data/spec/unit/mongoid/callbacks_spec.rb +55 -0
  140. data/spec/unit/mongoid/collection_spec.rb +171 -0
  141. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  142. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  143. data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
  144. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  145. data/spec/unit/mongoid/commands/create_spec.rb +30 -0
  146. data/spec/unit/mongoid/commands/delete_all_spec.rb +58 -0
  147. data/spec/unit/mongoid/commands/delete_spec.rb +35 -0
  148. data/spec/unit/mongoid/commands/destroy_all_spec.rb +23 -0
  149. data/spec/unit/mongoid/commands/destroy_spec.rb +44 -0
  150. data/spec/unit/mongoid/commands/save_spec.rb +105 -0
  151. data/spec/unit/mongoid/commands_spec.rb +282 -0
  152. data/spec/unit/mongoid/config_spec.rb +165 -0
  153. data/spec/unit/mongoid/contexts/enumerable_spec.rb +374 -0
  154. data/spec/unit/mongoid/contexts/mongo_spec.rb +505 -0
  155. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  156. data/spec/unit/mongoid/criteria_spec.rb +769 -0
  157. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  158. data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
  159. data/spec/unit/mongoid/criterion/inclusion_spec.rb +211 -0
  160. data/spec/unit/mongoid/criterion/optional_spec.rb +329 -0
  161. data/spec/unit/mongoid/cursor_spec.rb +74 -0
  162. data/spec/unit/mongoid/document_spec.rb +986 -0
  163. data/spec/unit/mongoid/enslavement_spec.rb +63 -0
  164. data/spec/unit/mongoid/errors_spec.rb +103 -0
  165. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  166. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  167. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
  168. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  169. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  170. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
  171. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +70 -0
  172. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  173. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  174. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
  175. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
  176. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  177. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  178. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  179. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
  180. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +43 -0
  181. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  182. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
  183. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  184. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
  185. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
  186. data/spec/unit/mongoid/factory_spec.rb +31 -0
  187. data/spec/unit/mongoid/field_spec.rb +81 -0
  188. data/spec/unit/mongoid/fields_spec.rb +158 -0
  189. data/spec/unit/mongoid/finders_spec.rb +368 -0
  190. data/spec/unit/mongoid/identity_spec.rb +88 -0
  191. data/spec/unit/mongoid/indexes_spec.rb +93 -0
  192. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  193. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  194. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  195. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  196. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  197. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  198. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  199. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  200. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  201. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  202. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  203. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  204. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  205. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  206. data/spec/unit/mongoid/scope_spec.rb +240 -0
  207. data/spec/unit/mongoid/timestamps_spec.rb +25 -0
  208. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  209. data/spec/unit/mongoid_spec.rb +37 -0
  210. metadata +431 -0
@@ -0,0 +1,165 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Config do
4
+
5
+ after :all do
6
+ config.raise_not_found_error = true
7
+ end
8
+
9
+ let(:config) { Humanoid::Config.instance }
10
+
11
+ describe "#database=" do
12
+
13
+ context "when object provided is not a Mongo::DB" do
14
+
15
+ it "raises an error" do
16
+ lambda { config.database = "Test" }.should raise_error
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ describe "#master=" do
24
+
25
+ context "when object provided is not a Mongo::DB" do
26
+
27
+ it "raises an error" do
28
+ lambda { config.master = "Test" }.should raise_error
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ describe "#parameterize_keys" do
36
+
37
+ it "defaults to true" do
38
+ config.parameterize_keys.should == true
39
+ end
40
+ end
41
+
42
+ describe "#persist_in_safe_mode=" do
43
+
44
+ context "when setting to true" do
45
+
46
+ before do
47
+ config.persist_in_safe_mode = true
48
+ end
49
+
50
+ it "sets the value" do
51
+ config.persist_in_safe_mode.should == true
52
+ end
53
+
54
+ end
55
+
56
+ context "when setting to false" do
57
+
58
+ before do
59
+ config.persist_in_safe_mode = false
60
+ end
61
+
62
+ it "sets the value" do
63
+ config.persist_in_safe_mode.should == false
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ describe "#raise_not_found_error=" do
71
+
72
+ context "when setting to true" do
73
+
74
+ before do
75
+ config.raise_not_found_error = true
76
+ end
77
+
78
+ it "sets the value" do
79
+ config.raise_not_found_error.should == true
80
+ end
81
+
82
+ end
83
+
84
+ context "when setting to false" do
85
+
86
+ before do
87
+ config.raise_not_found_error = false
88
+ end
89
+
90
+ it "sets the value" do
91
+ config.raise_not_found_error.should == false
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ describe "#reconnect_time" do
99
+
100
+ it "defaults to 3" do
101
+ config.reconnect_time.should == 3
102
+ end
103
+
104
+ end
105
+
106
+ describe "#reconnect_time=" do
107
+
108
+ after do
109
+ config.reconnect_time = 3
110
+ end
111
+
112
+ it "sets the time" do
113
+ config.reconnect_time = 5
114
+ config.reconnect_time.should == 5
115
+ end
116
+ end
117
+
118
+ describe "#slaves=" do
119
+
120
+ context "when object provided is not a Mongo::DB" do
121
+
122
+ it "raises an error" do
123
+ lambda { config.slaves = ["Test"] }.should raise_error
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+ describe "#allow_dynamic_fields=" do
131
+
132
+ context "when setting to true" do
133
+
134
+ before do
135
+ config.allow_dynamic_fields = true
136
+ end
137
+
138
+ it "sets the value" do
139
+ config.allow_dynamic_fields.should == true
140
+ end
141
+
142
+ end
143
+
144
+ context "when setting to false" do
145
+
146
+ before do
147
+ config.allow_dynamic_fields = false
148
+ end
149
+
150
+ it "sets the value" do
151
+ config.allow_dynamic_fields.should == false
152
+ end
153
+
154
+ end
155
+
156
+ end
157
+
158
+ describe "#use_object_ids" do
159
+
160
+ it "defaults to false" do
161
+ config.use_object_ids.should == false
162
+ end
163
+ end
164
+
165
+ end
@@ -0,0 +1,374 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Contexts::Enumerable do
4
+
5
+ before do
6
+ @london = Address.new(:number => 1, :street => "Bond Street")
7
+ @shanghai = Address.new(:number => 10, :street => "Nan Jing Dong Lu")
8
+ @melbourne = Address.new(:number => 20, :street => "Bourke Street")
9
+ @new_york = Address.new(:number => 20, :street => "Broadway")
10
+ @docs = [ @london, @shanghai, @melbourne, @new_york ]
11
+ @criteria = Humanoid::Criteria.new(Address)
12
+ @criteria.documents = @docs
13
+ @criteria.where(:street => "Bourke Street").only(:number)
14
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
15
+ end
16
+
17
+ describe "#aggregate" do
18
+
19
+ before do
20
+ @counts = @context.aggregate
21
+ end
22
+
23
+ it "groups by the fields provided in the options" do
24
+ @counts.size.should == 3
25
+ end
26
+
27
+ it "stores the counts in proper groups" do
28
+ @counts[1].should == 1
29
+ @counts[10].should == 1
30
+ @counts[20].should == 2
31
+ end
32
+ end
33
+
34
+ describe "#count" do
35
+
36
+ it "returns the size of the enumerable" do
37
+ @context.count.should == 4
38
+ end
39
+
40
+ end
41
+
42
+ describe "#execute" do
43
+
44
+ before do
45
+ @criteria = Humanoid::Criteria.new(Address)
46
+ @criteria.documents = @docs
47
+ end
48
+
49
+ it "returns the matching documents from the array" do
50
+ @context.execute.should == [ @melbourne ]
51
+ end
52
+
53
+ context "when selector is empty" do
54
+
55
+ before do
56
+ @criteria.only(:number)
57
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
58
+ end
59
+
60
+ it "returns all the documents" do
61
+ @context.execute.should == @docs
62
+ end
63
+ end
64
+
65
+ context "when skip and limit are in the options" do
66
+
67
+ before do
68
+ @criteria.skip(2).limit(2)
69
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
70
+ end
71
+
72
+ it "properly narrows down the matching results" do
73
+ @context.execute.should == [ @melbourne, @new_york ]
74
+ end
75
+ end
76
+
77
+ context "when limit is set without skip in the options" do
78
+
79
+ before do
80
+ @criteria.limit(2)
81
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
82
+ end
83
+
84
+ it "properly narrows down the matching results" do
85
+ @context.execute.size.should == 2
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ describe "#first" do
93
+
94
+ context "when a selector is present" do
95
+
96
+ it "returns the first that matches the selector" do
97
+ @context.first.should == @melbourne
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ describe "#group" do
104
+
105
+ before do
106
+ @group = @context.group
107
+ end
108
+
109
+ it "groups by the fields provided in the options" do
110
+ @group.size.should == 3
111
+ end
112
+
113
+ it "stores the documents in proper groups" do
114
+ @group[1].should == [ @london ]
115
+ @group[10].should == [ @shanghai ]
116
+ @group[20].should == [ @melbourne, @new_york ]
117
+ end
118
+
119
+ end
120
+
121
+ describe ".initialize" do
122
+
123
+ let(:selector) { { :field => "value" } }
124
+ let(:options) { { :skip => 20 } }
125
+ let(:documents) { [stub] }
126
+
127
+ before do
128
+ @criteria = Humanoid::Criteria.new(Address)
129
+ @criteria.documents = documents
130
+ @criteria.where(selector).skip(20)
131
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
132
+ end
133
+
134
+ it "sets the selector" do
135
+ @context.selector.should == selector
136
+ end
137
+
138
+ it "sets the options" do
139
+ @context.options.should == options
140
+ end
141
+
142
+ it "sets the documents" do
143
+ @context.documents.should == documents
144
+ end
145
+
146
+ end
147
+
148
+ describe "#last" do
149
+
150
+ it "returns the last matching in the enumerable" do
151
+ @context.last.should == @melbourne
152
+ end
153
+
154
+ end
155
+
156
+ describe "#max" do
157
+
158
+ it "returns the max value for the supplied field" do
159
+ @context.max(:number).should == 20
160
+ end
161
+
162
+ end
163
+
164
+ describe "#min" do
165
+
166
+ it "returns the min value for the supplied field" do
167
+ @context.min(:number).should == 1
168
+ end
169
+
170
+ end
171
+
172
+ describe "#one" do
173
+
174
+ it "returns the first matching in the enumerable" do
175
+ @context.one.should == @melbourne
176
+ end
177
+
178
+ end
179
+
180
+ describe "#page" do
181
+
182
+ context "when the page option exists" do
183
+
184
+ before do
185
+ @criteria = Humanoid::Criteria.new(Person).extras({ :page => 5 })
186
+ @criteria.documents = []
187
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
188
+ end
189
+
190
+ it "returns the page option" do
191
+ @context.page.should == 5
192
+ end
193
+
194
+ end
195
+
196
+ context "when the page option does not exist" do
197
+
198
+ before do
199
+ @criteria = Humanoid::Criteria.new(Person)
200
+ @criteria.documents = []
201
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
202
+ end
203
+
204
+ it "returns 1" do
205
+ @context.page.should == 1
206
+ end
207
+
208
+ end
209
+
210
+ end
211
+
212
+ describe "#paginate" do
213
+
214
+ before do
215
+ @criteria = Person.criteria.skip(2).limit(2)
216
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
217
+ @results = @context.paginate
218
+ end
219
+
220
+ it "executes and paginates the results" do
221
+ @results.current_page.should == 2
222
+ @results.per_page.should == 2
223
+ end
224
+
225
+ end
226
+
227
+ describe "#per_page" do
228
+
229
+ context "when a limit option exists" do
230
+
231
+ it "returns 20" do
232
+ @context.per_page.should == 20
233
+ end
234
+
235
+ end
236
+
237
+ context "when a limit option does not exist" do
238
+
239
+ before do
240
+ @criteria = Person.criteria.limit(50)
241
+ @criteria.documents = []
242
+ @context = Humanoid::Contexts::Enumerable.new(@criteria)
243
+ end
244
+
245
+ it "returns the limit" do
246
+ @context.per_page.should == 50
247
+ end
248
+
249
+ end
250
+
251
+ end
252
+
253
+ describe "#sum" do
254
+
255
+ it "returns the sum of all the field values" do
256
+ @context.sum(:number).should == 51
257
+ end
258
+
259
+ end
260
+
261
+ context "#id_criteria" do
262
+
263
+ let(:criteria) do
264
+ criteria = Humanoid::Criteria.new(Address)
265
+ criteria.documents = []
266
+ criteria
267
+ end
268
+ let(:context) { criteria.context }
269
+
270
+ context "with a single argument" do
271
+
272
+ let(:id) { Mongo::ObjectID.new.to_s }
273
+
274
+ before do
275
+ criteria.expects(:id).with(id).returns(criteria)
276
+ end
277
+
278
+ context "when the document is found" do
279
+
280
+ let(:document) { stub }
281
+
282
+ it "returns a matching document" do
283
+ context.expects(:one).returns(document)
284
+ document.expects(:blank? => false)
285
+ context.id_criteria(id).should == document
286
+ end
287
+
288
+ end
289
+
290
+ context "when the document is not found" do
291
+
292
+ it "raises an error" do
293
+ context.expects(:one).returns(nil)
294
+ lambda { context.id_criteria(id) }.should raise_error
295
+ end
296
+
297
+ end
298
+
299
+ end
300
+
301
+ context "multiple arguments" do
302
+
303
+ context "when an array of ids" do
304
+
305
+ let(:ids) do
306
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new.to_s }
307
+ end
308
+
309
+ context "when documents are found" do
310
+
311
+ let(:docs) do
312
+ (0..2).inject([]) { |ary, i| ary << stub }
313
+ end
314
+
315
+ before do
316
+ criteria.expects(:id).with(ids).returns(criteria)
317
+ end
318
+
319
+ it "returns matching documents" do
320
+ context.expects(:execute).returns(docs)
321
+ context.id_criteria(ids).should == docs
322
+ end
323
+
324
+ end
325
+
326
+ context "when documents are not found" do
327
+
328
+ it "raises an error" do
329
+ context.expects(:execute).returns([])
330
+ lambda { context.id_criteria(ids) }.should raise_error
331
+ end
332
+
333
+ end
334
+
335
+ end
336
+
337
+ context "when an array of object ids" do
338
+
339
+ let(:ids) do
340
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new }
341
+ end
342
+
343
+ context "when documents are found" do
344
+
345
+ let(:docs) do
346
+ (0..2).inject([]) { |ary, i| ary << stub }
347
+ end
348
+
349
+ before do
350
+ criteria.expects(:id).with(ids).returns(criteria)
351
+ end
352
+
353
+ it "returns matching documents" do
354
+ context.expects(:execute).returns(docs)
355
+ context.id_criteria(ids).should == docs
356
+ end
357
+
358
+ end
359
+
360
+ context "when documents are not found" do
361
+
362
+ it "raises an error" do
363
+ context.expects(:execute).returns([])
364
+ lambda { context.id_criteria(ids) }.should raise_error
365
+ end
366
+
367
+ end
368
+
369
+ end
370
+ end
371
+
372
+ end
373
+
374
+ end