mark_mapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +39 -0
  4. data/examples/attr_accessible.rb +24 -0
  5. data/examples/attr_protected.rb +24 -0
  6. data/examples/cache_key.rb +26 -0
  7. data/examples/custom_types.rb +26 -0
  8. data/examples/identity_map.rb +30 -0
  9. data/examples/identity_map/automatic.rb +2 -0
  10. data/examples/keys.rb +42 -0
  11. data/examples/modifiers/set.rb +27 -0
  12. data/examples/plugins.rb +40 -0
  13. data/examples/querying.rb +39 -0
  14. data/examples/sample_app.rb +43 -0
  15. data/examples/scopes.rb +56 -0
  16. data/examples/validating/embedded_docs.rb +31 -0
  17. data/lib/mark_mapper.rb +125 -0
  18. data/lib/mark_mapper/config.rb +90 -0
  19. data/lib/mark_mapper/connection.rb +60 -0
  20. data/lib/mark_mapper/criteria_hash.rb +194 -0
  21. data/lib/mark_mapper/document.rb +46 -0
  22. data/lib/mark_mapper/embedded_document.rb +32 -0
  23. data/lib/mark_mapper/exceptions.rb +33 -0
  24. data/lib/mark_mapper/extensions/array.rb +27 -0
  25. data/lib/mark_mapper/extensions/boolean.rb +45 -0
  26. data/lib/mark_mapper/extensions/date.rb +29 -0
  27. data/lib/mark_mapper/extensions/duplicable.rb +86 -0
  28. data/lib/mark_mapper/extensions/float.rb +18 -0
  29. data/lib/mark_mapper/extensions/hash.rb +26 -0
  30. data/lib/mark_mapper/extensions/integer.rb +27 -0
  31. data/lib/mark_mapper/extensions/kernel.rb +11 -0
  32. data/lib/mark_mapper/extensions/nil_class.rb +18 -0
  33. data/lib/mark_mapper/extensions/object.rb +30 -0
  34. data/lib/mark_mapper/extensions/object_id.rb +18 -0
  35. data/lib/mark_mapper/extensions/set.rb +20 -0
  36. data/lib/mark_mapper/extensions/string.rb +31 -0
  37. data/lib/mark_mapper/extensions/symbol.rb +87 -0
  38. data/lib/mark_mapper/extensions/time.rb +29 -0
  39. data/lib/mark_mapper/locale/en.yml +5 -0
  40. data/lib/mark_mapper/middleware/identity_map.rb +41 -0
  41. data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
  42. data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
  43. data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
  44. data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
  45. data/lib/mark_mapper/normalizers/integer.rb +19 -0
  46. data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
  47. data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
  48. data/lib/mark_mapper/options_hash.rb +103 -0
  49. data/lib/mark_mapper/pagination.rb +6 -0
  50. data/lib/mark_mapper/pagination/collection.rb +32 -0
  51. data/lib/mark_mapper/pagination/paginator.rb +46 -0
  52. data/lib/mark_mapper/plugins.rb +22 -0
  53. data/lib/mark_mapper/plugins/accessible.rb +61 -0
  54. data/lib/mark_mapper/plugins/active_model.rb +18 -0
  55. data/lib/mark_mapper/plugins/associations.rb +96 -0
  56. data/lib/mark_mapper/plugins/associations/base.rb +98 -0
  57. data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
  58. data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
  59. data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  60. data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
  61. data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
  62. data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
  63. data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
  64. data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  65. data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
  66. data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  67. data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  68. data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  69. data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
  70. data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
  71. data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  72. data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  73. data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
  74. data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
  75. data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
  76. data/lib/mark_mapper/plugins/caching.rb +21 -0
  77. data/lib/mark_mapper/plugins/callbacks.rb +42 -0
  78. data/lib/mark_mapper/plugins/clone.rb +24 -0
  79. data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
  80. data/lib/mark_mapper/plugins/dirty.rb +61 -0
  81. data/lib/mark_mapper/plugins/document.rb +41 -0
  82. data/lib/mark_mapper/plugins/dumpable.rb +22 -0
  83. data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
  84. data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  85. data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
  86. data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
  87. data/lib/mark_mapper/plugins/equality.rb +23 -0
  88. data/lib/mark_mapper/plugins/identity_map.rb +144 -0
  89. data/lib/mark_mapper/plugins/indexable.rb +86 -0
  90. data/lib/mark_mapper/plugins/inspect.rb +16 -0
  91. data/lib/mark_mapper/plugins/keys.rb +470 -0
  92. data/lib/mark_mapper/plugins/keys/key.rb +134 -0
  93. data/lib/mark_mapper/plugins/keys/static.rb +45 -0
  94. data/lib/mark_mapper/plugins/logger.rb +18 -0
  95. data/lib/mark_mapper/plugins/modifiers.rb +140 -0
  96. data/lib/mark_mapper/plugins/pagination.rb +16 -0
  97. data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
  98. data/lib/mark_mapper/plugins/persistence.rb +79 -0
  99. data/lib/mark_mapper/plugins/protected.rb +45 -0
  100. data/lib/mark_mapper/plugins/querying.rb +173 -0
  101. data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
  102. data/lib/mark_mapper/plugins/rails.rb +79 -0
  103. data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  104. data/lib/mark_mapper/plugins/sci.rb +82 -0
  105. data/lib/mark_mapper/plugins/scopes.rb +28 -0
  106. data/lib/mark_mapper/plugins/serialization.rb +109 -0
  107. data/lib/mark_mapper/plugins/timestamps.rb +29 -0
  108. data/lib/mark_mapper/plugins/touch.rb +18 -0
  109. data/lib/mark_mapper/plugins/userstamps.rb +18 -0
  110. data/lib/mark_mapper/plugins/validations.rb +96 -0
  111. data/lib/mark_mapper/query.rb +278 -0
  112. data/lib/mark_mapper/railtie.rb +52 -0
  113. data/lib/mark_mapper/railtie/database.rake +65 -0
  114. data/lib/mark_mapper/translation.rb +10 -0
  115. data/lib/mark_mapper/version.rb +4 -0
  116. data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
  117. data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
  118. data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
  119. data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
  120. data/spec/config/mark_mapper.yml +6 -0
  121. data/spec/examples_spec.rb +25 -0
  122. data/spec/functional/accessible_spec.rb +198 -0
  123. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
  124. data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
  125. data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
  126. data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
  127. data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
  128. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
  129. data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
  130. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
  131. data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
  132. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
  133. data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
  134. data/spec/functional/associations/one_proxy_spec.rb +406 -0
  135. data/spec/functional/associations_spec.rb +48 -0
  136. data/spec/functional/caching_spec.rb +75 -0
  137. data/spec/functional/callbacks_spec.rb +330 -0
  138. data/spec/functional/counter_cache_spec.rb +235 -0
  139. data/spec/functional/dirty_spec.rb +316 -0
  140. data/spec/functional/document_spec.rb +310 -0
  141. data/spec/functional/dumpable_spec.rb +24 -0
  142. data/spec/functional/dynamic_querying_spec.rb +75 -0
  143. data/spec/functional/embedded_document_spec.rb +316 -0
  144. data/spec/functional/equality_spec.rb +20 -0
  145. data/spec/functional/extensions_spec.rb +16 -0
  146. data/spec/functional/identity_map_spec.rb +483 -0
  147. data/spec/functional/keys_spec.rb +339 -0
  148. data/spec/functional/logger_spec.rb +20 -0
  149. data/spec/functional/modifiers_spec.rb +446 -0
  150. data/spec/functional/options_hash_spec.rb +41 -0
  151. data/spec/functional/pagination_spec.rb +89 -0
  152. data/spec/functional/partial_updates_spec.rb +530 -0
  153. data/spec/functional/protected_spec.rb +199 -0
  154. data/spec/functional/querying_spec.rb +984 -0
  155. data/spec/functional/rails_spec.rb +55 -0
  156. data/spec/functional/sci_spec.rb +374 -0
  157. data/spec/functional/scopes_spec.rb +204 -0
  158. data/spec/functional/static_keys_spec.rb +153 -0
  159. data/spec/functional/timestamps_spec.rb +97 -0
  160. data/spec/functional/touch_spec.rb +125 -0
  161. data/spec/functional/userstamps_spec.rb +46 -0
  162. data/spec/functional/validations_spec.rb +416 -0
  163. data/spec/quality_spec.rb +51 -0
  164. data/spec/spec_helper.rb +150 -0
  165. data/spec/support/matchers.rb +15 -0
  166. data/spec/support/models.rb +256 -0
  167. data/spec/symbol_operator_spec.rb +70 -0
  168. data/spec/symbol_spec.rb +9 -0
  169. data/spec/unit/associations/base_spec.rb +146 -0
  170. data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
  171. data/spec/unit/associations/many_association_spec.rb +64 -0
  172. data/spec/unit/associations/one_association_spec.rb +48 -0
  173. data/spec/unit/associations/proxy_spec.rb +103 -0
  174. data/spec/unit/clone_spec.rb +79 -0
  175. data/spec/unit/config_generator_spec.rb +24 -0
  176. data/spec/unit/criteria_hash_spec.rb +218 -0
  177. data/spec/unit/document_spec.rb +251 -0
  178. data/spec/unit/dynamic_finder_spec.rb +125 -0
  179. data/spec/unit/embedded_document_spec.rb +676 -0
  180. data/spec/unit/equality_spec.rb +38 -0
  181. data/spec/unit/exceptions_spec.rb +12 -0
  182. data/spec/unit/extensions_spec.rb +368 -0
  183. data/spec/unit/identity_map_middleware_spec.rb +134 -0
  184. data/spec/unit/inspect_spec.rb +47 -0
  185. data/spec/unit/key_spec.rb +276 -0
  186. data/spec/unit/keys_spec.rb +155 -0
  187. data/spec/unit/mark_mapper_spec.rb +37 -0
  188. data/spec/unit/model_generator_spec.rb +45 -0
  189. data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
  190. data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
  191. data/spec/unit/normalizers/fields_value_spec.rb +45 -0
  192. data/spec/unit/normalizers/hash_key_spec.rb +15 -0
  193. data/spec/unit/normalizers/integer_spec.rb +24 -0
  194. data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
  195. data/spec/unit/normalizers/sort_value_spec.rb +98 -0
  196. data/spec/unit/options_hash_spec.rb +64 -0
  197. data/spec/unit/pagination/collection_spec.rb +30 -0
  198. data/spec/unit/pagination/paginator_spec.rb +118 -0
  199. data/spec/unit/pagination_spec.rb +11 -0
  200. data/spec/unit/plugins_spec.rb +89 -0
  201. data/spec/unit/query_spec.rb +837 -0
  202. data/spec/unit/rails_compatibility_spec.rb +40 -0
  203. data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
  204. data/spec/unit/rails_spec.rb +188 -0
  205. data/spec/unit/serialization_spec.rb +169 -0
  206. data/spec/unit/serializers/json_serializer_spec.rb +218 -0
  207. data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
  208. data/spec/unit/time_zones_spec.rb +44 -0
  209. data/spec/unit/translation_spec.rb +27 -0
  210. data/spec/unit/validations_spec.rb +588 -0
  211. metadata +307 -0
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Equality" do
4
+ context "Case equality" do
5
+ before do
6
+ @person = Doc()
7
+ @address = Doc()
8
+
9
+ @person.one :address, :class => @address, :foreign_key => :person_id
10
+ @address.belongs_to :person, :class => @person
11
+ end
12
+
13
+ it "should work with proxies" do
14
+ person = @person.create!
15
+ address = @address.create!(:person => person)
16
+ @person.should === address.person
17
+ @address.should === person.address
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Core Extensions" do
4
+ describe "Time" do
5
+ let(:doc) do
6
+ Doc do
7
+ key :created_at, Time
8
+ end
9
+ end
10
+
11
+ it "should match the precision of Time types stored in the database" do
12
+ d = doc.create(:created_at => Time.now)
13
+ d.created_at.to_s.should == d.reload.created_at.to_s
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,483 @@
1
+ require 'spec_helper'
2
+
3
+ describe "IdentityMap" do
4
+ def assert_in_map(*resources)
5
+ [resources].flatten.each do |resource|
6
+ MarkMapper::Plugins::IdentityMap.include?(resource).should be_truthy
7
+ end
8
+ end
9
+
10
+ def assert_not_in_map(*resources)
11
+ [resources].flatten.each do |resource|
12
+ MarkMapper::Plugins::IdentityMap.include?(resource).should be_falsey
13
+ end
14
+ end
15
+
16
+ def expect_no_queries
17
+ expect_any_instance_of(MarkLogic::Collection).to receive(:find_one).never
18
+ expect_any_instance_of(MarkLogic::Collection).to receive(:find).never
19
+ end
20
+
21
+ def expects_one_query
22
+ expect_any_instance_of(MarkLogic::Collection).to receive(:find_one).once.and_return({})
23
+ end
24
+
25
+ def clear_identity_map
26
+ MarkMapper::Plugins::IdentityMap.clear
27
+ end
28
+
29
+ it "should default identity map to off" do
30
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_falsey
31
+ end
32
+
33
+ context "Document" do
34
+ before do
35
+ @original_identity_map_enabled = MarkMapper::Plugins::IdentityMap.enabled
36
+ MarkMapper::Plugins::IdentityMap.enabled = true
37
+
38
+ @person_class = Doc('Person') do
39
+ key :name, String
40
+ end
41
+
42
+ @post_class = Doc('Post') do
43
+ key :title, String
44
+ key :person_id, ObjectId
45
+ end
46
+
47
+ @post_class.belongs_to :person, :class => @person_class
48
+ @person_class.many :posts, :class => @post_class
49
+
50
+ clear_identity_map
51
+ end
52
+
53
+ after do
54
+ MarkMapper::Plugins::IdentityMap.enabled = @original_identity_map_enabled
55
+ end
56
+
57
+ it "should be able to clear the map of all models" do
58
+ person = @person_class.create(:name => 'John')
59
+ post = @post_class.create(:title => 'IM 4eva')
60
+
61
+ assert_in_map(person, post)
62
+ clear_identity_map
63
+ assert_not_in_map(person, post)
64
+
65
+ MarkMapper::Plugins::IdentityMap.repository.should be_empty
66
+ end
67
+
68
+ context ".use" do
69
+ before do
70
+ @person = @person_class.create
71
+ clear_identity_map
72
+ end
73
+
74
+ it "should use the identity map" do
75
+ MarkMapper::Plugins::IdentityMap.enabled = false
76
+ MarkMapper::Plugins::IdentityMap.use do
77
+ @person_class.find(@person.id).should equal(@person_class.find(@person.id))
78
+ end
79
+ end
80
+
81
+ it "should clear the map" do
82
+ MarkMapper::Plugins::IdentityMap.enabled = false
83
+ MarkMapper::Plugins::IdentityMap.repository['hello'] = 'world'
84
+ MarkMapper::Plugins::IdentityMap.use do
85
+ @person_class.find(@person.id)
86
+ end
87
+ MarkMapper::Plugins::IdentityMap.repository.empty?.should be_truthy
88
+ end
89
+
90
+ it "should set enabled back to original status" do
91
+ MarkMapper::Plugins::IdentityMap.enabled = false
92
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_falsey
93
+ MarkMapper::Plugins::IdentityMap.use do
94
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_truthy
95
+ end
96
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_falsey
97
+ end
98
+ end
99
+
100
+ context ".without" do
101
+ before do
102
+ @person = @person_class.create
103
+ clear_identity_map
104
+ end
105
+
106
+ it "should skip the map" do
107
+ MarkMapper::Plugins::IdentityMap.without do
108
+ @person_class.find(@person.id).should_not equal(@person_class.find(@person.id))
109
+ end
110
+ end
111
+
112
+ it "should set enabled back to original value" do
113
+ MarkMapper::Plugins::IdentityMap.enabled = true
114
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_truthy
115
+ MarkMapper::Plugins::IdentityMap.without do
116
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_falsey
117
+ end
118
+ MarkMapper::Plugins::IdentityMap.enabled?.should be_truthy
119
+ end
120
+ end
121
+
122
+ it "should default identity map to hash" do
123
+ MarkMapper::Plugins::IdentityMap.repository.should == {}
124
+ end
125
+
126
+ it "should add key to map when saved" do
127
+ person = @person_class.new
128
+ assert_not_in_map(person)
129
+ person.save.should be_truthy
130
+ assert_in_map(person)
131
+ end
132
+
133
+ it "should allow saving with options" do
134
+ person = @person_class.new
135
+ assert_not_in_map(person)
136
+ person.save(:validate => false).should be_truthy
137
+ assert_in_map(person)
138
+ end
139
+
140
+ it "should remove key from map when deleted" do
141
+ person = @person_class.create(:name => 'Fred')
142
+ assert_in_map(person)
143
+ person.delete
144
+ assert_not_in_map(person)
145
+ end
146
+
147
+ it "should remove key from map when destroyed" do
148
+ person = @person_class.create(:name => 'Fred')
149
+ assert_in_map(person)
150
+ person.destroy
151
+ assert_not_in_map(person)
152
+ end
153
+
154
+ context "#reload" do
155
+ before do
156
+ @person = @person_class.create(:name => 'Fred')
157
+ end
158
+
159
+ it "should re-query the object" do
160
+ assert_in_map(@person)
161
+ expects_one_query
162
+ @person.reload
163
+ end
164
+ end
165
+
166
+ context "#load" do
167
+ before do
168
+ @id = MarkLogic::ObjectId.new
169
+ end
170
+
171
+ it "should add document to map" do
172
+ loaded = @person_class.load('_id' => @id, 'name' => 'Frank')
173
+ assert_in_map(loaded)
174
+ end
175
+
176
+ it "should return document if already in map" do
177
+ first_load = @person_class.load('_id' => @id, 'name' => 'Frank')
178
+ second_load = @person_class.load('_id' => @id, 'name' => 'Frank')
179
+ first_load.should equal(second_load)
180
+ end
181
+
182
+ it "should allow passing with_cast" do
183
+ person_with_time_class = Doc('PersonWithTime') do
184
+ key :name, String
185
+ key :created_at, Time
186
+ end
187
+
188
+ expect do
189
+ loaded = person_with_time_class.load({'_id' => @id, 'name' => 'Frank', 'created_at' => '2014-12-07T20:36:45.529-08:00'}, true)
190
+ loaded.should be_present
191
+ loaded.created_at.should be_an_instance_of(Time)
192
+ end.to_not raise_error
193
+ end
194
+ end
195
+
196
+ context "#find (with one id)" do
197
+ it "should return nil if not found " do
198
+ @person_class.find(1234).should be_nil
199
+ end
200
+
201
+ context "for object not in map" do
202
+ before do
203
+ @person = @person_class.create(:name => 'Fred')
204
+ clear_identity_map
205
+ end
206
+
207
+ it "should query the database" do
208
+ expects_one_query
209
+ @person_class.find(@person.id)
210
+ end
211
+
212
+ it "should add object to map" do
213
+ assert_not_in_map(@person)
214
+ found_person = @person_class.find(@person.id)
215
+ assert_in_map(found_person)
216
+ end
217
+ end
218
+
219
+ context "for object in map" do
220
+ before do
221
+ @person = @person_class.create(:name => 'Fred')
222
+ end
223
+
224
+ it "should not query database" do
225
+ expect_no_queries
226
+ @person_class.find(@person.id)
227
+ end
228
+
229
+ it "should return exact object" do
230
+ assert_in_map(@person)
231
+ found_person = @person_class.find(@person.id)
232
+ found_person.should equal(@person)
233
+ end
234
+ end
235
+ end
236
+
237
+ context "#find (with one id and options)" do
238
+ before do
239
+ @person = @person_class.create(:name => 'Fred')
240
+ @post1 = @person.posts.create(:title => 'I Love MarkLogic')
241
+ @post2 = @person.posts.create(:title => 'Migrations Suck!')
242
+ end
243
+
244
+ # There are times when even though the id matches, other criteria doesn't
245
+ # so we need to do the query to ensure that when criteria doesn't match
246
+ # the document is in fact not found.
247
+ #
248
+ # I'm open to not making this query if someone can figure out reliable
249
+ # way to check if document matches criteria without querying.
250
+ it "should query the database" do
251
+ assert_in_map(@post1)
252
+ expects_one_query
253
+ @person.posts.find(@post1.id)
254
+ end
255
+
256
+ it "should return exact object" do
257
+ assert_in_map(@post1)
258
+ post = @person.posts.find(@post1.id)
259
+ post.should equal(@post1)
260
+ end
261
+
262
+ it "should return nil if not found " do
263
+ @person.posts.find(1234).should be_nil
264
+ end
265
+ end
266
+
267
+ context "#find (with multiple ids)" do
268
+ it "should add all documents to map" do
269
+ person1 = @person_class.create(:name => 'Fred')
270
+ person2 = @person_class.create(:name => 'Bill')
271
+ person3 = @person_class.create(:name => 'Jesse')
272
+ clear_identity_map
273
+
274
+ people = @person_class.find(person1.id, person2.id, person3.id)
275
+ assert_in_map(people)
276
+ end
277
+
278
+ it "should add missing documents to map and return existing ones" do
279
+ person1 = @person_class.create(:name => 'Fred')
280
+ clear_identity_map
281
+ person2 = @person_class.create(:name => 'Bill')
282
+ person3 = @person_class.create(:name => 'Jesse')
283
+
284
+ assert_not_in_map(person1)
285
+ assert_in_map(person2, person3)
286
+
287
+ people = @person_class.find(person1.id, person2.id, person3.id)
288
+
289
+ assert_in_map(people.first) # making sure one that wasn't mapped now is
290
+ assert_in_map(person2, person3)
291
+ end
292
+ end
293
+
294
+ context "#first" do
295
+ context "for object not in map" do
296
+ before do
297
+ @person = @person_class.create(:name => 'Fred')
298
+ clear_identity_map
299
+ end
300
+
301
+ it "should query the database" do
302
+ expects_one_query
303
+ @person_class.first(:_id => @person.id)
304
+ end
305
+
306
+ it "should add object to map" do
307
+ assert_not_in_map(@person)
308
+ found_person = @person_class.first(:_id => @person.id)
309
+ assert_in_map(found_person)
310
+ end
311
+
312
+ it "should return nil if not found" do
313
+ @person_class.first(:name => 'Bill').should be_nil
314
+ end
315
+ end
316
+
317
+ context "for object in map" do
318
+ before do
319
+ @person = @person_class.create(:name => 'Fred')
320
+ end
321
+
322
+ it "should not query database" do
323
+ expect_no_queries
324
+ @person_class.first(:_id => @person.id)
325
+ end
326
+
327
+ it "should return exact object" do
328
+ assert_in_map(@person)
329
+ found_person = @person_class.first(:_id => @person.id)
330
+ found_person.should equal(@person)
331
+ end
332
+ end
333
+ end
334
+
335
+ context "#all" do
336
+ it "should add all documents to map" do
337
+ person1 = @person_class.create(:name => 'Fred')
338
+ person2 = @person_class.create(:name => 'Bill')
339
+ person3 = @person_class.create(:name => 'Jesse')
340
+ clear_identity_map
341
+
342
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
343
+ assert_in_map(people)
344
+ end
345
+
346
+ it "should add missing documents to map and return existing ones" do
347
+ person1 = @person_class.create(:name => 'Fred')
348
+ clear_identity_map
349
+ person2 = @person_class.create(:name => 'Bill')
350
+ person3 = @person_class.create(:name => 'Jesse')
351
+
352
+ assert_not_in_map(person1)
353
+ assert_in_map(person2, person3)
354
+
355
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
356
+ # people.first is making sure one that wasn't mapped now is
357
+ assert_in_map(people.first, person2, person3)
358
+ end
359
+ end
360
+
361
+ context "#find_by_id" do
362
+ before do
363
+ @person = @person_class.create(:name => 'Bill')
364
+ end
365
+
366
+ it "should return nil for document id not found in collection" do
367
+ assert_in_map(@person)
368
+ @person_class.find_by_id(MarkLogic::ObjectId.new).should be_nil
369
+ end
370
+ end
371
+
372
+ context "#remove_documents_from_map" do
373
+ before do
374
+ @person = @person_class.create(:name => 'Fred')
375
+ end
376
+
377
+ it "should remove documents from the map" do
378
+ assert_in_map @person
379
+ @person_class.remove_documents_from_map(@person)
380
+ assert_not_in_map @person
381
+ end
382
+ end
383
+
384
+ context "querying and selecting certain fields" do
385
+ before do
386
+ @person = @person_class.create(:name => 'Bill')
387
+ clear_identity_map
388
+ end
389
+
390
+ it "should not add to map" do
391
+ assert_not_in_map(@person)
392
+ @person_class.first(:_id => @person.id, :select => 'name').should == @person
393
+ @person_class.first(:_id => @person.id, 'fields' => ['name']).should == @person
394
+ @person_class.last(:_id => @person.id, :select => 'name', :order => 'name').should == @person
395
+ @person_class.fields(:name).find(@person.id).should == @person
396
+ @person_class.all(:_id => @person.id, :select => 'name').should == [@person]
397
+ assert_not_in_map(@person)
398
+ end
399
+
400
+ it "should not add to map using where and each" do
401
+ @person_class.where(:id => @person.id).each{|_|}
402
+ assert_in_map(@person)
403
+ @person_class.where(:id => @person.id).only(:id).each{|_|}
404
+ assert_not_in_map(@person)
405
+ end
406
+
407
+ it "should return nil if not found" do
408
+ @person_class.fields(:name).find(MarkLogic::ObjectId.new).should be_nil
409
+ end
410
+ end
411
+
412
+ context "single collection inherited models" do
413
+ before do
414
+ class ::Item
415
+ include MarkMapper::Document
416
+
417
+ key :title, String
418
+ key :parent_id, ObjectId
419
+
420
+ belongs_to :parent, :class_name => 'Item'
421
+ one :blog, :class_name => 'Blog', :foreign_key => 'parent_id'
422
+ end
423
+ Item.collection.remove
424
+
425
+ class ::Blog < ::Item; end
426
+
427
+ class ::BlogPost < ::Item
428
+ key :blog_id, ObjectId
429
+ belongs_to :blog
430
+ end
431
+ end
432
+
433
+ after do
434
+ Object.send :remove_const, 'Item' if defined?(::Item)
435
+ Object.send :remove_const, 'Blog' if defined?(::Blog)
436
+ Object.send :remove_const, 'BlogPost' if defined?(::BlogPost)
437
+ end
438
+
439
+ it "should not query when finding by _id and _type" do
440
+ blog = Blog.create(:title => 'Blog')
441
+ post = BlogPost.create(:title => 'MarkLogic Rocks', :blog => blog)
442
+ clear_identity_map
443
+
444
+ blog = Item.find(blog.id)
445
+ post = Item.find(post.id)
446
+ assert_in_map(blog, post)
447
+
448
+ expect_no_queries
449
+ post.blog
450
+ Blog.find(blog.id)
451
+ end
452
+
453
+ it "should load from map when using parent collection inherited class" do
454
+ blog = Blog.create(:title => 'Jill')
455
+ Item.find(blog.id).should equal(blog)
456
+ end
457
+
458
+ it "should work correctly with belongs to proxy" do
459
+ root = Item.create(:title => 'Root')
460
+ assert_in_map(root)
461
+
462
+ blog = Blog.create(:title => 'Jill', :parent => root)
463
+ assert_in_map(blog)
464
+ root.should equal(blog.parent.target)
465
+ end
466
+
467
+ it "should work correctly with one proxy" do
468
+ blog = Blog.create(:title => 'Jill')
469
+ assert_in_map(blog)
470
+
471
+ root = Item.create(:title => 'Root', :blog => blog)
472
+ assert_in_map(root)
473
+ blog.should equal(root.blog.target)
474
+ end
475
+
476
+ it "should work correctly with one proxy create" do
477
+ root = Item.create(:title => 'Root')
478
+ blog = root.create_blog(:title => 'Blog')
479
+ blog.parent.should equal(root)
480
+ end
481
+ end
482
+ end
483
+ end