mark_mapper 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.rdoc +39 -0
- data/examples/attr_accessible.rb +24 -0
- data/examples/attr_protected.rb +24 -0
- data/examples/cache_key.rb +26 -0
- data/examples/custom_types.rb +26 -0
- data/examples/identity_map.rb +30 -0
- data/examples/identity_map/automatic.rb +2 -0
- data/examples/keys.rb +42 -0
- data/examples/modifiers/set.rb +27 -0
- data/examples/plugins.rb +40 -0
- data/examples/querying.rb +39 -0
- data/examples/sample_app.rb +43 -0
- data/examples/scopes.rb +56 -0
- data/examples/validating/embedded_docs.rb +31 -0
- data/lib/mark_mapper.rb +125 -0
- data/lib/mark_mapper/config.rb +90 -0
- data/lib/mark_mapper/connection.rb +60 -0
- data/lib/mark_mapper/criteria_hash.rb +194 -0
- data/lib/mark_mapper/document.rb +46 -0
- data/lib/mark_mapper/embedded_document.rb +32 -0
- data/lib/mark_mapper/exceptions.rb +33 -0
- data/lib/mark_mapper/extensions/array.rb +27 -0
- data/lib/mark_mapper/extensions/boolean.rb +45 -0
- data/lib/mark_mapper/extensions/date.rb +29 -0
- data/lib/mark_mapper/extensions/duplicable.rb +86 -0
- data/lib/mark_mapper/extensions/float.rb +18 -0
- data/lib/mark_mapper/extensions/hash.rb +26 -0
- data/lib/mark_mapper/extensions/integer.rb +27 -0
- data/lib/mark_mapper/extensions/kernel.rb +11 -0
- data/lib/mark_mapper/extensions/nil_class.rb +18 -0
- data/lib/mark_mapper/extensions/object.rb +30 -0
- data/lib/mark_mapper/extensions/object_id.rb +18 -0
- data/lib/mark_mapper/extensions/set.rb +20 -0
- data/lib/mark_mapper/extensions/string.rb +31 -0
- data/lib/mark_mapper/extensions/symbol.rb +87 -0
- data/lib/mark_mapper/extensions/time.rb +29 -0
- data/lib/mark_mapper/locale/en.yml +5 -0
- data/lib/mark_mapper/middleware/identity_map.rb +41 -0
- data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
- data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
- data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
- data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
- data/lib/mark_mapper/normalizers/integer.rb +19 -0
- data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
- data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
- data/lib/mark_mapper/options_hash.rb +103 -0
- data/lib/mark_mapper/pagination.rb +6 -0
- data/lib/mark_mapper/pagination/collection.rb +32 -0
- data/lib/mark_mapper/pagination/paginator.rb +46 -0
- data/lib/mark_mapper/plugins.rb +22 -0
- data/lib/mark_mapper/plugins/accessible.rb +61 -0
- data/lib/mark_mapper/plugins/active_model.rb +18 -0
- data/lib/mark_mapper/plugins/associations.rb +96 -0
- data/lib/mark_mapper/plugins/associations/base.rb +98 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
- data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
- data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
- data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
- data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
- data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
- data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
- data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
- data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
- data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
- data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
- data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
- data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
- data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
- data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
- data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
- data/lib/mark_mapper/plugins/caching.rb +21 -0
- data/lib/mark_mapper/plugins/callbacks.rb +42 -0
- data/lib/mark_mapper/plugins/clone.rb +24 -0
- data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
- data/lib/mark_mapper/plugins/dirty.rb +61 -0
- data/lib/mark_mapper/plugins/document.rb +41 -0
- data/lib/mark_mapper/plugins/dumpable.rb +22 -0
- data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
- data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
- data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
- data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
- data/lib/mark_mapper/plugins/equality.rb +23 -0
- data/lib/mark_mapper/plugins/identity_map.rb +144 -0
- data/lib/mark_mapper/plugins/indexable.rb +86 -0
- data/lib/mark_mapper/plugins/inspect.rb +16 -0
- data/lib/mark_mapper/plugins/keys.rb +470 -0
- data/lib/mark_mapper/plugins/keys/key.rb +134 -0
- data/lib/mark_mapper/plugins/keys/static.rb +45 -0
- data/lib/mark_mapper/plugins/logger.rb +18 -0
- data/lib/mark_mapper/plugins/modifiers.rb +140 -0
- data/lib/mark_mapper/plugins/pagination.rb +16 -0
- data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
- data/lib/mark_mapper/plugins/persistence.rb +79 -0
- data/lib/mark_mapper/plugins/protected.rb +45 -0
- data/lib/mark_mapper/plugins/querying.rb +173 -0
- data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
- data/lib/mark_mapper/plugins/rails.rb +79 -0
- data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
- data/lib/mark_mapper/plugins/sci.rb +82 -0
- data/lib/mark_mapper/plugins/scopes.rb +28 -0
- data/lib/mark_mapper/plugins/serialization.rb +109 -0
- data/lib/mark_mapper/plugins/timestamps.rb +29 -0
- data/lib/mark_mapper/plugins/touch.rb +18 -0
- data/lib/mark_mapper/plugins/userstamps.rb +18 -0
- data/lib/mark_mapper/plugins/validations.rb +96 -0
- data/lib/mark_mapper/query.rb +278 -0
- data/lib/mark_mapper/railtie.rb +52 -0
- data/lib/mark_mapper/railtie/database.rake +65 -0
- data/lib/mark_mapper/translation.rb +10 -0
- data/lib/mark_mapper/version.rb +4 -0
- data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
- data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
- data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
- data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
- data/spec/config/mark_mapper.yml +6 -0
- data/spec/examples_spec.rb +25 -0
- data/spec/functional/accessible_spec.rb +198 -0
- data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
- data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
- data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
- data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
- data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
- data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
- data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
- data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
- data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
- data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
- data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
- data/spec/functional/associations/one_proxy_spec.rb +406 -0
- data/spec/functional/associations_spec.rb +48 -0
- data/spec/functional/caching_spec.rb +75 -0
- data/spec/functional/callbacks_spec.rb +330 -0
- data/spec/functional/counter_cache_spec.rb +235 -0
- data/spec/functional/dirty_spec.rb +316 -0
- data/spec/functional/document_spec.rb +310 -0
- data/spec/functional/dumpable_spec.rb +24 -0
- data/spec/functional/dynamic_querying_spec.rb +75 -0
- data/spec/functional/embedded_document_spec.rb +316 -0
- data/spec/functional/equality_spec.rb +20 -0
- data/spec/functional/extensions_spec.rb +16 -0
- data/spec/functional/identity_map_spec.rb +483 -0
- data/spec/functional/keys_spec.rb +339 -0
- data/spec/functional/logger_spec.rb +20 -0
- data/spec/functional/modifiers_spec.rb +446 -0
- data/spec/functional/options_hash_spec.rb +41 -0
- data/spec/functional/pagination_spec.rb +89 -0
- data/spec/functional/partial_updates_spec.rb +530 -0
- data/spec/functional/protected_spec.rb +199 -0
- data/spec/functional/querying_spec.rb +984 -0
- data/spec/functional/rails_spec.rb +55 -0
- data/spec/functional/sci_spec.rb +374 -0
- data/spec/functional/scopes_spec.rb +204 -0
- data/spec/functional/static_keys_spec.rb +153 -0
- data/spec/functional/timestamps_spec.rb +97 -0
- data/spec/functional/touch_spec.rb +125 -0
- data/spec/functional/userstamps_spec.rb +46 -0
- data/spec/functional/validations_spec.rb +416 -0
- data/spec/quality_spec.rb +51 -0
- data/spec/spec_helper.rb +150 -0
- data/spec/support/matchers.rb +15 -0
- data/spec/support/models.rb +256 -0
- data/spec/symbol_operator_spec.rb +70 -0
- data/spec/symbol_spec.rb +9 -0
- data/spec/unit/associations/base_spec.rb +146 -0
- data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
- data/spec/unit/associations/many_association_spec.rb +64 -0
- data/spec/unit/associations/one_association_spec.rb +48 -0
- data/spec/unit/associations/proxy_spec.rb +103 -0
- data/spec/unit/clone_spec.rb +79 -0
- data/spec/unit/config_generator_spec.rb +24 -0
- data/spec/unit/criteria_hash_spec.rb +218 -0
- data/spec/unit/document_spec.rb +251 -0
- data/spec/unit/dynamic_finder_spec.rb +125 -0
- data/spec/unit/embedded_document_spec.rb +676 -0
- data/spec/unit/equality_spec.rb +38 -0
- data/spec/unit/exceptions_spec.rb +12 -0
- data/spec/unit/extensions_spec.rb +368 -0
- data/spec/unit/identity_map_middleware_spec.rb +134 -0
- data/spec/unit/inspect_spec.rb +47 -0
- data/spec/unit/key_spec.rb +276 -0
- data/spec/unit/keys_spec.rb +155 -0
- data/spec/unit/mark_mapper_spec.rb +37 -0
- data/spec/unit/model_generator_spec.rb +45 -0
- data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
- data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
- data/spec/unit/normalizers/fields_value_spec.rb +45 -0
- data/spec/unit/normalizers/hash_key_spec.rb +15 -0
- data/spec/unit/normalizers/integer_spec.rb +24 -0
- data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
- data/spec/unit/normalizers/sort_value_spec.rb +98 -0
- data/spec/unit/options_hash_spec.rb +64 -0
- data/spec/unit/pagination/collection_spec.rb +30 -0
- data/spec/unit/pagination/paginator_spec.rb +118 -0
- data/spec/unit/pagination_spec.rb +11 -0
- data/spec/unit/plugins_spec.rb +89 -0
- data/spec/unit/query_spec.rb +837 -0
- data/spec/unit/rails_compatibility_spec.rb +40 -0
- data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
- data/spec/unit/rails_spec.rb +188 -0
- data/spec/unit/serialization_spec.rb +169 -0
- data/spec/unit/serializers/json_serializer_spec.rb +218 -0
- data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
- data/spec/unit/time_zones_spec.rb +44 -0
- data/spec/unit/translation_spec.rb +27 -0
- data/spec/unit/validations_spec.rb +588 -0
- metadata +307 -0
@@ -0,0 +1,302 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "ManyPolymorphicProxy" do
|
4
|
+
before do
|
5
|
+
Room.collection.remove
|
6
|
+
Message.collection.remove
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should default reader to empty array" do
|
10
|
+
Room.new.messages.should == []
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should add type key to polymorphic class base" do
|
14
|
+
Message.keys.keys.should include('_type')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow adding to assiciation like it was an array" do
|
18
|
+
room = Room.new
|
19
|
+
room.messages << Enter.new
|
20
|
+
room.messages.push Exit.new
|
21
|
+
room.messages.concat Exit.new
|
22
|
+
room.messages.size.should == 3
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to replace the association" do
|
26
|
+
room = Room.create(:name => 'Lounge')
|
27
|
+
|
28
|
+
lambda {
|
29
|
+
room.messages = [
|
30
|
+
Enter.new(:body => 'John entered room', :position => 1),
|
31
|
+
Chat.new(:body => 'Heyyyoooo!', :position => 2),
|
32
|
+
Exit.new(:body => 'John exited room', :position => 3)
|
33
|
+
]
|
34
|
+
}.should change { Message.count }.by(3)
|
35
|
+
|
36
|
+
room = room.reload
|
37
|
+
messages = room.messages.all :order => "position"
|
38
|
+
messages.size.should == 3
|
39
|
+
messages[0].body.should == 'John entered room'
|
40
|
+
messages[1].body.should == 'Heyyyoooo!'
|
41
|
+
messages[2].body.should == 'John exited room'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should correctly store type when using <<, push and concat" do
|
45
|
+
room = Room.new
|
46
|
+
room.messages << Enter.new(:body => 'John entered the room', :position => 1)
|
47
|
+
room.messages.push Exit.new(:body => 'John entered the room', :position => 2)
|
48
|
+
room.messages.concat Chat.new(:body => 'Holla!' , :position => 3)
|
49
|
+
|
50
|
+
room = room.reload
|
51
|
+
messages = room.messages.all :order => "position"
|
52
|
+
messages[0]._type.should == 'Enter'
|
53
|
+
messages[1]._type.should == 'Exit'
|
54
|
+
messages[2]._type.should == 'Chat'
|
55
|
+
end
|
56
|
+
|
57
|
+
context "build" do
|
58
|
+
it "should assign foreign key" do
|
59
|
+
room = Room.create
|
60
|
+
message = room.messages.build
|
61
|
+
message.room_id.should == room._id
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should assign _type" do
|
65
|
+
room = Room.create
|
66
|
+
message = room.messages.build
|
67
|
+
message._type.should == 'Message'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should allow assigning attributes" do
|
71
|
+
room = Room.create
|
72
|
+
message = room.messages.build(:body => 'Foo!')
|
73
|
+
message.body.should == 'Foo!'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "create" do
|
78
|
+
it "should assign foreign key" do
|
79
|
+
room = Room.create
|
80
|
+
message = room.messages.create
|
81
|
+
message.room_id.should == room._id
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should assign _type" do
|
85
|
+
room = Room.create
|
86
|
+
message = room.messages.create
|
87
|
+
message._type.should == 'Message'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should save record" do
|
91
|
+
room = Room.create
|
92
|
+
lambda {
|
93
|
+
room.messages.create
|
94
|
+
}.should change { Message.count }
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should allow passing attributes" do
|
98
|
+
room = Room.create
|
99
|
+
message = room.messages.create(:body => 'Foo!')
|
100
|
+
message.body.should == 'Foo!'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "count" do
|
105
|
+
it "should work scoped to association" do
|
106
|
+
room = Room.create
|
107
|
+
3.times { room.messages.create }
|
108
|
+
|
109
|
+
other_room = Room.create
|
110
|
+
2.times { other_room.messages.create }
|
111
|
+
|
112
|
+
room.messages.count.should == 3
|
113
|
+
other_room.messages.count.should == 2
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should work with conditions" do
|
117
|
+
room = Room.create
|
118
|
+
room.messages.create(:body => 'Foo')
|
119
|
+
room.messages.create(:body => 'Other 1')
|
120
|
+
room.messages.create(:body => 'Other 2')
|
121
|
+
|
122
|
+
room.messages.count(:body => 'Foo').should == 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "Finding scoped to association" do
|
127
|
+
before do
|
128
|
+
@lounge = Room.create(:name => 'Lounge')
|
129
|
+
@lm1 = Message.create(:body => 'Loungin!', :position => 1)
|
130
|
+
@lm2 = Message.create(:body => 'I love loungin!', :position => 2)
|
131
|
+
@lounge.messages = [@lm1, @lm2]
|
132
|
+
@lounge.save
|
133
|
+
|
134
|
+
@hall = Room.create(:name => 'Hall')
|
135
|
+
@hm1 = Message.create(:body => 'Do not fall in the hall', :position => 1)
|
136
|
+
@hm3 = Message.create(:body => 'Loungin!', :position => 3)
|
137
|
+
@hm2 = Message.create(:body => 'Hall the king!', :position => 2)
|
138
|
+
@hall.messages = [@hm1, @hm2, @hm3]
|
139
|
+
@hall.save
|
140
|
+
@hall.reload
|
141
|
+
end
|
142
|
+
|
143
|
+
context "dynamic finders" do
|
144
|
+
it "should work with single key" do
|
145
|
+
@lounge.messages.find_by_position(1).should == @lm1
|
146
|
+
@hall.messages.find_by_position(2).should == @hm2
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should work with multiple keys" do
|
150
|
+
@lounge.messages.find_by_body_and_position('Loungin!', 1).should == @lm1
|
151
|
+
@lounge.messages.find_by_body_and_position('Loungin!', 2).should be_nil
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should raise error when using !" do
|
155
|
+
lambda {
|
156
|
+
@lounge.messages.find_by_position!(222)
|
157
|
+
}.should raise_error(MarkMapper::DocumentNotFound)
|
158
|
+
end
|
159
|
+
|
160
|
+
context "find_or_create_by" do
|
161
|
+
it "should not create document if found" do
|
162
|
+
lambda {
|
163
|
+
message = @lounge.messages.find_or_create_by_body('Loungin!')
|
164
|
+
message.room.should == @lounge
|
165
|
+
message.should == @lm1
|
166
|
+
}.should_not change { Message.count }
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should create document if not found" do
|
170
|
+
lambda {
|
171
|
+
message = @lounge.messages.find_or_create_by_body('Yo dawg!')
|
172
|
+
message.room.should == @lounge
|
173
|
+
message._type.should == 'Message'
|
174
|
+
}.should change { Message.count }.by(1)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with #all" do
|
180
|
+
it "should work" do
|
181
|
+
@lounge.messages.all(:order => "position").should == [@lm1, @lm2]
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should work with conditions" do
|
185
|
+
messages = @lounge.messages.all(:body => 'Loungin!', :order => "position")
|
186
|
+
messages.should == [@lm1]
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should work with order" do
|
190
|
+
messages = @lounge.messages.all(:order => 'position desc')
|
191
|
+
messages.should == [@lm2, @lm1]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with #first" do
|
196
|
+
it "should work" do
|
197
|
+
@lounge.messages.first(:order => "position asc").should == @lm1
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should work with conditions" do
|
201
|
+
message = @lounge.messages.first(:body => 'I love loungin!', :order => "position asc")
|
202
|
+
message.should == @lm2
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with #last" do
|
207
|
+
it "should work" do
|
208
|
+
@lounge.messages.last(:order => "position asc").should == @lm2
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should work with conditions" do
|
212
|
+
message = @lounge.messages.last(:body => 'Loungin!', :order => "position asc")
|
213
|
+
message.should == @lm1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "with one id" do
|
218
|
+
it "should work for id in association" do
|
219
|
+
@lounge.messages.find(@lm2._id).should == @lm2
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should not work for id not in association" do
|
223
|
+
lambda {
|
224
|
+
@lounge.messages.find!(@hm2._id)
|
225
|
+
}.should raise_error(MarkMapper::DocumentNotFound)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "with query options/criteria" do
|
230
|
+
it "should work with order on association" do
|
231
|
+
@lounge.messages.should == [@lm1, @lm2]
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should allow overriding the order provided to the association" do
|
235
|
+
@lounge.messages.all(:order => 'position').should == [@lm1, @lm2]
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should allow using conditions on association" do
|
239
|
+
@hall.latest_messages.should == [@hm3, @hm2]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "with multiple ids" do
|
244
|
+
it "should work for ids in association" do
|
245
|
+
messages = @lounge.messages.find(@lm1._id, @lm2._id)
|
246
|
+
messages.should == [@lm1, @lm2]
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should not work for ids not in association" do
|
250
|
+
expect {
|
251
|
+
@lounge.messages.find!(@lm1._id, @lm2._id, @hm2._id)
|
252
|
+
}.to raise_error(MarkMapper::DocumentNotFound)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context "with #paginate" do
|
257
|
+
before do
|
258
|
+
@messages = @hall.messages.paginate(:per_page => 2, :page => 1, :order => 'position asc')
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should return total pages" do
|
262
|
+
@messages.total_pages.should == 2
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should return total entries" do
|
266
|
+
@messages.total_entries.should == 3
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should return the subject" do
|
270
|
+
@messages.should == [@hm1, @hm2]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
context "extending the association" do
|
276
|
+
it "should work using a block passed to many" do
|
277
|
+
room = Room.new(:name => "Amazing Room")
|
278
|
+
messages = room.messages = [
|
279
|
+
Enter.new(:body => 'John entered room', :position => 3),
|
280
|
+
Chat.new(:body => 'Heyyyoooo!', :position => 4),
|
281
|
+
Exit.new(:body => 'John exited room', :position => 5),
|
282
|
+
Enter.new(:body => 'Steve entered room', :position => 6),
|
283
|
+
Chat.new(:body => 'Anyone there?', :position => 7),
|
284
|
+
Exit.new(:body => 'Steve exited room', :position => 8)
|
285
|
+
]
|
286
|
+
room.save
|
287
|
+
room.messages.older.should == messages[3..5]
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should work using many's :extend option" do
|
291
|
+
|
292
|
+
room = Room.new(:name => "Amazing Room")
|
293
|
+
accounts = room.accounts = [
|
294
|
+
Bot.new(:last_logged_in => 3.weeks.ago),
|
295
|
+
AccountUser.new(:last_logged_in => nil),
|
296
|
+
Bot.new(:last_logged_in => 1.week.ago)
|
297
|
+
]
|
298
|
+
room.save
|
299
|
+
room.accounts.inactive.should == [accounts[1]]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
@@ -0,0 +1,489 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/models'
|
3
|
+
|
4
|
+
describe "OneAsProxy" do
|
5
|
+
before do
|
6
|
+
@post_class = Doc('Post')
|
7
|
+
@author_class = Doc('Author')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should default to nil" do
|
11
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
12
|
+
@post_class.new.author.nil?.should be_truthy
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return nil instead of a proxy" do
|
16
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
17
|
+
nil.should === @post_class.new.author
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not define any keys" do
|
21
|
+
count = @post_class.keys.length
|
22
|
+
@post_class.one :author, :class => @author_class
|
23
|
+
@post_class.keys.length.should == count
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should allow assignment of associated document using a hash" do
|
27
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
28
|
+
|
29
|
+
post = @post_class.new('author' => { 'name' => 'Frank' })
|
30
|
+
post.author.name.should == 'Frank'
|
31
|
+
|
32
|
+
post.save.should be_truthy
|
33
|
+
post.reload
|
34
|
+
|
35
|
+
post.author.name.should == 'Frank'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should only return a document with the correct type" do
|
39
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
40
|
+
post = @post_class.create
|
41
|
+
|
42
|
+
author = @author_class.create(:authorable_id => post.id, :authorable_type => "Nada")
|
43
|
+
post.reload.author.should be_nil
|
44
|
+
|
45
|
+
author = @author_class.create(:authorable_id => post.id, :authorable_type => "Post")
|
46
|
+
post.reload.author.should == author
|
47
|
+
end
|
48
|
+
|
49
|
+
context "replacing the association" do
|
50
|
+
context "with an object of the class" do
|
51
|
+
before do
|
52
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
53
|
+
@post = @post_class.new
|
54
|
+
@author = @author_class.new(:name => 'Frank')
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should work" do
|
58
|
+
@post.author = @author
|
59
|
+
@post.reload
|
60
|
+
|
61
|
+
@post.author.should == @author
|
62
|
+
@post.author.nil?.should be_falsey
|
63
|
+
|
64
|
+
new_author = @author_class.new(:name => 'Emily')
|
65
|
+
@post.author = new_author
|
66
|
+
@post.author.should == new_author
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should generate a new proxy instead of modifying the existing one" do
|
70
|
+
@post.author = @author
|
71
|
+
@post.reload
|
72
|
+
|
73
|
+
@post.author.should == @author
|
74
|
+
@post.author.nil?.should be_falsey
|
75
|
+
|
76
|
+
original_author = @post.author
|
77
|
+
original_author.name.should == 'Frank'
|
78
|
+
new_author = @author_class.new(:name => 'Emily')
|
79
|
+
@post.author = new_author
|
80
|
+
@post.author.should == new_author
|
81
|
+
|
82
|
+
original_author.name.should == 'Frank'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should assign foreign key" do
|
86
|
+
@post.author = @author
|
87
|
+
@post.author.authorable_id.should == @post.id
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should assign _type" do
|
91
|
+
@post.author = @author
|
92
|
+
@post.author.authorable_type.should == "Post"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "with a Hash" do
|
97
|
+
before do
|
98
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
99
|
+
@post = @post_class.new
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should convert to an object of the class and work" do
|
103
|
+
@post.author = {'name' => 'Frank'}
|
104
|
+
@post.reload
|
105
|
+
|
106
|
+
@post.author.name.should == 'Frank'
|
107
|
+
@post.author.nil?.should be_falsey
|
108
|
+
|
109
|
+
@post.author = {'name' => 'Emily'}
|
110
|
+
@post.author.name.should == 'Emily'
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should assign foreign key" do
|
114
|
+
@post.author = {'name' => 'Frank'}
|
115
|
+
@post.author.authorable_id.should == @post.id
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should assign _type" do
|
119
|
+
@post.author = {'name' => 'Frank'}
|
120
|
+
@post.author.authorable_type.should == "Post"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "with :dependent" do
|
125
|
+
context "=> delete" do
|
126
|
+
before do
|
127
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :delete
|
128
|
+
|
129
|
+
@post = @post_class.create
|
130
|
+
@author = @author_class.new
|
131
|
+
@post.author = @author
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should call delete on the existing document" do
|
135
|
+
expect_any_instance_of(@author_class).to receive(:delete).once
|
136
|
+
@post.author = @author_class.new
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should remove the existing document from the database" do
|
140
|
+
@post.author = @author_class.new
|
141
|
+
lambda { @author.reload }.should raise_error(MarkMapper::DocumentNotFound)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should do nothing if it's the same document" do
|
145
|
+
expect_any_instance_of(@author_class).to receive(:delete).never
|
146
|
+
@post.author = @author
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "=> destory" do
|
151
|
+
before do
|
152
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :destroy
|
153
|
+
|
154
|
+
@post = @post_class.create
|
155
|
+
@author = @author_class.new
|
156
|
+
@post.author = @author
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should call destroy the existing document" do
|
160
|
+
expect_any_instance_of(@author_class).to receive(:destroy).once
|
161
|
+
@post.author = @author_class.new
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should remove the existing document from the database" do
|
165
|
+
@post.author = @author_class.new
|
166
|
+
lambda { @author.reload }.should raise_error(MarkMapper::DocumentNotFound)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should do nothing if it's the same document" do
|
170
|
+
expect_any_instance_of(@author_class).to receive(:destroy).never
|
171
|
+
@post.author = @author
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "=> nullify" do
|
176
|
+
before do
|
177
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :nullify
|
178
|
+
|
179
|
+
@post = @post_class.create
|
180
|
+
@author = @author_class.new
|
181
|
+
@post.author = @author
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should nullify the existing document" do
|
185
|
+
@author.reload
|
186
|
+
@author.authorable_id.should == @post.id
|
187
|
+
|
188
|
+
@post.author = @author_class.new
|
189
|
+
|
190
|
+
@author.reload
|
191
|
+
@author.authorable_id.should be_nil
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should work when it's the same document" do
|
195
|
+
old_author = @post.author
|
196
|
+
@post.author = @author
|
197
|
+
old_author.should == @post.author
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should nullify _type" do
|
201
|
+
@post.author = @author_class.new
|
202
|
+
@author.reload
|
203
|
+
@author.authorable_type.should be_nil
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "unspecified" do
|
208
|
+
before do
|
209
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
210
|
+
|
211
|
+
@post = @post_class.create
|
212
|
+
@author = @author_class.new
|
213
|
+
@post.author = @author
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should nullify the existing document" do
|
217
|
+
@author.reload
|
218
|
+
@author.authorable_id.should == @post.id
|
219
|
+
|
220
|
+
@post.author = @author_class.new
|
221
|
+
|
222
|
+
@author.reload
|
223
|
+
@author.authorable_id.should be_nil
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should nullify _type" do
|
227
|
+
@post.author = @author_class.new
|
228
|
+
@author.reload
|
229
|
+
@author.authorable_type.should be_nil
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context "with nil" do
|
235
|
+
before do
|
236
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
237
|
+
|
238
|
+
@post = @post_class.new
|
239
|
+
@author = @author_class.new(:name => 'Frank')
|
240
|
+
@post.author = @author
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should nullify the existing document" do
|
244
|
+
@post.author = nil
|
245
|
+
@author.reload
|
246
|
+
@author.authorable_id.should be_nil
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should set the target to nil" do
|
250
|
+
@post.author = nil
|
251
|
+
@post.author.should == nil
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should nullify _type" do
|
255
|
+
@post.author = nil
|
256
|
+
@author.reload
|
257
|
+
@author.authorable_type.should be_nil
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should have boolean method for testing presence" do
|
263
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
264
|
+
|
265
|
+
post = @post_class.new
|
266
|
+
post.author?.should be_falsey
|
267
|
+
|
268
|
+
post.author = @author_class.new(:name => 'Frank')
|
269
|
+
post.author?.should be_truthy
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should work with criteria" do
|
273
|
+
@post_class.one :primary_author, :as => :authorable, :class => @author_class, :primary => true
|
274
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :primary => false
|
275
|
+
|
276
|
+
post = @post_class.create
|
277
|
+
author = @author_class.create(:name => 'Frank', :primary => false, :authorable_id => post.id, :authorable_type => 'Post')
|
278
|
+
primary = @author_class.create(:name => 'Bill', :primary => true, :authorable_id => post.id, :authorable_type => 'Post')
|
279
|
+
post.reload
|
280
|
+
post.author.should == author
|
281
|
+
post.primary_author.should == primary
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should unset the association" do
|
285
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
286
|
+
post = @post_class.create
|
287
|
+
author = @author_class.create
|
288
|
+
post.update_attributes!(:author => author)
|
289
|
+
post.reload
|
290
|
+
post.author = nil
|
291
|
+
post.author.nil?.should be_truthy
|
292
|
+
end
|
293
|
+
|
294
|
+
context "destroying parent with :dependent" do
|
295
|
+
context "=> destroy" do
|
296
|
+
before do
|
297
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :destroy
|
298
|
+
|
299
|
+
@post = @post_class.create
|
300
|
+
@author = @author_class.new
|
301
|
+
@post.author = @author
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should should call destroy on the associated documents" do
|
305
|
+
expect_any_instance_of(@author_class).to receive(:destroy).once
|
306
|
+
@post.destroy
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should should remove the associated documents" do
|
310
|
+
@author_class.count.should == 1
|
311
|
+
@post.destroy
|
312
|
+
@post.author.should == nil
|
313
|
+
@author_class.count.should == 0
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
context "=> delete" do
|
318
|
+
before do
|
319
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :delete
|
320
|
+
|
321
|
+
@post = @post_class.create
|
322
|
+
@author = @author_class.new
|
323
|
+
@post.author = @author
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should should call delete the associated documents" do
|
327
|
+
expect_any_instance_of(@author_class).to receive(:delete).once
|
328
|
+
@post.destroy
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should remove the associated documents" do
|
332
|
+
@author_class.count.should == 1
|
333
|
+
@post.destroy
|
334
|
+
@post.author.should == nil
|
335
|
+
@author_class.count.should == 0
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "=> nullify" do
|
340
|
+
before do
|
341
|
+
@post_class.one :author, :as => :authorable, :class => @author_class, :dependent => :nullify
|
342
|
+
|
343
|
+
@post = @post_class.create
|
344
|
+
@author = @author_class.new
|
345
|
+
@post.author = @author
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should should nullify the relationship but not destroy the associated document" do
|
349
|
+
@author_class.count.should == 1
|
350
|
+
@post.destroy
|
351
|
+
@post.author.should == nil
|
352
|
+
@author_class.count.should == 1
|
353
|
+
|
354
|
+
@author_class.first.should == @author
|
355
|
+
@author.authorable_id.should == nil
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should nullify _type" do
|
359
|
+
@post.destroy
|
360
|
+
@author.authorable_type.should be_nil
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context "unspecified" do
|
365
|
+
before do
|
366
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
367
|
+
|
368
|
+
@post = @post_class.create
|
369
|
+
@author = @author_class.new
|
370
|
+
@post.author = @author
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should should nullify the relationship but not destroy the associated document" do
|
374
|
+
@author_class.count.should == 1
|
375
|
+
@post.destroy
|
376
|
+
@post.author.should == nil
|
377
|
+
@author_class.count.should == 1
|
378
|
+
|
379
|
+
@author_class.first.should == @author
|
380
|
+
@author.authorable_id.should == nil
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should nullify _type" do
|
384
|
+
@post.destroy
|
385
|
+
@author.authorable_type.should be_nil
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context "#build" do
|
391
|
+
before do
|
392
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
393
|
+
@post = @post_class.create
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should be able to build with attributes" do
|
397
|
+
author = @post.build_author(:name => 'John')
|
398
|
+
@post.author.should be_instance_of(@author_class)
|
399
|
+
@post.author.should be_new
|
400
|
+
@post.author.name.should == 'John'
|
401
|
+
@post.author.should == author
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should assign foreign key" do
|
405
|
+
@post.build_author
|
406
|
+
@post.author.authorable_id.should == @post.id
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should assign _type" do
|
410
|
+
@post.build_author
|
411
|
+
@post.author.authorable_type.should == 'Post'
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
context "#create" do
|
416
|
+
before do
|
417
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
418
|
+
@post = @post_class.create
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should be able to create" do
|
422
|
+
author = @post.create_author(:name => 'John')
|
423
|
+
@post.author.should be_instance_of(@author_class)
|
424
|
+
@post.author.should_not be_new
|
425
|
+
@post.author.name.should == 'John'
|
426
|
+
@post.author.should == author
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should assign foreign key" do
|
430
|
+
@post.create_author
|
431
|
+
@post.author.authorable_id.should == @post.id
|
432
|
+
end
|
433
|
+
|
434
|
+
it "should assign _type" do
|
435
|
+
@post.create_author
|
436
|
+
@post.author.authorable_type.should == 'Post'
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
context "#create!" do
|
441
|
+
before do
|
442
|
+
@author_class.key :name, String, :required => true
|
443
|
+
@post_class.one :author, :as => :authorable, :class => @author_class
|
444
|
+
@post = @post_class.create
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should raise exception if invalid" do
|
448
|
+
expect { @post.create_author! }.to raise_error(MarkMapper::DocumentNotValid)
|
449
|
+
end
|
450
|
+
|
451
|
+
it "should work if valid" do
|
452
|
+
author = @post.create_author!(:name => 'John')
|
453
|
+
@post.author.should be_instance_of(@author_class)
|
454
|
+
@post.author.should_not be_new
|
455
|
+
@post.author.name.should == 'John'
|
456
|
+
@post.author.should == author
|
457
|
+
end
|
458
|
+
|
459
|
+
it "should assign foreign key if valid" do
|
460
|
+
@post.create_author!(:name => 'John')
|
461
|
+
@post.author.authorable_id.should == @post.id
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should assign _type if valid" do
|
465
|
+
@post.create_author!(:name => 'John')
|
466
|
+
@post.author.authorable_type.should == 'Post'
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context "namespaced foreign keys" do
|
471
|
+
before do
|
472
|
+
News::Paper.one :article, :as => 'articleable', :class_name => 'News::Article'
|
473
|
+
News::Article.belongs_to :articleable, :polymorphic => true
|
474
|
+
|
475
|
+
@paper = News::Paper.create
|
476
|
+
end
|
477
|
+
|
478
|
+
it "should work" do
|
479
|
+
@paper.create_article
|
480
|
+
@paper.article.class.should == News::Article
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should properly infer the foreign key" do
|
484
|
+
article = @paper.create_article
|
485
|
+
article.should respond_to(:articleable_id)
|
486
|
+
article.articleable_id.should == @paper.id
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|