mongoid 5.0.0 → 5.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CHANGELOG.md +54 -2
- data/lib/config/locales/en.yml +1 -1
- data/lib/mongoid/attributes.rb +1 -1
- data/lib/mongoid/clients.rb +7 -4
- data/lib/mongoid/clients/options.rb +2 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +2 -1
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +4 -1
- data/lib/mongoid/contextual/mongo.rb +4 -5
- data/lib/mongoid/document.rb +1 -0
- data/lib/mongoid/indexable/specification.rb +3 -5
- data/lib/mongoid/indexable/validators/options.rb +7 -1
- data/lib/mongoid/matchable/exists.rb +1 -1
- data/lib/mongoid/persistable.rb +2 -1
- data/lib/mongoid/persistable/creatable.rb +1 -1
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/positional.rb +75 -0
- data/lib/mongoid/relations/counter_cache.rb +19 -0
- data/lib/mongoid/relations/eager/base.rb +4 -2
- data/lib/mongoid/relations/embedded/batchable.rb +10 -3
- data/lib/mongoid/relations/proxy.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +6 -5
- data/lib/mongoid/selectable.rb +36 -1
- data/lib/mongoid/threaded.rb +34 -2
- data/lib/mongoid/timestamps/created.rb +1 -2
- data/lib/mongoid/timestamps/timeless.rb +19 -2
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -1
- data/spec/app/models/account.rb +8 -0
- data/spec/app/models/answer.rb +2 -0
- data/spec/app/models/article.rb +2 -0
- data/spec/app/models/author.rb +2 -0
- data/spec/app/models/baby.rb +4 -0
- data/spec/app/models/book.rb +2 -0
- data/spec/app/models/consumption_period.rb +7 -0
- data/spec/app/models/exhibitor.rb +1 -0
- data/spec/app/models/kaleidoscope.rb +6 -0
- data/spec/app/models/kangaroo.rb +4 -0
- data/spec/app/models/note.rb +3 -0
- data/spec/app/models/page.rb +11 -0
- data/spec/app/models/simple.rb +5 -0
- data/spec/config/mongoid.yml +3 -1
- data/spec/mongoid/atomic/paths_spec.rb +17 -10
- data/spec/mongoid/attributes_spec.rb +2 -2
- data/spec/mongoid/clients/options_spec.rb +15 -0
- data/spec/mongoid/clients_spec.rb +6 -2
- data/spec/mongoid/config_spec.rb +3 -2
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +25 -2
- data/spec/mongoid/contextual/atomic_spec.rb +6 -6
- data/spec/mongoid/contextual/mongo_spec.rb +28 -75
- data/spec/mongoid/criteria_spec.rb +54 -0
- data/spec/mongoid/fields/standard_spec.rb +1 -1
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/indexable/specification_spec.rb +1 -1
- data/spec/mongoid/indexable_spec.rb +7 -7
- data/spec/mongoid/interceptable_spec.rb +55 -0
- data/spec/mongoid/persistable/creatable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +50 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +56 -4
- data/spec/mongoid/persistable/pushable_spec.rb +11 -0
- data/spec/mongoid/persistable/savable_spec.rb +20 -2
- data/spec/mongoid/positional_spec.rb +221 -0
- data/spec/mongoid/query_cache_spec.rb +19 -0
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +1 -1
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -11
- data/spec/mongoid/relations/eager/has_many_spec.rb +37 -0
- data/spec/mongoid/relations/eager_spec.rb +11 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +38 -9
- data/spec/mongoid/relations/embedded/one_spec.rb +1 -1
- data/spec/mongoid/relations/proxy_spec.rb +22 -0
- data/spec/mongoid/relations/reflections_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +160 -19
- data/spec/mongoid/selectable_spec.rb +16 -6
- data/spec/mongoid/timestamps/timeless_spec.rb +17 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +17 -0
- metadata +40 -5
- metadata.gz.sig +3 -0
@@ -170,6 +170,61 @@ describe Mongoid::Interceptable do
|
|
170
170
|
it "runs after document instantiation" do
|
171
171
|
expect(game.name).to eq("Testing")
|
172
172
|
end
|
173
|
+
|
174
|
+
context 'when the document is embedded' do
|
175
|
+
|
176
|
+
after do
|
177
|
+
Book.destroy_all
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:book) do
|
181
|
+
book = Book.new({
|
182
|
+
:pages => [
|
183
|
+
{
|
184
|
+
content: "Page 1",
|
185
|
+
notes: [
|
186
|
+
{ message: "Page 1 / Note A" },
|
187
|
+
{ message: "Page 1 / Note B" }
|
188
|
+
]
|
189
|
+
},
|
190
|
+
{
|
191
|
+
content: "Page 2",
|
192
|
+
notes: [
|
193
|
+
{ message: "Page 2 / Note A" },
|
194
|
+
{ message: "Page 2 / Note B" }
|
195
|
+
]
|
196
|
+
}
|
197
|
+
]
|
198
|
+
})
|
199
|
+
book.id = '123'
|
200
|
+
book.save
|
201
|
+
book
|
202
|
+
end
|
203
|
+
|
204
|
+
let(:new_message) do
|
205
|
+
'Note C'
|
206
|
+
end
|
207
|
+
|
208
|
+
before do
|
209
|
+
book.pages.each do | page |
|
210
|
+
page.notes.destroy_all
|
211
|
+
page.notes.new(message: new_message)
|
212
|
+
page.save
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
let(:expected_messages) do
|
217
|
+
book.reload.pages.reduce([]) do |messages, p|
|
218
|
+
messages += p.notes.reduce([]) do |msgs, n|
|
219
|
+
msgs << n.message
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'runs the callback on the embedded documents and saves the parent document' do
|
225
|
+
expect(expected_messages.all? { |m| m == new_message }).to be(true)
|
226
|
+
end
|
227
|
+
end
|
173
228
|
end
|
174
229
|
|
175
230
|
describe ".after_build" do
|
@@ -393,6 +393,25 @@ describe Mongoid::Persistable::Creatable do
|
|
393
393
|
expect(container.vehicles.size).to eq(2)
|
394
394
|
end
|
395
395
|
end
|
396
|
+
|
397
|
+
context 'when searching by a Time value' do
|
398
|
+
|
399
|
+
let!(:account) do
|
400
|
+
Account.create!(name: 'test', period_started_at: Time.now.utc)
|
401
|
+
end
|
402
|
+
|
403
|
+
let!(:queried_consumption) do
|
404
|
+
account.consumption_periods.find_or_create_by(started_at: account.period_started_at)
|
405
|
+
end
|
406
|
+
|
407
|
+
before do
|
408
|
+
account.reload
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'does not change the Time value' do
|
412
|
+
expect(queried_consumption).to eq(account.current_consumption)
|
413
|
+
end
|
414
|
+
end
|
396
415
|
end
|
397
416
|
|
398
417
|
context "#find_or_create_by!" do
|
@@ -82,6 +82,35 @@ describe Mongoid::Persistable::Destroyable do
|
|
82
82
|
expect(from_db.addresses).to be_empty
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
context 'when removing from a list of embedded documents' do
|
87
|
+
|
88
|
+
context 'when the embedded documents list is reversed in memory' do
|
89
|
+
|
90
|
+
let(:word) do
|
91
|
+
Word.create!(name: 'driver')
|
92
|
+
end
|
93
|
+
|
94
|
+
let(:from_db) do
|
95
|
+
Word.find(word.id)
|
96
|
+
end
|
97
|
+
|
98
|
+
before do
|
99
|
+
word.definitions.find_or_create_by(description: 'database connector')
|
100
|
+
word.definitions.find_or_create_by(description: 'chauffeur')
|
101
|
+
word.definitions = word.definitions.reverse
|
102
|
+
word.definitions.last.destroy
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'removes the embedded document in memory' do
|
106
|
+
expect(word.definitions.size).to eq(1)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'removes the embedded document in the database' do
|
110
|
+
expect(from_db.definitions.size).to eq(1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
85
114
|
end
|
86
115
|
|
87
116
|
context "when removing deeply embedded documents" do
|
@@ -188,5 +217,26 @@ describe Mongoid::Persistable::Destroyable do
|
|
188
217
|
end
|
189
218
|
end
|
190
219
|
end
|
220
|
+
|
221
|
+
context 'when removing a list of embedded documents' do
|
222
|
+
|
223
|
+
context 'when the embedded documents list is reversed in memory' do
|
224
|
+
|
225
|
+
let(:word) do
|
226
|
+
Word.create!(name: 'driver')
|
227
|
+
end
|
228
|
+
|
229
|
+
before do
|
230
|
+
word.definitions.find_or_create_by(description: 'database connector')
|
231
|
+
word.definitions.find_or_create_by(description: 'chauffeur')
|
232
|
+
word.definitions = word.definitions.reverse
|
233
|
+
word.definitions.destroy_all
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'removes all embedded documents' do
|
237
|
+
expect(word.definitions.size).to eq(0)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
191
241
|
end
|
192
242
|
end
|
@@ -16,7 +16,7 @@ describe Mongoid::Persistable::Incrementable do
|
|
16
16
|
expect(person.score).to eq(90)
|
17
17
|
end
|
18
18
|
|
19
|
-
it "sets a
|
19
|
+
it "sets a nonexistent value" do
|
20
20
|
expect(person.inte).to eq(30)
|
21
21
|
end
|
22
22
|
|
@@ -32,7 +32,7 @@ describe Mongoid::Persistable::Incrementable do
|
|
32
32
|
expect(person.reload.score).to eq(90)
|
33
33
|
end
|
34
34
|
|
35
|
-
it "persists a
|
35
|
+
it "persists a nonexistent inc" do
|
36
36
|
expect(person.reload.inte).to eq(30)
|
37
37
|
end
|
38
38
|
|
@@ -97,7 +97,7 @@ describe Mongoid::Persistable::Incrementable do
|
|
97
97
|
expect(address.no).to eq(90)
|
98
98
|
end
|
99
99
|
|
100
|
-
it "sets a
|
100
|
+
it "sets a nonexistent value" do
|
101
101
|
expect(address.house).to eq(30)
|
102
102
|
end
|
103
103
|
|
@@ -113,7 +113,7 @@ describe Mongoid::Persistable::Incrementable do
|
|
113
113
|
expect(address.reload.no).to eq(90)
|
114
114
|
end
|
115
115
|
|
116
|
-
it "persists a
|
116
|
+
it "persists a nonexistent inc" do
|
117
117
|
expect(address.reload.house).to eq(30)
|
118
118
|
end
|
119
119
|
|
@@ -169,5 +169,57 @@ describe Mongoid::Persistable::Incrementable do
|
|
169
169
|
it_behaves_like "an incrementable embedded document"
|
170
170
|
end
|
171
171
|
end
|
172
|
+
|
173
|
+
context "when the document is embedded in another embedded document" do
|
174
|
+
shared_examples_for "an incrementable embedded document in another embedded document" do
|
175
|
+
|
176
|
+
it "increments a positive value" do
|
177
|
+
expect(second_answer.position).to eq(2)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "persists a positive inc" do
|
181
|
+
expect(second_answer.reload.position).to eq(2)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "clears out dirty changes" do
|
185
|
+
expect(second_answer).to_not be_changed
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
let(:survey) do
|
190
|
+
Survey.create
|
191
|
+
end
|
192
|
+
|
193
|
+
let(:question) do
|
194
|
+
survey.questions.create(content: 'foo')
|
195
|
+
end
|
196
|
+
|
197
|
+
let!(:first_answer) do
|
198
|
+
question.answers.create(position: 99)
|
199
|
+
end
|
200
|
+
|
201
|
+
let!(:second_answer) do
|
202
|
+
question.answers.create(position: 1)
|
203
|
+
end
|
204
|
+
|
205
|
+
context "when providing string fields" do
|
206
|
+
|
207
|
+
let!(:inc) do
|
208
|
+
second_answer.inc("position" => 1)
|
209
|
+
end
|
210
|
+
|
211
|
+
it_behaves_like "an incrementable embedded document in another embedded document"
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
context "when providing symbol fields" do
|
216
|
+
|
217
|
+
let!(:inc) do
|
218
|
+
second_answer.inc(position: 1)
|
219
|
+
end
|
220
|
+
|
221
|
+
it_behaves_like "an incrementable embedded document in another embedded document"
|
222
|
+
end
|
223
|
+
end
|
172
224
|
end
|
173
225
|
end
|
@@ -122,6 +122,17 @@ describe Mongoid::Persistable::Pushable do
|
|
122
122
|
|
123
123
|
it_behaves_like "a unique pushable embedded document"
|
124
124
|
end
|
125
|
+
|
126
|
+
context "when provided an array of objects" do
|
127
|
+
|
128
|
+
before do
|
129
|
+
person.add_to_set(array: [{ a: 1}, { b: 2}])
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'persists the array of objects' do
|
133
|
+
expect(person.reload.array).to eq([{ 'a' => 1}, { 'b' => 2}])
|
134
|
+
end
|
135
|
+
end
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
@@ -83,6 +83,24 @@ describe Mongoid::Persistable::Savable do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
|
+
|
87
|
+
context 'when the embedded document is unchanged' do
|
88
|
+
|
89
|
+
let(:kangaroo) do
|
90
|
+
Kangaroo.new
|
91
|
+
end
|
92
|
+
|
93
|
+
after do
|
94
|
+
Kangaroo.destroy_all
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'only makes one call to the database' do
|
98
|
+
allow(Kangaroo.collection).to receive(:insert).once
|
99
|
+
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).never
|
100
|
+
kangaroo.build_baby
|
101
|
+
kangaroo.save
|
102
|
+
end
|
103
|
+
end
|
86
104
|
end
|
87
105
|
end
|
88
106
|
|
@@ -395,7 +413,7 @@ describe Mongoid::Persistable::Savable do
|
|
395
413
|
end
|
396
414
|
end
|
397
415
|
|
398
|
-
it "reads for
|
416
|
+
it "reads for persistence as a UTC Time" do
|
399
417
|
expect(user.changes["last_login"].last.class).to eq(Time)
|
400
418
|
end
|
401
419
|
|
@@ -414,7 +432,7 @@ describe Mongoid::Persistable::Savable do
|
|
414
432
|
end
|
415
433
|
end
|
416
434
|
|
417
|
-
it "reads for
|
435
|
+
it "reads for persistence as a UTC Time" do
|
418
436
|
expect(user.changes["account_expires"].last.class).to eq(Time)
|
419
437
|
end
|
420
438
|
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Positional do
|
4
|
+
|
5
|
+
describe "#positionally" do
|
6
|
+
|
7
|
+
let(:positionable) do
|
8
|
+
Class.new do
|
9
|
+
include Mongoid::Positional
|
10
|
+
end.new
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:updates) do
|
14
|
+
{
|
15
|
+
"$set" => {
|
16
|
+
"field" => "value",
|
17
|
+
"children.0.field" => "value",
|
18
|
+
"children.0.children.1.children.3.field" => "value"
|
19
|
+
},
|
20
|
+
"$pushAll" => {
|
21
|
+
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when a child has an embeds many under an embeds one" do
|
27
|
+
|
28
|
+
context "when selector does not include the embeds one" do
|
29
|
+
|
30
|
+
let(:selector) do
|
31
|
+
{ "_id" => 1, "child._id" => 2 }
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:ops) do
|
35
|
+
{
|
36
|
+
"$set" => {
|
37
|
+
"field" => "value",
|
38
|
+
"child.children.1.children.3.field" => "value",
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:processed) do
|
44
|
+
positionable.positionally(selector, ops)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not do any replacement" do
|
48
|
+
expect(processed).to eq(ops)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when selector includes the embeds one" do
|
53
|
+
|
54
|
+
let(:selector) do
|
55
|
+
{ "_id" => 1, "child._id" => 2, "child.children._id" => 3 }
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:ops) do
|
59
|
+
{
|
60
|
+
"$set" => {
|
61
|
+
"field" => "value",
|
62
|
+
"child.children.1.children.3.field" => "value",
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:expected) do
|
68
|
+
{
|
69
|
+
"$set" => {
|
70
|
+
"field" => "value",
|
71
|
+
"child.children.1.children.3.field" => "value",
|
72
|
+
}
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:processed) do
|
77
|
+
positionable.positionally(selector, ops)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "does not do any replacement" do
|
81
|
+
expect(processed).to eq(expected)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when the selector has only 1 pair" do
|
87
|
+
|
88
|
+
let(:selector) do
|
89
|
+
{ "_id" => 1 }
|
90
|
+
end
|
91
|
+
|
92
|
+
let(:processed) do
|
93
|
+
positionable.positionally(selector, updates)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "does not do any replacement" do
|
97
|
+
expect(processed).to eq(updates)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when the selector has 2 pairs" do
|
102
|
+
|
103
|
+
context "when the second pair has an id" do
|
104
|
+
|
105
|
+
let(:selector) do
|
106
|
+
{ "_id" => 1, "children._id" => 2 }
|
107
|
+
end
|
108
|
+
|
109
|
+
let(:expected) do
|
110
|
+
{
|
111
|
+
"$set" => {
|
112
|
+
"field" => "value",
|
113
|
+
"children.$.field" => "value",
|
114
|
+
"children.0.children.1.children.3.field" => "value"
|
115
|
+
},
|
116
|
+
"$pushAll" => {
|
117
|
+
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
118
|
+
}
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:processed) do
|
123
|
+
positionable.positionally(selector, updates)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "replaces the first index with the positional operator" do
|
127
|
+
expect(processed).to eq(expected)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when the second pair has no id" do
|
132
|
+
|
133
|
+
let(:selector) do
|
134
|
+
{ "_id" => 1, "children._id" => nil }
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:expected) do
|
138
|
+
{
|
139
|
+
"$set" => {
|
140
|
+
"field" => "value",
|
141
|
+
"children.0.field" => "value",
|
142
|
+
"children.0.children.1.children.3.field" => "value"
|
143
|
+
},
|
144
|
+
"$pushAll" => {
|
145
|
+
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
let(:processed) do
|
151
|
+
positionable.positionally(selector, updates)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "does not replace the index with the positional operator" do
|
155
|
+
expect(processed).to eq(expected)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when the selector has 3 pairs" do
|
161
|
+
|
162
|
+
let(:selector) do
|
163
|
+
{ "_id" => 1, "children._id" => 2, "children.0.children._id" => 3 }
|
164
|
+
end
|
165
|
+
|
166
|
+
let(:expected) do
|
167
|
+
{
|
168
|
+
"$set" => {
|
169
|
+
"field" => "value",
|
170
|
+
"children.$.field" => "value",
|
171
|
+
"children.0.children.1.children.3.field" => "value"
|
172
|
+
},
|
173
|
+
"$pushAll" => {
|
174
|
+
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
175
|
+
}
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
let(:processed) do
|
180
|
+
positionable.positionally(selector, updates)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "replaces the first index with the positional operator" do
|
184
|
+
expect(processed).to eq(expected)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "when the selector has 4 pairs" do
|
189
|
+
|
190
|
+
let(:selector) do
|
191
|
+
{
|
192
|
+
"_id" => 1,
|
193
|
+
"children._id" => 2,
|
194
|
+
"children.0.children._id" => 3,
|
195
|
+
"children.0.children.1.children._id" => 4
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
let(:expected) do
|
200
|
+
{
|
201
|
+
"$set" => {
|
202
|
+
"field" => "value",
|
203
|
+
"children.$.field" => "value",
|
204
|
+
"children.0.children.1.children.3.field" => "value"
|
205
|
+
},
|
206
|
+
"$pushAll" => {
|
207
|
+
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
208
|
+
}
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
let(:processed) do
|
213
|
+
positionable.positionally(selector, updates)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "replaces the first index with the positional operator" do
|
217
|
+
expect(processed).to eq(expected)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|