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,339 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Keys" do
|
4
|
+
it "should not have a disparity between the ivar and accessor" do
|
5
|
+
doc = Doc do
|
6
|
+
key :foo, String
|
7
|
+
|
8
|
+
def modify_foo
|
9
|
+
@foo = :baz
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_foo
|
13
|
+
@foo
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
instance = doc.new(:foo => "bar")
|
18
|
+
instance.get_foo.should == instance.foo
|
19
|
+
|
20
|
+
instance.foo = :bing
|
21
|
+
instance.get_foo.should == instance.foo
|
22
|
+
|
23
|
+
instance.modify_foo
|
24
|
+
instance.get_foo.should == instance.foo
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return the value when set using send with the writer method" do
|
28
|
+
doc = Doc do
|
29
|
+
key :foo, String
|
30
|
+
end
|
31
|
+
|
32
|
+
instance = doc.new(:foo => 'bar')
|
33
|
+
instance.send("foo=", 'baz').should == 'baz'
|
34
|
+
instance.foo.should == 'baz'
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when persisting an typecasted array" do
|
38
|
+
TypecastedKeyModel = Doc do
|
39
|
+
key :people, Array, :typecast => "Person"
|
40
|
+
end
|
41
|
+
|
42
|
+
Person = Struct.new(:name) do
|
43
|
+
def self.to_marklogic(value)
|
44
|
+
value.name
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.from_marklogic(value)
|
48
|
+
Person.new value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not mutate the model's state" do
|
53
|
+
person = Person.new "Bob"
|
54
|
+
doc = TypecastedKeyModel.new(:people => [person])
|
55
|
+
|
56
|
+
doc.save
|
57
|
+
|
58
|
+
doc.people.should == [person]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should not bomb if a key is written before Keys#initialize gets to get called" do
|
63
|
+
doc = Class.new do
|
64
|
+
include MarkMapper::Document
|
65
|
+
|
66
|
+
def initialize
|
67
|
+
self.class.key :something, String
|
68
|
+
self.something = :other_thing
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
expect { doc.new }.to_not raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should not bomb if a key is read before Keys#initialize gets to get called" do
|
77
|
+
doc = Class.new do
|
78
|
+
include MarkMapper::Document
|
79
|
+
|
80
|
+
def initialize
|
81
|
+
self.class.key :something, String
|
82
|
+
self.something
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
expect { doc.new }.to_not raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should permit for key overrides" do
|
91
|
+
doc = Class.new do
|
92
|
+
include MarkMapper::Document
|
93
|
+
key :class, String, :accessors => :skip
|
94
|
+
end
|
95
|
+
|
96
|
+
doc.collection.insert('class' => 'String')
|
97
|
+
doc.all.first.tap do |d|
|
98
|
+
d.class.should == doc
|
99
|
+
d["class"].should == "String"
|
100
|
+
d.attributes["class"].should == "String"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "key segmenting" do
|
105
|
+
let(:doc) {
|
106
|
+
Doc {
|
107
|
+
key :defined
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
before do
|
112
|
+
doc.collection.insert(:dynamic => "foo")
|
113
|
+
doc.first
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#dynamic_keys" do
|
117
|
+
it "should find dynamic keys" do
|
118
|
+
doc.dynamic_keys.keys.should == ["dynamic"]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#defined_keys" do
|
123
|
+
it "should find defined keys" do
|
124
|
+
doc.defined_keys.keys.should =~ ["_id", "defined"]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "with invalid names" do
|
130
|
+
it "should warn when key names start with an uppercase letter" do
|
131
|
+
doc = Doc {}
|
132
|
+
expect(Kernel).to receive(:warn).once.with(/may not start with uppercase letters/)
|
133
|
+
doc.class_eval do
|
134
|
+
key :NotConstant
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should handle keys that start with uppercase letters by translating their first letter to lowercase" do
|
139
|
+
doc = Doc {}
|
140
|
+
allow(Kernel).to receive(:warn)
|
141
|
+
doc.class_eval do
|
142
|
+
key :NotConstant
|
143
|
+
end
|
144
|
+
doc.collection.insert("NotConstant" => "Just data!")
|
145
|
+
doc.first.notConstant.should == "Just data!"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not create accessors for bad keys" do
|
149
|
+
doc = Doc {}
|
150
|
+
expect(doc).to_not receive(:create_accessors_for)
|
151
|
+
doc.class_eval do
|
152
|
+
key :"bad-name", :__dynamic => true
|
153
|
+
end
|
154
|
+
expect { doc.new.method(:"bad-name") }.to raise_error(NameError)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should not create accessors for reserved keys" do
|
158
|
+
doc = Doc {}
|
159
|
+
expect(doc).to_not receive(:create_accessors_for)
|
160
|
+
doc.class_eval do
|
161
|
+
key :"class", :__dynamic => true
|
162
|
+
end
|
163
|
+
expect(doc.new.class).to eq doc
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should create accessors for good keys" do
|
167
|
+
doc = Doc {
|
168
|
+
key :good_name
|
169
|
+
}
|
170
|
+
doc.new.good_name.should be_nil
|
171
|
+
expect { doc.new.method("good_name") }.to_not raise_error
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should handle loading dynamic fields from the database that have bad names" do
|
176
|
+
doc = Doc {}
|
177
|
+
doc.collection.insert("foo-bar" => "baz-bin")
|
178
|
+
|
179
|
+
doc.first["foo-bar"].should == "baz-bin"
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "with aliases" do
|
183
|
+
AliasedKeyModel = Doc do
|
184
|
+
key :foo, :abbr => :f
|
185
|
+
key :with_underscores, :alias => "with-hyphens"
|
186
|
+
key :field_name, :field_name => "alternate_field_name"
|
187
|
+
key :bar
|
188
|
+
end
|
189
|
+
|
190
|
+
before { AliasedKeyModel.collection.drop }
|
191
|
+
|
192
|
+
context "standard key operations" do
|
193
|
+
before do
|
194
|
+
AliasedKeyModel.create(:foo => "whee!", :bar => "whoo!")
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should serialize with aliased keys" do
|
198
|
+
AliasedKeyModel.collection.find_one.keys.should =~ %w(_id f bar)
|
199
|
+
|
200
|
+
AliasedKeyModel.first.tap do |d|
|
201
|
+
d.foo.should == "whee!"
|
202
|
+
d.bar.should == "whoo!"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should permit querying via direct field names" do
|
207
|
+
AliasedKeyModel.where(AliasedKeyModel.abbr(:foo) => "whee!").first.foo.should == "whee!"
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should permit querying via direct field names" do
|
211
|
+
AliasedKeyModel.where(:foo => "whee!").criteria_hash.keys.should == ["f"]
|
212
|
+
AliasedKeyModel.where(:foo => "whee!").first.foo.should == "whee!"
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should permit filtering via aliases" do
|
216
|
+
AliasedKeyModel.where(:foo => "whee!").fields(:foo).first.foo.should == "whee!"
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should permit dealiasing of atomic operations" do
|
220
|
+
m = AliasedKeyModel.first
|
221
|
+
m.set(:foo => 1)
|
222
|
+
AliasedKeyModel.collection.find_one["f"].should == 1
|
223
|
+
AliasedKeyModel.collection.find_one["foo"].should be_nil
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should permit dealiasing of update operations" do
|
227
|
+
m = AliasedKeyModel.first
|
228
|
+
m.update_attributes(:foo => 1)
|
229
|
+
AliasedKeyModel.collection.find_one["f"].should == 1
|
230
|
+
AliasedKeyModel.collection.find_one["foo"].should be_nil
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should not break when unaliasing non-keys" do
|
234
|
+
AliasedKeyModel.where(:badkey => "whee!").criteria_hash.keys.should == [:badkey]
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should serialize to JSON with full keys" do
|
238
|
+
AliasedKeyModel.first.as_json.tap do |json|
|
239
|
+
json.should have_key "foo"
|
240
|
+
json.should_not have_key "f"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "given field which are not valid Ruby method names" do
|
246
|
+
before { AliasedKeyModel.create(:with_underscores => "foobar") }
|
247
|
+
it "should work" do
|
248
|
+
AliasedKeyModel.first.with_underscores.should == "foobar"
|
249
|
+
AliasedKeyModel.collection.find_one["with-hyphens"].should == "foobar"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context "given a field aliased with :field_name" do
|
254
|
+
before { AliasedKeyModel.create(:field_name => "foobar") }
|
255
|
+
it "should work" do
|
256
|
+
AliasedKeyModel.first.field_name.should == "foobar"
|
257
|
+
AliasedKeyModel.collection.find_one["alternate_field_name"].should == "foobar"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
context "associations" do
|
262
|
+
AssociatedKeyWithAlias = Doc do
|
263
|
+
set_collection_name "associated_documents"
|
264
|
+
key :name, String, :abbr => :n
|
265
|
+
key :association_id, ObjectId, :abbr => :aid
|
266
|
+
end
|
267
|
+
|
268
|
+
OwnerDocWithKeyAliases = Doc do
|
269
|
+
set_collection_name "owner_documents"
|
270
|
+
key :name, String, :abbr => :n
|
271
|
+
many :associated_documents, :class_name => "AssociatedKeyWithAlias", :foreign_key => AssociatedKeyWithAlias.abbr(:association_id)
|
272
|
+
many :other_documents, :class_name => "EmbeddedDocWithAliases"
|
273
|
+
end
|
274
|
+
|
275
|
+
EmbeddedDocWithAliases = EDoc do
|
276
|
+
key :embedded_name, String, :abbr => :en
|
277
|
+
end
|
278
|
+
|
279
|
+
before do
|
280
|
+
AssociatedKeyWithAlias.collection.drop
|
281
|
+
OwnerDocWithKeyAliases.collection.drop
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should work" do
|
285
|
+
owner = OwnerDocWithKeyAliases.create(:name => "Big Boss")
|
286
|
+
|
287
|
+
associated_documents = 3.times.map {|i| AssociatedKeyWithAlias.new(:name => "Associated Record #{i}") }
|
288
|
+
owner.associated_documents = associated_documents
|
289
|
+
owner.save
|
290
|
+
|
291
|
+
owner.reload
|
292
|
+
owner.associated_documents.to_a.should =~ associated_documents.to_a
|
293
|
+
|
294
|
+
AssociatedKeyWithAlias.collection.find_one.keys.should =~ %w(_id n aid)
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should work with embedded documents" do
|
298
|
+
owner = OwnerDocWithKeyAliases.create(:name => "Big Boss")
|
299
|
+
owner.other_documents << EmbeddedDocWithAliases.new(:embedded_name => "Underling")
|
300
|
+
owner.save
|
301
|
+
|
302
|
+
owner.reload
|
303
|
+
owner.other_documents[0].embedded_name.should == "Underling"
|
304
|
+
owner.collection.find_one["other_documents"][0]["en"].should == "Underling"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe "removing keys" do
|
310
|
+
DocWithRemovedKey = Doc do
|
311
|
+
key :something
|
312
|
+
validates_uniqueness_of :something
|
313
|
+
remove_key :something
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'should remove the key' do
|
317
|
+
DocWithRemovedKey.keys.should_not have_key "_something"
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'should remove validations' do
|
321
|
+
DocWithRemovedKey._validate_callbacks.should be_empty
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
describe "removing keys in the presence of a validation method" do
|
326
|
+
DocWithRemovedValidator = Doc do
|
327
|
+
key :something
|
328
|
+
validate :something_valid?
|
329
|
+
remove_key :something
|
330
|
+
|
331
|
+
def something_valid?; true; end
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'should remove the key' do
|
335
|
+
DocWithRemovedKey.keys.should_not have_key "_something"
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Logger" do
|
4
|
+
context "with connection that has logger" do
|
5
|
+
before do
|
6
|
+
@output = StringIO.new
|
7
|
+
@logger = Logger.new(@output)
|
8
|
+
MarkLogic.logger = @logger
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to get access to that logger" do
|
12
|
+
MarkMapper.logger.should == @logger
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to log messages" do
|
16
|
+
MarkMapper.logger.debug 'testing'
|
17
|
+
@output.string.include?('testing').should be_truthy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,446 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Modifiers
|
4
|
+
describe "Modifiers" do
|
5
|
+
let(:page_class_with_compound_key) {
|
6
|
+
Doc do
|
7
|
+
key :_id, Hash, :default => lambda { { 'n' => 42, 'i' => MarkLogic::ObjectId.new } }
|
8
|
+
key :title, String
|
9
|
+
key :day_count, Integer, :default => 0
|
10
|
+
key :week_count, Integer, :default => 0
|
11
|
+
key :month_count, Integer, :default => 0
|
12
|
+
key :tags, Array
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
let(:page_class_with_standard_key) {
|
17
|
+
Doc do
|
18
|
+
key :title, String
|
19
|
+
key :day_count, Integer, :default => 0
|
20
|
+
key :week_count, Integer, :default => 0
|
21
|
+
key :month_count, Integer, :default => 0
|
22
|
+
key :tags, Array
|
23
|
+
end
|
24
|
+
}
|
25
|
+
|
26
|
+
def assert_page_counts(page, day_count, week_count, month_count)
|
27
|
+
doc = page.collection.find_one(:_id => page.id)
|
28
|
+
doc.should be_present, "Could not find document"
|
29
|
+
doc.fetch('day_count').should == day_count
|
30
|
+
doc.fetch('week_count').should == week_count
|
31
|
+
doc.fetch('month_count').should == month_count
|
32
|
+
end
|
33
|
+
|
34
|
+
def assert_keys_removed(page, *keys)
|
35
|
+
page.class.collection.find_one(:_id => page.id).tap do |doc|
|
36
|
+
doc.should be_present, "Could not find document"
|
37
|
+
(doc.keys & keys).should be_empty, "Expected to not have keys #{keys.inspect}, got #{(keys & doc.keys).inspect}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "ClassMethods" do
|
42
|
+
let!(:page_class) { page_class_with_standard_key }
|
43
|
+
let!(:page) { page_class.create(:title => 'Home') }
|
44
|
+
let!(:page2) { page_class.create(:title => 'Home') }
|
45
|
+
|
46
|
+
context "unset" do
|
47
|
+
let!(:page) { page_class.create(:title => 'Home', :tags => %w(foo bar)) }
|
48
|
+
|
49
|
+
it "should work with criteria and keys" do
|
50
|
+
page_class.unset({:title => 'Home'}, :title, :tags)
|
51
|
+
assert_keys_removed page, :title, :tags
|
52
|
+
assert_keys_removed page2, :title, :tags
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should work with ids and keys" do
|
56
|
+
page_class.unset(page.id, page2.id, :title, :tags)
|
57
|
+
assert_keys_removed page, :title, :tags
|
58
|
+
assert_keys_removed page2, :title, :tags
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "increment" do
|
63
|
+
it "should work with criteria and modifier hashes" do
|
64
|
+
page_class.increment({:title => 'Home'}, :day_count => 1, :week_count => 2, :month_count => 3)
|
65
|
+
|
66
|
+
assert_page_counts page, 1, 2, 3
|
67
|
+
assert_page_counts page2, 1, 2, 3
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should work with ids and modifier hash" do
|
71
|
+
page_class.increment(page.id, page2.id, :day_count => 1, :week_count => 2, :month_count => 3)
|
72
|
+
|
73
|
+
assert_page_counts page, 1, 2, 3
|
74
|
+
assert_page_counts page2, 1, 2, 3
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should work with ids given as strings" do
|
78
|
+
page_class.increment(page.id.to_s, page2.id.to_s, :day_count => 1, :week_count => 2, :month_count => 3)
|
79
|
+
|
80
|
+
assert_page_counts page, 1, 2, 3
|
81
|
+
assert_page_counts page2, 1, 2, 3
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "decrement" do
|
86
|
+
let!(:page) { page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3) }
|
87
|
+
let!(:page2) { page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3) }
|
88
|
+
|
89
|
+
it "should work with criteria and modifier hashes" do
|
90
|
+
page_class.decrement({:title => 'Home'}, :day_count => 1, :week_count => 2, :month_count => 3)
|
91
|
+
|
92
|
+
assert_page_counts page, 0, 0, 0
|
93
|
+
assert_page_counts page2, 0, 0, 0
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should work with ids and modifier hash" do
|
97
|
+
page_class.decrement(page.id, page2.id, :day_count => 1, :week_count => 2, :month_count => 3)
|
98
|
+
|
99
|
+
assert_page_counts page, 0, 0, 0
|
100
|
+
assert_page_counts page2, 0, 0, 0
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should decrement with positive or negative numbers" do
|
104
|
+
page_class.decrement(page.id, page2.id, :day_count => -1, :week_count => 2, :month_count => -3)
|
105
|
+
|
106
|
+
assert_page_counts page, 0, 0, 0
|
107
|
+
assert_page_counts page2, 0, 0, 0
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should work with ids given as strings" do
|
111
|
+
page_class.decrement(page.id.to_s, page2.id.to_s, :day_count => -1, :week_count => 2, :month_count => -3)
|
112
|
+
|
113
|
+
assert_page_counts page, 0, 0, 0
|
114
|
+
assert_page_counts page2, 0, 0, 0
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "set" do
|
119
|
+
it "should work with criteria and modifier hashes" do
|
120
|
+
page_class.set({:title => 'Home'}, :title => 'Home Revised')
|
121
|
+
|
122
|
+
page.reload
|
123
|
+
page.title.should == 'Home Revised'
|
124
|
+
|
125
|
+
page2.reload
|
126
|
+
page2.title.should == 'Home Revised'
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should work with ids and modifier hash" do
|
130
|
+
page_class.set(page.id, page2.id, :title => 'Home Revised')
|
131
|
+
|
132
|
+
page.reload
|
133
|
+
page.title.should == 'Home Revised'
|
134
|
+
|
135
|
+
page2.reload
|
136
|
+
page2.title.should == 'Home Revised'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should typecast values before querying" do
|
140
|
+
page_class.key :tags, Set
|
141
|
+
|
142
|
+
expect {
|
143
|
+
page_class.set(page.id, :tags => ['foo', 'bar'].to_set)
|
144
|
+
page.reload
|
145
|
+
page.tags.should == Set.new(['foo', 'bar'])
|
146
|
+
}.to_not raise_error
|
147
|
+
end
|
148
|
+
|
149
|
+
# it "should not typecast keys that are not defined in document" do
|
150
|
+
# expect {
|
151
|
+
# page_class.set(page.id, :colors => ['red', 'green'].to_set)
|
152
|
+
# }.to raise_error(BSON::InvalidDocument)
|
153
|
+
# end
|
154
|
+
|
155
|
+
it "should set keys that are not defined in document" do
|
156
|
+
page_class.set(page.id, :colors => %w[red green])
|
157
|
+
page.reload
|
158
|
+
page[:colors].should == %w[red green]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "push" do
|
163
|
+
it "should work with criteria and modifier hashes" do
|
164
|
+
page_class.push({:title => 'Home'}, :tags => 'foo')
|
165
|
+
|
166
|
+
page.reload
|
167
|
+
page.tags.should == %w(foo)
|
168
|
+
|
169
|
+
page2.reload
|
170
|
+
page2.tags.should == %w(foo)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should work with ids and modifier hash" do
|
174
|
+
page_class.push(page.id, page2.id, :tags => 'foo')
|
175
|
+
|
176
|
+
page.reload
|
177
|
+
page.tags.should == %w(foo)
|
178
|
+
|
179
|
+
page2.reload
|
180
|
+
page2.tags.should == %w(foo)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "push_all" do
|
185
|
+
let(:tags) { %w(foo bar) }
|
186
|
+
|
187
|
+
it "should work with criteria and modifier hashes" do
|
188
|
+
page_class.push_all({:title => 'Home'}, :tags => tags)
|
189
|
+
|
190
|
+
page.reload
|
191
|
+
page.tags.should == tags
|
192
|
+
|
193
|
+
page2.reload
|
194
|
+
page2.tags.should == tags
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should work with ids and modifier hash" do
|
198
|
+
page_class.push_all(page.id, page2.id, :tags => tags)
|
199
|
+
|
200
|
+
page.reload
|
201
|
+
page.tags.should == tags
|
202
|
+
|
203
|
+
page2.reload
|
204
|
+
page2.tags.should == tags
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# context "pull" do
|
209
|
+
# let(:page) { page_class.create(:title => 'Home', :tags => %w(foo bar)) }
|
210
|
+
# let(:page2) { page_class.create(:title => 'Home', :tags => %w(foo bar)) }
|
211
|
+
|
212
|
+
# it "should work with criteria and modifier hashes" do
|
213
|
+
# page_class.pull({:title => 'Home'}, :tags => 'foo')
|
214
|
+
|
215
|
+
# page.reload
|
216
|
+
# page.tags.should == %w(bar)
|
217
|
+
|
218
|
+
# page2.reload
|
219
|
+
# page2.tags.should == %w(bar)
|
220
|
+
# end
|
221
|
+
|
222
|
+
# it "should be able to pull with ids and modifier hash" do
|
223
|
+
# page_class.pull(page.id, page2.id, :tags => 'foo')
|
224
|
+
|
225
|
+
# page.reload
|
226
|
+
# page.tags.should == %w(bar)
|
227
|
+
|
228
|
+
# page2.reload
|
229
|
+
# page2.tags.should == %w(bar)
|
230
|
+
# end
|
231
|
+
# end
|
232
|
+
|
233
|
+
# context "pull_all" do
|
234
|
+
# let(:page) { page_class.create(:title => 'Home', :tags => %w(foo bar baz)) }
|
235
|
+
# let(:page2) { page_class.create(:title => 'Home', :tags => %w(foo bar baz)) }
|
236
|
+
|
237
|
+
# it "should work with criteria and modifier hashes" do
|
238
|
+
# page_class.pull_all({:title => 'Home'}, :tags => %w(foo bar))
|
239
|
+
|
240
|
+
# page.reload
|
241
|
+
# page.tags.should == %w(baz)
|
242
|
+
|
243
|
+
# page2.reload
|
244
|
+
# page2.tags.should == %w(baz)
|
245
|
+
# end
|
246
|
+
|
247
|
+
# it "should work with ids and modifier hash" do
|
248
|
+
# page_class.pull_all(page.id, page2.id, :tags => %w(foo bar))
|
249
|
+
|
250
|
+
# page.reload
|
251
|
+
# page.tags.should == %w(baz)
|
252
|
+
|
253
|
+
# page2.reload
|
254
|
+
# page2.tags.should == %w(baz)
|
255
|
+
# end
|
256
|
+
# end
|
257
|
+
|
258
|
+
# context "add_to_set" do
|
259
|
+
# let(:page) { page_class.create(:title => 'Home', :tags => 'foo') }
|
260
|
+
|
261
|
+
# it "should be able to add to set with criteria and modifier hash" do
|
262
|
+
# page_class.add_to_set({:title => 'Home'}, :tags => 'foo')
|
263
|
+
|
264
|
+
# page.reload
|
265
|
+
# page.tags.should == %w(foo)
|
266
|
+
|
267
|
+
# page2.reload
|
268
|
+
# page2.tags.should == %w(foo)
|
269
|
+
# end
|
270
|
+
|
271
|
+
# it "should be able to add to set with ids and modifier hash" do
|
272
|
+
# page_class.add_to_set(page.id, page2.id, :tags => 'foo')
|
273
|
+
|
274
|
+
# page.reload
|
275
|
+
# page.tags.should == %w(foo)
|
276
|
+
|
277
|
+
# page2.reload
|
278
|
+
# page2.tags.should == %w(foo)
|
279
|
+
# end
|
280
|
+
# end
|
281
|
+
|
282
|
+
# context "push_uniq" do
|
283
|
+
# let(:page) { page_class.create(:title => 'Home', :tags => 'foo') }
|
284
|
+
|
285
|
+
# it "should be able to push uniq with criteria and modifier hash" do
|
286
|
+
# page_class.push_uniq({:title => 'Home'}, :tags => 'foo')
|
287
|
+
|
288
|
+
# page.reload
|
289
|
+
# page.tags.should == %w(foo)
|
290
|
+
|
291
|
+
# page2.reload
|
292
|
+
# page2.tags.should == %w(foo)
|
293
|
+
# end
|
294
|
+
|
295
|
+
# it "should be able to push uniq with ids and modifier hash" do
|
296
|
+
# page_class.push_uniq(page.id, page2.id, :tags => 'foo')
|
297
|
+
|
298
|
+
# page.reload
|
299
|
+
# page.tags.should == %w(foo)
|
300
|
+
|
301
|
+
# page2.reload
|
302
|
+
# page2.tags.should == %w(foo)
|
303
|
+
# end
|
304
|
+
# end
|
305
|
+
|
306
|
+
# context "pop" do
|
307
|
+
# let(:page) { page_class.create(:title => 'Home', :tags => %w(foo bar)) }
|
308
|
+
|
309
|
+
# it "should be able to remove the last element the array" do
|
310
|
+
# page_class.pop(page.id, :tags => 1)
|
311
|
+
# page.reload
|
312
|
+
# page.tags.should == %w(foo)
|
313
|
+
# end
|
314
|
+
|
315
|
+
# it "should be able to remove the first element of the array" do
|
316
|
+
# page_class.pop(page.id, :tags => -1)
|
317
|
+
# page.reload
|
318
|
+
# page.tags.should == %w(bar)
|
319
|
+
# end
|
320
|
+
# end
|
321
|
+
end
|
322
|
+
|
323
|
+
context "compound keys" do
|
324
|
+
it "should create a document" do
|
325
|
+
expect {
|
326
|
+
page_class_with_compound_key.create(:title => 'Foo', :tags => %w(foo))
|
327
|
+
}.to change { page_class_with_compound_key.count }.by(1)
|
328
|
+
doc = page_class_with_compound_key.first
|
329
|
+
page_class_with_compound_key.find(doc._id).should == doc
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context "instance methods" do
|
334
|
+
{
|
335
|
+
:page_class_with_standard_key => "with standard key",
|
336
|
+
:page_class_with_compound_key => "with compound key",
|
337
|
+
}.each do |klass, description|
|
338
|
+
context description do
|
339
|
+
let!(:page_class) { send(klass) }
|
340
|
+
|
341
|
+
it "should be able to unset with keys" do
|
342
|
+
page = page_class.create(:title => 'Foo', :tags => %w(foo))
|
343
|
+
page.unset(:title, :tags)
|
344
|
+
assert_keys_removed page, :title, :tags
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should be able to increment with modifier hashes" do
|
348
|
+
page = page_class.create
|
349
|
+
page.increment(:day_count => 1, :week_count => 2, :month_count => 3)
|
350
|
+
|
351
|
+
assert_page_counts page, 1, 2, 3
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should be able to decrement with modifier hashes" do
|
355
|
+
page = page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
|
356
|
+
page.decrement(:day_count => 1, :week_count => 2, :month_count => 3)
|
357
|
+
|
358
|
+
assert_page_counts page, 0, 0, 0
|
359
|
+
end
|
360
|
+
|
361
|
+
it "should always decrement when decrement is called whether number is positive or negative" do
|
362
|
+
page = page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
|
363
|
+
page.decrement(:day_count => -1, :week_count => 2, :month_count => -3)
|
364
|
+
assert_page_counts page, 0, 0, 0
|
365
|
+
end
|
366
|
+
|
367
|
+
it "should be able to set with modifier hashes" do
|
368
|
+
page = page_class.create(:title => 'Home')
|
369
|
+
page.set(:title => 'Home Revised')
|
370
|
+
|
371
|
+
page.reload
|
372
|
+
page.title.should == 'Home Revised'
|
373
|
+
end
|
374
|
+
|
375
|
+
it "should be able to push with modifier hashes" do
|
376
|
+
page = page_class.create
|
377
|
+
page.push(:tags => 'foo')
|
378
|
+
|
379
|
+
page.reload
|
380
|
+
page.tags.should == %w(foo)
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should be able to push_all with modifier hashes" do
|
384
|
+
page = page_class.create
|
385
|
+
page.push_all(:tags => %w(foo bar))
|
386
|
+
|
387
|
+
page.reload
|
388
|
+
page.tags.should == %w(foo bar)
|
389
|
+
end
|
390
|
+
|
391
|
+
# it "should be able to pull with criteria and modifier hashes" do
|
392
|
+
# page = page_class.create(:tags => %w(foo bar))
|
393
|
+
# page.pull(:tags => 'foo')
|
394
|
+
|
395
|
+
# page.reload
|
396
|
+
# page.tags.should == %w(bar)
|
397
|
+
# end
|
398
|
+
|
399
|
+
# it "should be able to pull_all with criteria and modifier hashes" do
|
400
|
+
# page = page_class.create(:tags => %w(foo bar baz))
|
401
|
+
# page.pull_all(:tags => %w(foo bar))
|
402
|
+
|
403
|
+
# page.reload
|
404
|
+
# page.tags.should == %w(baz)
|
405
|
+
# end
|
406
|
+
|
407
|
+
# it "should be able to add_to_set with criteria and modifier hash" do
|
408
|
+
# page = page_class.create(:tags => 'foo')
|
409
|
+
# page2 = page_class.create
|
410
|
+
|
411
|
+
# page.add_to_set(:tags => 'foo')
|
412
|
+
# page2.add_to_set(:tags => 'foo')
|
413
|
+
|
414
|
+
# page.reload
|
415
|
+
# page.tags.should == %w(foo)
|
416
|
+
|
417
|
+
# page2.reload
|
418
|
+
# page2.tags.should == %w(foo)
|
419
|
+
# end
|
420
|
+
|
421
|
+
# it "should be able to push uniq with criteria and modifier hash" do
|
422
|
+
# page = page_class.create(:tags => 'foo')
|
423
|
+
# page2 = page_class.create
|
424
|
+
|
425
|
+
# page.push_uniq(:tags => 'foo')
|
426
|
+
# page2.push_uniq(:tags => 'foo')
|
427
|
+
|
428
|
+
# page.reload
|
429
|
+
# page.tags.should == %w(foo)
|
430
|
+
|
431
|
+
# page2.reload
|
432
|
+
# page2.tags.should == %w(foo)
|
433
|
+
# end
|
434
|
+
|
435
|
+
# it "should be able to pop with modifier hashes" do
|
436
|
+
# page = page_class.create(:tags => %w(foo bar))
|
437
|
+
# page.pop(:tags => 1)
|
438
|
+
|
439
|
+
# page.reload
|
440
|
+
# page.tags.should == %w(foo)
|
441
|
+
# end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|