mongoid_monkey 0.1.3 → 0.1.4
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 +4 -4
- data/lib/patches/atomic.rb +225 -1
- data/lib/version.rb +1 -1
- data/spec/app/models/address.rb +17 -0
- data/spec/app/models/name.rb +14 -0
- data/spec/app/models/person.rb +39 -0
- data/spec/unit/{atomic_spec.rb → atomic/atomic_contextual_spec.rb} +0 -0
- data/spec/unit/atomic/mongoid3_style/atomic/add_to_set_spec.rb +266 -0
- data/spec/unit/atomic/mongoid3_style/atomic/bit_spec.rb +92 -0
- data/spec/unit/atomic/mongoid3_style/atomic/inc_spec.rb +137 -0
- data/spec/unit/atomic/mongoid3_style/atomic/pop_spec.rb +115 -0
- data/spec/unit/atomic/mongoid3_style/atomic/pull_all_spec.rb +81 -0
- data/spec/unit/atomic/mongoid3_style/atomic/pull_spec.rb +84 -0
- data/spec/unit/atomic/mongoid3_style/atomic/push_all_spec.rb +81 -0
- data/spec/unit/atomic/mongoid3_style/atomic/push_spec.rb +81 -0
- data/spec/unit/atomic/mongoid3_style/atomic/rename_spec.rb +46 -0
- data/spec/unit/atomic/mongoid3_style/atomic/sets_spec.rb +158 -0
- data/spec/unit/atomic/mongoid3_style/atomic/unset_spec.rb +69 -0
- data/spec/unit/atomic/mongoid3_style/atomic_spec.rb +220 -0
- data/spec/unit/atomic/mongoid4_style/incrementable_spec.rb +232 -0
- data/spec/unit/atomic/mongoid4_style/logical_spec.rb +262 -0
- data/spec/unit/atomic/mongoid4_style/poppable_spec.rb +139 -0
- data/spec/unit/atomic/mongoid4_style/pullable_spec.rb +172 -0
- data/spec/unit/atomic/mongoid4_style/pushable_spec.rb +159 -0
- data/spec/unit/atomic/mongoid4_style/renamable_spec.rb +139 -0
- data/spec/unit/atomic/mongoid4_style/settable_spec.rb +172 -0
- data/spec/unit/atomic/mongoid4_style/unsettable_spec.rb +28 -0
- metadata +46 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 214e7694779c183b25d31b4a3acd022b6d197883
|
4
|
+
data.tar.gz: ba65a452be5ef5778673fb790872ad7e879e368e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c3906fb7a21840e4e1688bc1f9f9bcbfa608d3083533d52b87cb8caf31783dfe6aea1ae462b85c6908cb9d9b05ec35cd5e04e6d83e2e0750dbcb2f231d96c1b
|
7
|
+
data.tar.gz: 9c0dc36cb5537f059791b16d43ba2dd5fb3337d3597e3dfc4600c469d3717166a6761a5d8a335731dae3e6810340aad0e7a1b51bea69136af6a78bbab17d1864
|
data/lib/patches/atomic.rb
CHANGED
@@ -111,4 +111,228 @@ module Atomic
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
|
+
module Mongoid
|
116
|
+
module Persistence
|
117
|
+
module Atomic
|
118
|
+
|
119
|
+
# push_all is deprecated so not supported
|
120
|
+
|
121
|
+
def add_to_set_with_mongoid4(*args)
|
122
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
123
|
+
adds = args.first
|
124
|
+
prepare_atomic_operation do |ops|
|
125
|
+
process_atomic_operations(adds) do |field, value|
|
126
|
+
existing = send(field) || (attributes[field] ||= [])
|
127
|
+
values = [ value ].flatten(1)
|
128
|
+
values.each do |val|
|
129
|
+
existing.push(val) unless existing.include?(val)
|
130
|
+
end
|
131
|
+
ops[atomic_attribute_name(field)] = { "$each" => values }
|
132
|
+
end
|
133
|
+
{ "$addToSet" => ops }
|
134
|
+
end
|
135
|
+
else
|
136
|
+
add_to_set_without_mongoid4(*args)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
alias_method_chain :add_to_set, :mongoid4
|
140
|
+
|
141
|
+
def bit_with_mongoid4(*args)
|
142
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
143
|
+
operations = args.first
|
144
|
+
prepare_atomic_operation do |ops|
|
145
|
+
process_atomic_operations(operations) do |field, values|
|
146
|
+
value = attributes[field]
|
147
|
+
values.each do |op, val|
|
148
|
+
value = value & val if op.to_s == "and"
|
149
|
+
value = value | val if op.to_s == "or"
|
150
|
+
end
|
151
|
+
attributes[field] = value
|
152
|
+
ops[atomic_attribute_name(field)] = values
|
153
|
+
end
|
154
|
+
{ "$bit" => ops }
|
155
|
+
end
|
156
|
+
else
|
157
|
+
bit_without_mongoid4(*args)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
alias_method_chain :bit, :mongoid4
|
161
|
+
|
162
|
+
def inc_with_mongoid4(*args)
|
163
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
164
|
+
increments = args.first
|
165
|
+
prepare_atomic_operation do |ops|
|
166
|
+
process_atomic_operations(increments) do |field, value|
|
167
|
+
increment = value.__to_inc__
|
168
|
+
current = attributes[field]
|
169
|
+
attributes[field] = (current || 0) + increment
|
170
|
+
ops[atomic_attribute_name(field)] = increment
|
171
|
+
end
|
172
|
+
{ "$inc" => ops }
|
173
|
+
end
|
174
|
+
else
|
175
|
+
inc_without_mongoid4(*args)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
alias_method_chain :inc, :mongoid4
|
179
|
+
|
180
|
+
def pop_with_mongoid4(*args)
|
181
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
182
|
+
pops = args.first
|
183
|
+
prepare_atomic_operation do |ops|
|
184
|
+
process_atomic_operations(pops) do |field, value|
|
185
|
+
values = send(field)
|
186
|
+
value > 0 ? values.pop : values.shift
|
187
|
+
ops[atomic_attribute_name(field)] = value
|
188
|
+
end
|
189
|
+
{ "$pop" => ops }
|
190
|
+
end
|
191
|
+
else
|
192
|
+
pop_without_mongoid4(*args)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
alias_method_chain :pop, :mongoid4
|
196
|
+
|
197
|
+
def pull_with_mongoid4(*args)
|
198
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
199
|
+
pulls = args.first
|
200
|
+
prepare_atomic_operation do |ops|
|
201
|
+
process_atomic_operations(pulls) do |field, value|
|
202
|
+
(send(field) || []).delete(value)
|
203
|
+
ops[atomic_attribute_name(field)] = value
|
204
|
+
end
|
205
|
+
{ "$pull" => ops }
|
206
|
+
end
|
207
|
+
else
|
208
|
+
pull_without_mongoid4(*args)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
alias_method_chain :pull, :mongoid4
|
212
|
+
|
213
|
+
def pull_all_with_mongoid4(*args)
|
214
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
215
|
+
pulls = args.first
|
216
|
+
prepare_atomic_operation do |ops|
|
217
|
+
process_atomic_operations(pulls) do |field, value|
|
218
|
+
existing = send(field) || []
|
219
|
+
value.each{ |val| existing.delete(val) }
|
220
|
+
ops[atomic_attribute_name(field)] = value
|
221
|
+
end
|
222
|
+
{ "$pullAll" => ops }
|
223
|
+
end
|
224
|
+
else
|
225
|
+
pull_all_without_mongoid4(*args)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
alias_method_chain :pull_all, :mongoid4
|
229
|
+
|
230
|
+
def push_with_mongoid4(*args)
|
231
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
232
|
+
pushes = args.first
|
233
|
+
prepare_atomic_operation do |ops|
|
234
|
+
process_atomic_operations(pushes) do |field, value|
|
235
|
+
existing = send(field) || (attributes[field] ||= [])
|
236
|
+
values = [ value ].flatten(1)
|
237
|
+
values.each{ |val| existing.push(val) }
|
238
|
+
ops[atomic_attribute_name(field)] = { "$each" => values }
|
239
|
+
end
|
240
|
+
{ "$push" => ops }
|
241
|
+
end
|
242
|
+
else
|
243
|
+
push_without_mongoid4(*args)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
alias_method_chain :push, :mongoid4
|
247
|
+
|
248
|
+
def rename_with_mongoid4(*args)
|
249
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
250
|
+
renames = args.first
|
251
|
+
prepare_atomic_operation do |ops|
|
252
|
+
process_atomic_operations(renames) do |old_field, new_field|
|
253
|
+
new_name = new_field.to_s
|
254
|
+
attributes[new_name] = attributes.delete(old_field)
|
255
|
+
ops[atomic_attribute_name(old_field)] = atomic_attribute_name(new_name)
|
256
|
+
end
|
257
|
+
{ "$rename" => ops }
|
258
|
+
end
|
259
|
+
else
|
260
|
+
rename_without_mongoid4(*args)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
alias_method_chain :rename, :mongoid4
|
264
|
+
|
265
|
+
def set_with_mongoid4(*args)
|
266
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
267
|
+
setters = args.first
|
268
|
+
prepare_atomic_operation do |ops|
|
269
|
+
process_atomic_operations(setters) do |field, value|
|
270
|
+
process_attribute(field.to_s, value)
|
271
|
+
ops[atomic_attribute_name(field)] = attributes[field]
|
272
|
+
end
|
273
|
+
{ "$set" => ops }
|
274
|
+
end
|
275
|
+
else
|
276
|
+
set_without_mongoid4(*args)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
alias_method_chain :set, :mongoid4
|
280
|
+
|
281
|
+
# unset params are consistent, however it returns self in Mongoid 4
|
282
|
+
# def unset_with_mongoid4(*args)
|
283
|
+
# unset_without_mongoid4(*args)
|
284
|
+
# self
|
285
|
+
# end
|
286
|
+
# alias_method_chain :unset, :mongoid4
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def executing_atomically?
|
291
|
+
!@atomic_updates_to_execute.nil?
|
292
|
+
end
|
293
|
+
|
294
|
+
def post_process_persist(result, options = {})
|
295
|
+
post_persist unless result == false
|
296
|
+
errors.clear unless performing_validations?(options)
|
297
|
+
true
|
298
|
+
end
|
299
|
+
|
300
|
+
def prepare_atomic_operation
|
301
|
+
operations = yield({})
|
302
|
+
persist_or_delay_atomic_operation(operations)
|
303
|
+
self
|
304
|
+
end
|
305
|
+
|
306
|
+
def process_atomic_operations(operations)
|
307
|
+
operations.each do |field, value|
|
308
|
+
unless attribute_writable?(field)
|
309
|
+
raise Errors::ReadonlyAttribute.new(field, value)
|
310
|
+
end
|
311
|
+
normalized = database_field_name(field)
|
312
|
+
yield(normalized, value)
|
313
|
+
remove_change(normalized)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def persist_or_delay_atomic_operation(operation)
|
318
|
+
if executing_atomically?
|
319
|
+
operation.each do |(name, hash)|
|
320
|
+
@atomic_updates_to_execute[name] ||= {}
|
321
|
+
@atomic_updates_to_execute[name].merge!(hash)
|
322
|
+
end
|
323
|
+
else
|
324
|
+
persist_atomic_operations(operation)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def persist_atomic_operations(operations)
|
329
|
+
if persisted?
|
330
|
+
selector = atomic_selector
|
331
|
+
_root.collection.find(selector).update(operations)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
data/lib/version.rb
CHANGED
data/spec/app/models/address.rb
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
|
2
2
|
class Address
|
3
3
|
include Mongoid::Document
|
4
|
+
field :address_type
|
5
|
+
field :number, type: Integer
|
6
|
+
field :no, type: Integer
|
7
|
+
field :h, as: :house, type: Integer
|
4
8
|
field :street
|
9
|
+
field :city
|
10
|
+
field :state
|
11
|
+
field :post_code
|
12
|
+
field :parent_title
|
13
|
+
field :services, type: Array
|
14
|
+
field :aliases, as: :a, type: Array
|
15
|
+
field :test, type: Array
|
16
|
+
field :latlng, type: Array
|
17
|
+
field :map, type: Hash
|
18
|
+
field :move_in, type: DateTime
|
19
|
+
field :end_date, type: Date
|
20
|
+
field :s, type: String, as: :suite
|
5
21
|
field :name, localize: true
|
22
|
+
|
6
23
|
embedded_in :addressable, polymorphic: true
|
7
24
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Name
|
2
|
+
include Mongoid::Document
|
3
|
+
|
4
|
+
field :first_name, type: String
|
5
|
+
field :last_name, type: String
|
6
|
+
field :parent_title, type: String
|
7
|
+
field :middle, type: String
|
8
|
+
|
9
|
+
embedded_in :namable, polymorphic: true
|
10
|
+
|
11
|
+
def set_parent=(set = false)
|
12
|
+
self.parent_title = namable.title if set
|
13
|
+
end
|
14
|
+
end
|
data/spec/app/models/person.rb
CHANGED
@@ -8,4 +8,43 @@ class Person
|
|
8
8
|
index name: 1
|
9
9
|
index title: 1
|
10
10
|
index({ ssn: 1 }, { unique: true })
|
11
|
+
field :username, default: -> { "arthurnn#{rand(0..10)}" }
|
12
|
+
field :title
|
13
|
+
field :terms, type: Boolean
|
14
|
+
field :pets, type: Boolean, default: false
|
15
|
+
field :age, type: Integer, default: "100"
|
16
|
+
field :dob, type: Date
|
17
|
+
field :employer_id
|
18
|
+
field :lunch_time, type: Time
|
19
|
+
field :aliases, type: Array
|
20
|
+
field :map, type: Hash
|
21
|
+
field :map_with_default, type: Hash, default: {}
|
22
|
+
field :score, type: Integer
|
23
|
+
field :blood_alcohol_content, type: Float, default: ->{ 0.0 }
|
24
|
+
field :last_drink_taken_at, type: Date, default: ->{ 1.day.ago.in_time_zone("Alaska") }
|
25
|
+
field :ssn
|
26
|
+
field :owner_id, type: Integer
|
27
|
+
field :security_code
|
28
|
+
field :reading, type: Object
|
29
|
+
field :pattern, type: Regexp
|
30
|
+
field :override_me, type: Integer
|
31
|
+
field :at, as: :aliased_timestamp, type: Time
|
32
|
+
field :t, as: :test, type: String
|
33
|
+
field :i, as: :inte, type: Integer
|
34
|
+
field :a, as: :array, type: Array
|
35
|
+
field :desc, localize: true
|
36
|
+
field :test_array, type: Array
|
37
|
+
field :overridden_setter, type: String
|
38
|
+
field :arrays, type: Array
|
39
|
+
field :range, type: Range
|
40
|
+
|
41
|
+
embeds_many :addresses, as: :addressable, validate: false
|
42
|
+
embeds_one :name, as: :namable, validate: false do
|
43
|
+
def extension
|
44
|
+
"Testing"
|
45
|
+
end
|
46
|
+
def dawkins?
|
47
|
+
first_name == "Richard" && last_name == "Dawkins"
|
48
|
+
end
|
49
|
+
end
|
11
50
|
end
|
File without changes
|
@@ -0,0 +1,266 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
if Mongoid::VERSION =~ /\A3\./
|
4
|
+
|
5
|
+
describe Mongoid::Persistence::Atomic::AddToSet do
|
6
|
+
|
7
|
+
describe "#persist" do
|
8
|
+
|
9
|
+
context "when the document is new" do
|
10
|
+
|
11
|
+
let(:person) do
|
12
|
+
Person.new
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when adding a single value" do
|
16
|
+
|
17
|
+
let!(:added) do
|
18
|
+
person.add_to_set(:aliases, "Bond")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "adds the value onto the array" do
|
22
|
+
person.aliases.should eq([ "Bond" ])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "does not reset the dirty flagging" do
|
26
|
+
person.changes["aliases"].should eq([nil, ["Bond"]])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns the new array value" do
|
30
|
+
added.should eq([ "Bond" ])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when adding multiple values" do
|
35
|
+
|
36
|
+
let!(:added) do
|
37
|
+
person.add_to_set(:aliases, [ "Bond", "James" ])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "adds the value onto the array" do
|
41
|
+
person.aliases.should eq([ "Bond", "James" ])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "does not reset the dirty flagging" do
|
45
|
+
person.changes["aliases"].should eq([nil, ["Bond", "James"]])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the new array value" do
|
49
|
+
added.should eq([ "Bond", "James" ])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when the field exists" do
|
55
|
+
|
56
|
+
context "when the value is unique" do
|
57
|
+
|
58
|
+
let(:person) do
|
59
|
+
Person.create(aliases: [ "007" ])
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when adding a single value" do
|
63
|
+
|
64
|
+
let!(:added) do
|
65
|
+
person.add_to_set(:aliases, "Bond")
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:reloaded) do
|
69
|
+
person.reload
|
70
|
+
end
|
71
|
+
|
72
|
+
it "adds the value onto the array" do
|
73
|
+
person.aliases.should eq([ "007", "Bond" ])
|
74
|
+
end
|
75
|
+
|
76
|
+
it "persists the data" do
|
77
|
+
reloaded.aliases.should eq([ "007", "Bond" ])
|
78
|
+
end
|
79
|
+
|
80
|
+
it "removes the field from the dirty attributes" do
|
81
|
+
person.changes["aliases"].should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "resets the document dirty flag" do
|
85
|
+
person.should_not be_changed
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns the new array value" do
|
89
|
+
added.should eq([ "007", "Bond" ])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when adding a multiple values" do
|
94
|
+
|
95
|
+
let!(:added) do
|
96
|
+
person.add_to_set(:aliases, [ "Bond", "James" ])
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:reloaded) do
|
100
|
+
person.reload
|
101
|
+
end
|
102
|
+
|
103
|
+
it "adds the value onto the array" do
|
104
|
+
person.aliases.should eq([ "007", "Bond", "James" ])
|
105
|
+
end
|
106
|
+
|
107
|
+
it "persists the data" do
|
108
|
+
reloaded.aliases.should eq([ "007", "Bond", "James" ])
|
109
|
+
end
|
110
|
+
|
111
|
+
it "removes the field from the dirty attributes" do
|
112
|
+
person.changes["aliases"].should be_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "resets the document dirty flag" do
|
116
|
+
person.should_not be_changed
|
117
|
+
end
|
118
|
+
|
119
|
+
it "returns the new array value" do
|
120
|
+
added.should eq([ "007", "Bond", "James" ])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when the value is not unique" do
|
126
|
+
|
127
|
+
let(:person) do
|
128
|
+
Person.create(aliases: [ "Bond" ])
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when adding a single value" do
|
132
|
+
|
133
|
+
let!(:added) do
|
134
|
+
person.add_to_set(:aliases, "Bond")
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:reloaded) do
|
138
|
+
person.reload
|
139
|
+
end
|
140
|
+
|
141
|
+
it "does not add the value" do
|
142
|
+
person.aliases.should eq([ "Bond" ])
|
143
|
+
end
|
144
|
+
|
145
|
+
it "persists the data" do
|
146
|
+
reloaded.aliases.should eq([ "Bond" ])
|
147
|
+
end
|
148
|
+
|
149
|
+
it "removes the field from the dirty attributes" do
|
150
|
+
person.changes["aliases"].should be_nil
|
151
|
+
end
|
152
|
+
|
153
|
+
it "resets the document dirty flag" do
|
154
|
+
person.should_not be_changed
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns the array value" do
|
158
|
+
added.should eq([ "Bond" ])
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when adding multiple values" do
|
163
|
+
|
164
|
+
let!(:added) do
|
165
|
+
person.add_to_set(:aliases, [ "Bond", "James" ])
|
166
|
+
end
|
167
|
+
|
168
|
+
let(:reloaded) do
|
169
|
+
person.reload
|
170
|
+
end
|
171
|
+
|
172
|
+
it "does not add the duplicate value" do
|
173
|
+
person.aliases.should eq([ "Bond", "James" ])
|
174
|
+
end
|
175
|
+
|
176
|
+
it "persists the data" do
|
177
|
+
reloaded.aliases.should eq([ "Bond", "James" ])
|
178
|
+
end
|
179
|
+
|
180
|
+
it "removes the field from the dirty attributes" do
|
181
|
+
person.changes["aliases"].should be_nil
|
182
|
+
end
|
183
|
+
|
184
|
+
it "resets the document dirty flag" do
|
185
|
+
person.should_not be_changed
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns the array value" do
|
189
|
+
added.should eq([ "Bond", "James" ])
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "when the field does not exist" do
|
196
|
+
|
197
|
+
let(:person) do
|
198
|
+
Person.create
|
199
|
+
end
|
200
|
+
|
201
|
+
context "when adding a single value" do
|
202
|
+
|
203
|
+
let!(:added) do
|
204
|
+
person.add_to_set(:aliases, "Bond")
|
205
|
+
end
|
206
|
+
|
207
|
+
let(:reloaded) do
|
208
|
+
person.reload
|
209
|
+
end
|
210
|
+
|
211
|
+
it "adds the value onto the array" do
|
212
|
+
person.aliases.should eq([ "Bond" ])
|
213
|
+
end
|
214
|
+
|
215
|
+
it "persists the data" do
|
216
|
+
reloaded.aliases.should eq([ "Bond" ])
|
217
|
+
end
|
218
|
+
|
219
|
+
it "removes the field from the dirty attributes" do
|
220
|
+
person.changes["aliases"].should be_nil
|
221
|
+
end
|
222
|
+
|
223
|
+
it "resets the document dirty flag" do
|
224
|
+
person.should_not be_changed
|
225
|
+
end
|
226
|
+
|
227
|
+
it "returns the new array value" do
|
228
|
+
added.should eq([ "Bond" ])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "when adding multiple values" do
|
233
|
+
|
234
|
+
let!(:added) do
|
235
|
+
person.add_to_set(:aliases, [ "Bond", "James" ])
|
236
|
+
end
|
237
|
+
|
238
|
+
let(:reloaded) do
|
239
|
+
person.reload
|
240
|
+
end
|
241
|
+
|
242
|
+
it "adds the value onto the array" do
|
243
|
+
person.aliases.should eq([ "Bond", "James" ])
|
244
|
+
end
|
245
|
+
|
246
|
+
it "persists the data" do
|
247
|
+
reloaded.aliases.should eq([ "Bond", "James" ])
|
248
|
+
end
|
249
|
+
|
250
|
+
it "removes the field from the dirty attributes" do
|
251
|
+
person.changes["aliases"].should be_nil
|
252
|
+
end
|
253
|
+
|
254
|
+
it "resets the document dirty flag" do
|
255
|
+
person.should_not be_changed
|
256
|
+
end
|
257
|
+
|
258
|
+
it "returns the new array value" do
|
259
|
+
added.should eq([ "Bond", "James" ])
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
if Mongoid::VERSION =~ /\A3\./
|
4
|
+
|
5
|
+
describe Mongoid::Persistence::Atomic::Bit do
|
6
|
+
|
7
|
+
describe "#bit" do
|
8
|
+
|
9
|
+
let(:person) do
|
10
|
+
Person.create(age: 60)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:reloaded) do
|
14
|
+
person.reload
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when performing a bitwise and" do
|
18
|
+
|
19
|
+
let!(:bit) do
|
20
|
+
person.bit(:age, { and: 13 })
|
21
|
+
end
|
22
|
+
|
23
|
+
it "performs the bitwise operation" do
|
24
|
+
person.age.should eq(12)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the new value" do
|
28
|
+
bit.should eq(12)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "persists the changes" do
|
32
|
+
reloaded.age.should eq(12)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "resets the dirty attributes" do
|
36
|
+
person.changes["age"].should be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when performing a bitwise or" do
|
41
|
+
|
42
|
+
let!(:bit) do
|
43
|
+
person.bit(:age, { or: 13 })
|
44
|
+
end
|
45
|
+
|
46
|
+
it "performs the bitwise operation" do
|
47
|
+
person.age.should eq(61)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns the new value" do
|
51
|
+
bit.should eq(61)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "persists the changes" do
|
55
|
+
reloaded.age.should eq(61)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "resets the dirty attributes" do
|
59
|
+
person.changes["age"].should be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when chaining bitwise operations" do
|
64
|
+
|
65
|
+
let(:hash) do
|
66
|
+
{ and: 13, or: 10 }
|
67
|
+
end
|
68
|
+
|
69
|
+
let!(:bit) do
|
70
|
+
person.bit(:age, hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "performs the bitwise operation" do
|
74
|
+
person.age.should eq(14)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns the new value" do
|
78
|
+
bit.should eq(14)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "persists the changes" do
|
82
|
+
reloaded.age.should eq(14)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "resets the dirty attributes" do
|
86
|
+
person.changes["age"].should be_nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|