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,55 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Callbacks do
4
+
5
+ describe ".included" do
6
+
7
+ before do
8
+ @class = Class.new do
9
+ include Humanoid::Callbacks
10
+ end
11
+ end
12
+
13
+ it "includes the before_create callback" do
14
+ @class.should respond_to(:before_create)
15
+ end
16
+
17
+ it "includes the after_create callback" do
18
+ @class.should respond_to(:after_create)
19
+ end
20
+
21
+ it "includes the before_destroy callback" do
22
+ @class.should respond_to(:before_destroy)
23
+ end
24
+
25
+ it "includes the after_destroy callback" do
26
+ @class.should respond_to(:after_destroy)
27
+ end
28
+
29
+ it "includes the before_save callback" do
30
+ @class.should respond_to(:before_save)
31
+ end
32
+
33
+ it "includes the after_save callback" do
34
+ @class.should respond_to(:after_save)
35
+ end
36
+
37
+ it "includes the before_update callback" do
38
+ @class.should respond_to(:before_update)
39
+ end
40
+
41
+ it "includes the after_update callback" do
42
+ @class.should respond_to(:after_update)
43
+ end
44
+
45
+ it "includes the before_validation callback" do
46
+ @class.should respond_to(:before_validation)
47
+ end
48
+
49
+ it "includes the after_validation callback" do
50
+ @class.should respond_to(:after_validation)
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,171 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Collection do
4
+
5
+ let(:master) do
6
+ stub.quacks_like(Humanoid::Collections::Master.allocate)
7
+ end
8
+
9
+ let(:slaves) do
10
+ stub.quacks_like(Humanoid::Collections::Slaves.allocate)
11
+ end
12
+
13
+ let(:collection) do
14
+ Humanoid::Collection.new(Person, "people")
15
+ end
16
+
17
+ before do
18
+ collection.instance_variable_set(:@master, master)
19
+ collection.instance_variable_set(:@slaves, slaves)
20
+ end
21
+
22
+ context "Mongo::Collection write operations" do
23
+
24
+ Humanoid::Collections::Operations::WRITE.each do |name|
25
+
26
+ it "defines #{name}" do
27
+ collection.should respond_to(name)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ context "Mongo::Collection read operations" do
34
+
35
+ Humanoid::Collections::Operations::READ.each do |name|
36
+
37
+ it "defines #{name}" do
38
+ collection.should respond_to(name)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#directed" do
44
+
45
+ before do
46
+ slaves.expects(:empty?).returns(false)
47
+ end
48
+
49
+ context "when an enslave option is not passed" do
50
+
51
+ before do
52
+ Person.enslave
53
+ end
54
+
55
+ after do
56
+ Person.enslaved = false
57
+ end
58
+
59
+ it "uses the default" do
60
+ collection.directed.should == slaves
61
+ end
62
+ end
63
+
64
+ context "when an enslave option is passed" do
65
+
66
+ it "overwrites the default" do
67
+ collection.directed(:enslave => true).should == slaves
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ describe "#find" do
74
+
75
+ before do
76
+ @cursor = stub.quacks_like(Humanoid::Cursor.allocate)
77
+ Humanoid::Cursor.expects(:new).with(Person, collection, @mongo_cursor).returns(@cursor)
78
+ end
79
+
80
+ context "when no block supplied" do
81
+
82
+ before do
83
+ master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
84
+ end
85
+
86
+ it "finds return a cursor" do
87
+ collection.find({ :test => "value"}).should == @cursor
88
+ end
89
+
90
+ end
91
+
92
+ context "when a block is supplied" do
93
+
94
+ before do
95
+ master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
96
+ end
97
+
98
+ it "yields to the cursor and closes it" do
99
+ @cursor.expects(:close).returns(true)
100
+ collection.find({ :test => "value" }) do |cur|
101
+ cur.should == @cursor
102
+ end
103
+ end
104
+ end
105
+
106
+ context "when an enslave option exists" do
107
+
108
+ before do
109
+ @options = { :enslave => true }
110
+ slaves.expects(:empty?).returns(false)
111
+ slaves.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
112
+ end
113
+
114
+ it "sends the query to the slave pool" do
115
+ collection.find({ :test => "value"}, @options).should == @cursor
116
+ end
117
+
118
+ it "deletes the enslave option" do
119
+ collection.find({ :test => "value"}, @options)
120
+ @options[:enslave].should be_nil
121
+ end
122
+ end
123
+
124
+ context "when an enslave option does not exist" do
125
+
126
+ before do
127
+ master.expects(:find).with({ :test => "value" }, {}).returns(@mongo_cursor)
128
+ end
129
+
130
+ it "sends the query to the master" do
131
+ collection.find({ :test => "value"}).should == @cursor
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "#find_one" do
137
+
138
+ before do
139
+ @person = stub
140
+ end
141
+
142
+ context "when an enslave option exists" do
143
+
144
+ before do
145
+ @options = { :enslave => true }
146
+ slaves.expects(:empty?).returns(false)
147
+ slaves.expects(:find_one).with({ :test => "value" }, {}).returns(@person)
148
+ end
149
+
150
+ it "sends the query to the slave pool" do
151
+ collection.find_one({ :test => "value"}, @options).should == @person
152
+ end
153
+
154
+ it "deletes the enslave option" do
155
+ collection.find_one({ :test => "value"}, @options)
156
+ @options[:enslave].should be_nil
157
+ end
158
+ end
159
+
160
+ context "when an enslave option does not exist" do
161
+
162
+ before do
163
+ master.expects(:find_one).with({ :test => "value" }, {}).returns(@person)
164
+ end
165
+
166
+ it "sends the query to the master" do
167
+ collection.find_one({ :test => "value"}).should == @person
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Collections::CyclicIterator do
4
+
5
+ before do
6
+ @first = stub
7
+ @second = stub
8
+ @third = stub
9
+ @fourth = stub
10
+ end
11
+
12
+ let(:array) do
13
+ [ @first, @second, @third, @fourth ]
14
+ end
15
+
16
+ describe "#initialize" do
17
+
18
+ let(:iterator) do
19
+ Humanoid::Collections::CyclicIterator.new(array)
20
+ end
21
+
22
+ it "defaults the counter to -1" do
23
+ iterator.counter.should == -1
24
+ end
25
+ end
26
+
27
+ describe "#next" do
28
+
29
+ context "when the iterator has just been created" do
30
+
31
+ let(:iterator) do
32
+ Humanoid::Collections::CyclicIterator.new(array)
33
+ end
34
+
35
+ it "returns the first element" do
36
+ iterator.next.should == @first
37
+ end
38
+ end
39
+
40
+ context "when the iterator is in the middle" do
41
+
42
+ let(:iterator) do
43
+ Humanoid::Collections::CyclicIterator.new(array)
44
+ end
45
+
46
+ before do
47
+ 2.times { iterator.next }
48
+ end
49
+
50
+ it "returns the next element given the index" do
51
+ iterator.next.should == @third
52
+ end
53
+ end
54
+
55
+ context "when the iterator is on the last element" do
56
+
57
+ let(:iterator) do
58
+ Humanoid::Collections::CyclicIterator.new(array)
59
+ end
60
+
61
+ before do
62
+ 4.times { iterator.next }
63
+ end
64
+
65
+ it "returns the first element" do
66
+ iterator.next.should == @first
67
+ end
68
+
69
+ it "resets the counter" do
70
+ iterator.next
71
+ iterator.counter.should == 0
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Collections::Master do
4
+
5
+ let(:collection) do
6
+ stub.quacks_like(Mongo::Collection.allocate)
7
+ end
8
+
9
+ let(:db) do
10
+ stub.quacks_like(Mongo::DB.allocate)
11
+ end
12
+
13
+ let(:master) do
14
+ Humanoid::Collections::Master.new(db, "people")
15
+ end
16
+
17
+ before do
18
+ db.expects(:collection).with("people").returns(collection)
19
+ end
20
+
21
+ context "Mongo::Collection operations" do
22
+
23
+ Humanoid::Collections::Operations::ALL.each do |name|
24
+
25
+ it "defines #{name}" do
26
+ master.should respond_to(name)
27
+ end
28
+
29
+ describe "##{name}" do
30
+
31
+ before do
32
+ collection.expects(name)
33
+ end
34
+
35
+ it "delegates to the collection" do
36
+ master.send(name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Collections::Mimic do
4
+
5
+ let(:mimic) do
6
+ klass = Class.new do
7
+ include Humanoid::Collections::Mimic
8
+ end
9
+ klass.new
10
+ end
11
+
12
+ describe "#attempt" do
13
+
14
+ before do
15
+ @operation = stub.quacks_like(Proc.new {})
16
+ end
17
+
18
+ context "when the call succeeds" do
19
+
20
+ it "returns the value" do
21
+ @operation.expects(:call).returns([])
22
+ mimic.attempt(@operation, Time.now).should == []
23
+ end
24
+ end
25
+
26
+ context "when the call fails" do
27
+
28
+ before do
29
+ Humanoid.reconnect_time = 0.10
30
+ end
31
+
32
+ after do
33
+ Humanoid.reconnect_time = 3
34
+ end
35
+
36
+ it "retries the call" do
37
+ @operation.expects(:call).at_least_once.raises(Mongo::ConnectionFailure.new)
38
+ lambda { mimic.attempt(@operation, Time.now) }.should raise_error
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+
3
+ describe Humanoid::Collections::Master do
4
+
5
+ let(:collection) do
6
+ stub.quacks_like(Mongo::Collection.allocate)
7
+ end
8
+
9
+ let(:db) do
10
+ stub.quacks_like(Mongo::DB.allocate)
11
+ end
12
+
13
+ describe "#empty?" do
14
+
15
+ context "when the slaves exist" do
16
+
17
+ let(:slave) do
18
+ Humanoid::Collections::Slaves.new([ db ], "people")
19
+ end
20
+
21
+ before do
22
+ db.expects(:collection).with("people").returns(collection)
23
+ end
24
+
25
+ it "returns false" do
26
+ slave.should_not be_empty
27
+ end
28
+ end
29
+
30
+ context "when the slaves do not exist" do
31
+
32
+ let(:slave) do
33
+ Humanoid::Collections::Slaves.new([], "people")
34
+ end
35
+
36
+ it "returns true" do
37
+ slave.should be_empty
38
+ end
39
+ end
40
+
41
+ context "when the slaves are nil" do
42
+
43
+ let(:slave) do
44
+ Humanoid::Collections::Slaves.new(nil, "people")
45
+ end
46
+
47
+ it "returns true" do
48
+ slave.should be_empty
49
+ end
50
+ end
51
+ end
52
+
53
+ context "Mongo::Collection operations" do
54
+
55
+ let(:slave) do
56
+ Humanoid::Collections::Slaves.new([ db ], "people")
57
+ end
58
+
59
+ before do
60
+ db.expects(:collection).with("people").returns(collection)
61
+ end
62
+
63
+ Humanoid::Collections::Operations::READ.each do |name|
64
+
65
+ it "defines #{name}" do
66
+ slave.should respond_to(name)
67
+ end
68
+
69
+ describe "##{name}" do
70
+
71
+ before do
72
+ collection.expects(name)
73
+ end
74
+
75
+ it "delegates to the collection" do
76
+ slave.send(name)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end