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,31 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Factory do
4
+
5
+ describe ".build" do
6
+
7
+ context "when the _type attribute is present" do
8
+
9
+ before do
10
+ @attributes = { "_type" => "Person", "title" => "Sir" }
11
+ end
12
+
13
+ it "instantiates based on the type" do
14
+ person = Humanoid::Factory.build(Person, @attributes)
15
+ person.title.should == "Sir"
16
+ end
17
+ end
18
+
19
+ context "when _type is not preset" do
20
+
21
+ before do
22
+ @attributes = { "title" => "Sir" }
23
+ end
24
+
25
+ it "instantiates based on the type" do
26
+ person = Humanoid::Factory.build(Person, @attributes)
27
+ person.title.should == "Sir"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Field do
4
+
5
+ describe "#default" do
6
+
7
+ before do
8
+ @field = Humanoid::Field.new(:score, :default => 0)
9
+ end
10
+
11
+ it "returns the default option" do
12
+ @field.default.should == 0
13
+ end
14
+
15
+ end
16
+
17
+ describe "#name" do
18
+
19
+ before do
20
+ @field = Humanoid::Field.new(:score, :default => 0)
21
+ end
22
+
23
+ it "returns the name" do
24
+ @field.name.should == :score
25
+ end
26
+
27
+ end
28
+
29
+ describe "#type" do
30
+
31
+ before do
32
+ @field = Humanoid::Field.new(:name)
33
+ end
34
+
35
+ it "defaults to String" do
36
+ @field.type.should == String
37
+ end
38
+
39
+ end
40
+
41
+ describe "#set" do
42
+
43
+ before do
44
+ @type = mock
45
+ @field = Humanoid::Field.new(:score, :default => 10, :type => @type)
46
+ end
47
+
48
+ context "nil is provided" do
49
+
50
+ it "returns the default value" do
51
+ @field.set(nil).should == 10
52
+ end
53
+
54
+ end
55
+
56
+ context "value is provided" do
57
+
58
+ it "sets the value" do
59
+ @type.expects(:set).with("30").returns(30)
60
+ @field.set("30").should == 30
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ describe "#get" do
68
+
69
+ before do
70
+ @type = mock
71
+ @field = Humanoid::Field.new(:score, :default => 10, :type => @type)
72
+ end
73
+
74
+ it "returns the value" do
75
+ @type.expects(:get).with(30).returns(30)
76
+ @field.get(30).should == 30
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,158 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Fields do
4
+
5
+ describe ".defaults" do
6
+
7
+ it "returns a hash of all the default values" do
8
+ Game.defaults.should == { "high_score" => 500, "score" => 0 }
9
+ end
10
+
11
+ end
12
+
13
+ describe "#defaults" do
14
+
15
+ context "on parent classes" do
16
+
17
+ before do
18
+ @shape = Shape.new
19
+ end
20
+
21
+ it "does not return subclass defaults" do
22
+ @shape.defaults.should == { "x" => 0, "y" => 0 }
23
+ end
24
+
25
+ end
26
+
27
+ context "on subclasses" do
28
+
29
+ before do
30
+ @circle = Circle.new
31
+ end
32
+
33
+ it "has the parent and child defaults" do
34
+ @circle.defaults.should == { "x" => 0, "y" => 0, "radius" => 0 }
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ describe ".field" do
42
+
43
+ context "with no options" do
44
+
45
+ before do
46
+ Person.field(:testing)
47
+ end
48
+
49
+ it "adds a reader for the fields defined" do
50
+ @person = Person.new(:testing => "Test")
51
+ @person.testing.should == "Test"
52
+ end
53
+
54
+ it "adds a writer for the fields defined" do
55
+ @person = Person.new(:testing => "Test")
56
+ @person.testing = "Testy"
57
+ @person.testing.should == "Testy"
58
+ end
59
+
60
+ it "adds an reader method with a question mark" do
61
+ @person = Person.new(:testing => "Test")
62
+ @person.testing?.should be_true
63
+ Person.new.testing?.should be_false
64
+ end
65
+
66
+ end
67
+
68
+ context "when type is an object" do
69
+
70
+ before do
71
+ @person = Person.new
72
+ @drink = MixedDrink.new(:name => "Jack and Coke")
73
+ @person.mixed_drink = @drink
74
+ end
75
+
76
+ it "allows proper access to the object" do
77
+ @person.mixed_drink.should == @drink
78
+ @person.attributes[:mixed_drink].except(:_id).except(:_type).should ==
79
+ { "name" => "Jack and Coke" }
80
+ end
81
+
82
+ it "adds an reader method with a question mark" do
83
+ @person.mixed_drink?.should be_true
84
+ end
85
+
86
+ end
87
+
88
+ context "when type is a boolean" do
89
+
90
+ before do
91
+ @person = Person.new(:terms => true)
92
+ end
93
+
94
+ it "adds an accessor method with a question mark" do
95
+ @person.terms?.should be_true
96
+ end
97
+
98
+ end
99
+
100
+ context "when as is specified" do
101
+
102
+ before do
103
+ Person.field :aliased, :as => :alias, :type => Boolean
104
+ @person = Person.new(:alias => true)
105
+ end
106
+
107
+ it "uses the alias to write the attribute" do
108
+ @person.expects(:write_attribute).with("aliased", true)
109
+ @person.alias = true
110
+ end
111
+
112
+ it "uses the alias to read the attribute" do
113
+ @person.expects(:read_attribute).with("aliased")
114
+ @person.alias
115
+ end
116
+
117
+ it "uses the alias for the query method" do
118
+ @person.expects(:read_attribute).with("aliased")
119
+ @person.alias?
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ describe "#fields" do
127
+
128
+ context "on parent classes" do
129
+
130
+ before do
131
+ @shape = Shape.new
132
+ end
133
+
134
+ it "does not return subclass fields" do
135
+ @shape.fields.keys.should include("x")
136
+ @shape.fields.keys.should include("y")
137
+ @shape.fields.keys.should_not include("radius")
138
+ end
139
+
140
+ end
141
+
142
+ context "on subclasses" do
143
+
144
+ before do
145
+ @circle = Circle.new
146
+ end
147
+
148
+ it "has the parent and child fields" do
149
+ @circle.fields.keys.should include("x")
150
+ @circle.fields.keys.should include("y")
151
+ @circle.fields.keys.should include("radius")
152
+ end
153
+
154
+ end
155
+
156
+ end
157
+
158
+ end
@@ -0,0 +1,368 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Finders do
4
+
5
+ before do
6
+ @collection = stub(:name => "people")
7
+ @database = stub(:collection => @collection)
8
+ Humanoid.stubs(:database).returns(@database)
9
+ end
10
+
11
+ after do
12
+ Person.instance_variable_set(:@collection, nil)
13
+ @database = nil
14
+ @collection = nil
15
+ end
16
+
17
+ describe ".all" do
18
+
19
+ before do
20
+ @conditions = { :conditions => { :test => "Test" } }
21
+ end
22
+
23
+ context "when a selector is provided" do
24
+
25
+ it "finds from the collection and instantiate objects for each returned" do
26
+ Humanoid::Criteria.expects(:translate).with(Person, @conditions)
27
+ Person.all(@conditions)
28
+ end
29
+
30
+ end
31
+
32
+ context "when a selector is not provided" do
33
+
34
+ it "finds from the collection and instantiate objects for each returned" do
35
+ Humanoid::Criteria.expects(:translate).with(Person, nil)
36
+ Person.all
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ describe ".count" do
44
+
45
+ before do
46
+ @conditions = { :conditions => { :title => "Sir" } }
47
+ @criteria = mock
48
+ end
49
+
50
+ it "delegates to the criteria api" do
51
+ Humanoid::Criteria.expects(:translate).with(Person, @conditions).returns(@criteria)
52
+ @criteria.expects(:count).returns(10)
53
+ Person.count(@conditions).should == 10
54
+ end
55
+
56
+ context "when no options provided" do
57
+
58
+ it "adds in the default parameters" do
59
+ Humanoid::Criteria.expects(:translate).with(Person, nil).returns(@criteria)
60
+ @criteria.expects(:count).returns(10)
61
+ Person.count.should == 10
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe ".find" do
69
+
70
+ before do
71
+ @attributes = {}
72
+ @criteria = mock
73
+ end
74
+
75
+ context "when an id is passed in" do
76
+
77
+ before do
78
+ @id = Mongo::ObjectID.new.to_s
79
+ end
80
+
81
+ it "delegates to criteria" do
82
+ Humanoid::Criteria.expects(:translate).with(Person, @id.to_s).returns(Person.new)
83
+ Person.find(@id.to_s)
84
+ end
85
+
86
+ context "when no document is found" do
87
+
88
+ it "raises an error" do
89
+ @error = Humanoid::Errors::DocumentNotFound.new(Person, @id.to_s)
90
+ Humanoid::Criteria.expects(:translate).with(Person, @id.to_s).raises(@error)
91
+ lambda { Person.find(@id.to_s) }.should raise_error
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ context "when an array of ids is passed in" do
99
+
100
+ before do
101
+ @ids = []
102
+ 3.times { @ids << Mongo::ObjectID.new.to_s }
103
+ end
104
+
105
+ it "delegates to the criteria" do
106
+
107
+ end
108
+
109
+ end
110
+
111
+ context "when nil passed in" do
112
+
113
+ it "raises an error" do
114
+ lambda { Person.find(nil) }.should raise_error
115
+ end
116
+
117
+ end
118
+
119
+ context "when finding first" do
120
+
121
+ it "delegates to criteria" do
122
+ Humanoid::Criteria.expects(:translate).with(Person, :conditions => { :test => "Test" }).returns(@criteria)
123
+ @criteria.expects(:one).returns(@attributes)
124
+ Person.find(:first, :conditions => { :test => "Test" })
125
+ end
126
+
127
+ end
128
+
129
+ context "when finding all" do
130
+
131
+ before do
132
+ @conditions = { :conditions => { :test => "Test" } }
133
+ end
134
+
135
+ it "delegates to find_all" do
136
+ Humanoid::Criteria.expects(:translate).with(Person, @conditions).returns(@criteria)
137
+ Person.find(:all, @conditions)
138
+ end
139
+
140
+ end
141
+
142
+ context "when sorting" do
143
+
144
+ before do
145
+ @conditions = { :conditions => { :test => "Test" }, :sort => { :test => -1 } }
146
+ end
147
+
148
+ it "adds the sort parameters for the collection call" do
149
+ Humanoid::Criteria.expects(:translate).with(Person, @conditions).returns(@criteria)
150
+ Person.find(:all, @conditions)
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ describe ".find_or_create_by" do
157
+
158
+ before do
159
+ @person = Person.new(:age => 30)
160
+ @criteria = mock
161
+ end
162
+
163
+ context "when the document is found" do
164
+
165
+ it "returns the document" do
166
+ Humanoid::Criteria.expects(:translate).with(
167
+ Person, :conditions => { :age => 30 }
168
+ ).returns(@criteria)
169
+ @criteria.expects(:one).returns(@person)
170
+ Person.find_or_create_by(:age => 30).should == @person
171
+ end
172
+
173
+ end
174
+
175
+ context "when the document is not found" do
176
+
177
+ it "creates a new document" do
178
+ Humanoid::Criteria.expects(:translate).with(
179
+ Person, :conditions => { :age => 30 }
180
+ ).returns(@criteria)
181
+ @criteria.expects(:one).returns(nil)
182
+ Person.expects(:create).returns(@person)
183
+ person = Person.find_or_create_by(:age => 30)
184
+ person.should be_a_kind_of(Person)
185
+ person.age.should == 30
186
+ end
187
+
188
+ end
189
+
190
+ end
191
+
192
+ describe ".find_or_initialize_by" do
193
+
194
+ before do
195
+ @person = Person.new(:age => 30)
196
+ @criteria = mock
197
+ end
198
+
199
+ context "when the document is found" do
200
+
201
+ it "returns the document" do
202
+ Humanoid::Criteria.expects(:translate).with(
203
+ Person, :conditions => { :age => 30 }
204
+ ).returns(@criteria)
205
+ @criteria.expects(:one).returns(@person)
206
+ Person.find_or_initialize_by(:age => 30).should == @person
207
+ end
208
+
209
+ end
210
+
211
+ context "when the document is not found" do
212
+
213
+ it "returns a new document with the conditions" do
214
+ Humanoid::Criteria.expects(:translate).with(
215
+ Person, :conditions => { :age => 30 }
216
+ ).returns(@criteria)
217
+ @criteria.expects(:one).returns(nil)
218
+ person = Person.find_or_initialize_by(:age => 30)
219
+ person.should be_a_kind_of(Person)
220
+ person.should be_a_new_record
221
+ person.age.should == 30
222
+ end
223
+
224
+ end
225
+
226
+ end
227
+
228
+ describe ".first" do
229
+
230
+ before do
231
+ @criteria = mock
232
+ @conditions = { :conditions => { :test => "Test" } }
233
+ end
234
+
235
+ context "when a selector is provided" do
236
+
237
+ it "finds the first document from the collection and instantiates it" do
238
+ Humanoid::Criteria.expects(:translate).with(Person, @conditions).returns(@criteria)
239
+ @criteria.expects(:one)
240
+ Person.first(@conditions)
241
+ end
242
+
243
+ end
244
+
245
+ context "when a selector is not provided" do
246
+
247
+ it "finds the first document from the collection and instantiates it" do
248
+ Humanoid::Criteria.expects(:translate).with(Person, nil).returns(@criteria)
249
+ @criteria.expects(:one)
250
+ Person.first
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+
257
+ describe ".last" do
258
+
259
+ before do
260
+ @criteria = mock
261
+ end
262
+
263
+ it "finds the last document by the id" do
264
+ Humanoid::Criteria.expects(:translate).with(Person, nil).returns(@criteria)
265
+ @criteria.expects(:last)
266
+ Person.last
267
+ end
268
+
269
+ end
270
+
271
+ describe ".max" do
272
+
273
+ before do
274
+ @criteria = mock
275
+ end
276
+
277
+ it "returns the sum of a new criteria" do
278
+ Humanoid::Criteria.expects(:new).returns(@criteria)
279
+ @criteria.expects(:max).with(:age).returns(50.0)
280
+ Person.max(:age).should == 50.0
281
+ end
282
+
283
+ end
284
+
285
+ describe ".min" do
286
+
287
+ before do
288
+ @criteria = mock
289
+ end
290
+
291
+ it "returns the sum of a new criteria" do
292
+ Humanoid::Criteria.expects(:new).returns(@criteria)
293
+ @criteria.expects(:min).with(:age).returns(50.0)
294
+ Person.min(:age).should == 50.0
295
+ end
296
+
297
+ end
298
+
299
+ describe ".paginate" do
300
+
301
+ before do
302
+ @criteria = stub(:page => 1, :per_page => "20", :count => 100)
303
+ end
304
+
305
+ context "when pagination parameters are passed" do
306
+
307
+ before do
308
+ @params = { :conditions => { :test => "Test" }, :page => 2, :per_page => 20 }
309
+ end
310
+
311
+ it "delegates to will paginate with the results" do
312
+ Humanoid::Criteria.expects(:translate).with(Person, @params).returns(@criteria)
313
+ @criteria.expects(:paginate).returns([])
314
+ Person.paginate(@params)
315
+ end
316
+
317
+ end
318
+
319
+ context "when pagination parameters are not passed" do
320
+
321
+ before do
322
+ @params = { :conditions => { :test => "Test" }}
323
+ end
324
+
325
+ it "delegates to will paginate with default values" do
326
+ Humanoid::Criteria.expects(:translate).with(Person, @params).returns(@criteria)
327
+ @criteria.expects(:paginate).returns([])
328
+ Person.paginate(:conditions => { :test => "Test" })
329
+ end
330
+
331
+ end
332
+
333
+ end
334
+
335
+ describe ".only" do
336
+
337
+ it "returns a new criteria with select conditions added" do
338
+ criteria = Person.only(:title, :age)
339
+ criteria.options.should == { :fields => [ :title, :age ] }
340
+ end
341
+
342
+ end
343
+
344
+ describe ".sum" do
345
+
346
+ before do
347
+ @criteria = mock
348
+ end
349
+
350
+ it "returns the sum of a new criteria" do
351
+ Humanoid::Criteria.expects(:new).returns(@criteria)
352
+ @criteria.expects(:sum).with(:age).returns(50.0)
353
+ sum = Person.sum(:age)
354
+ sum.should == 50.0
355
+ end
356
+
357
+ end
358
+
359
+ describe ".where" do
360
+
361
+ it "returns a new criteria with select conditions added" do
362
+ criteria = Person.where(:title => "Sir")
363
+ criteria.selector.should == { :title => "Sir" }
364
+ end
365
+
366
+ end
367
+
368
+ end