mongoid 6.4.1 → 6.4.2
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongoid/contextual/map_reduce.rb +1 -1
- data/lib/mongoid/criteria/modifiable.rb +12 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +1 -1
- data/lib/mongoid/matchable.rb +3 -0
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistence_context.rb +4 -0
- data/lib/mongoid/version.rb +1 -1
- data/spec/app/models/array_field.rb +7 -0
- data/spec/mongoid/clients/factory_spec.rb +3 -3
- data/spec/mongoid/clients/options_spec.rb +28 -13
- data/spec/mongoid/clients/sessions_spec.rb +3 -3
- data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable_spec.rb +26 -1
- data/spec/mongoid/persistable/settable_spec.rb +19 -0
- metadata +451 -446
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4c5d349e3de6af570dd7b1347fd76b6056848149180dc355e116f67f8ac2c3c6
|
4
|
+
data.tar.gz: e9be28598f701bb124ba6626bb777da07d05bca692224110078700557f2c0aa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bf33975f8969cc06ac717cef1a443429dd6ad8e8a7cd755c8b74ed9b7bc0e1a113413dac81098f54f9c181b91d03fc5958adfaaddb03d7fb91caa9f2e11dc84
|
7
|
+
data.tar.gz: c5ef0576ed9941a5ba0f0865fdaff885766e4d6fe6901d1037ce408a0acdc0e00fdbfe503a5a7d721d8178a83c39c6e5893aaf0c258e871b3dca17939d0e7d97
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -165,7 +165,7 @@ module Mongoid
|
|
165
165
|
def raw
|
166
166
|
validate_out!
|
167
167
|
cmd = command
|
168
|
-
opts = { read: cmd.delete(:read)
|
168
|
+
opts = { read: cmd.delete(:read) } if cmd[:read]
|
169
169
|
@map_reduce.database.command(cmd, (opts || {}).merge(session: _session)).first
|
170
170
|
end
|
171
171
|
alias :results :raw
|
@@ -3,6 +3,10 @@ module Mongoid
|
|
3
3
|
class Criteria
|
4
4
|
module Modifiable
|
5
5
|
|
6
|
+
# @attribute [r] create_attrs Additional attributes to add to the Document upon creation.
|
7
|
+
# @api private
|
8
|
+
attr_reader :create_attrs
|
9
|
+
|
6
10
|
# Build a document given the selector and return it.
|
7
11
|
# Complex criteria, such as $in and $or operations will get ignored.
|
8
12
|
#
|
@@ -57,6 +61,9 @@ module Mongoid
|
|
57
61
|
|
58
62
|
# Define attributes with which new documents will be created.
|
59
63
|
#
|
64
|
+
# Note that if `find_or_create_by` is called after this in a method chain, the attributes in
|
65
|
+
# the query will override those from this method.
|
66
|
+
#
|
60
67
|
# @example Define attributes to be used when a new document is created.
|
61
68
|
# Person.create_with(job: 'Engineer').find_or_create_by(employer: 'MongoDB')
|
62
69
|
#
|
@@ -64,7 +71,9 @@ module Mongoid
|
|
64
71
|
#
|
65
72
|
# @since 5.1.0
|
66
73
|
def create_with(attrs = {})
|
67
|
-
|
74
|
+
tap do
|
75
|
+
(@create_attrs ||= {}).merge!(attrs)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
|
70
79
|
# Find the first +Document+ given the conditions, or creates a new document
|
@@ -172,7 +181,8 @@ module Mongoid
|
|
172
181
|
#
|
173
182
|
# @since 3.0.0
|
174
183
|
def create_document(method, attrs = nil, &block)
|
175
|
-
|
184
|
+
attrs = (create_attrs || {}).merge(attrs || {})
|
185
|
+
attributes = selector.reduce(attrs) do |hash, (key, value)|
|
176
186
|
unless invalid_key?(hash, key) || invalid_embedded_doc?(value)
|
177
187
|
hash[key] = value
|
178
188
|
end
|
@@ -24,7 +24,7 @@ module Mongoid
|
|
24
24
|
# @since 2.0.0
|
25
25
|
POLYGON = "Polygon"
|
26
26
|
|
27
|
-
# @attribute [rw] negating If the next
|
27
|
+
# @attribute [rw] negating If the next expression is negated.
|
28
28
|
# @attribute [rw] selector The query selector.
|
29
29
|
attr_accessor :negating, :selector
|
30
30
|
|
data/lib/mongoid/matchable.rb
CHANGED
@@ -11,6 +11,7 @@ require "mongoid/matchable/lte"
|
|
11
11
|
require "mongoid/matchable/ne"
|
12
12
|
require "mongoid/matchable/nin"
|
13
13
|
require "mongoid/matchable/or"
|
14
|
+
require "mongoid/matchable/nor"
|
14
15
|
require "mongoid/matchable/size"
|
15
16
|
require "mongoid/matchable/elem_match"
|
16
17
|
require "mongoid/matchable/regexp"
|
@@ -40,6 +41,7 @@ module Mongoid
|
|
40
41
|
"$ne" => Ne,
|
41
42
|
"$nin" => Nin,
|
42
43
|
"$or" => Or,
|
44
|
+
"$nor" => Nor,
|
43
45
|
"$size" => Size
|
44
46
|
}.with_indifferent_access.freeze
|
45
47
|
|
@@ -124,6 +126,7 @@ module Mongoid
|
|
124
126
|
case key.to_s
|
125
127
|
when "$or" then Or.new(value, document)
|
126
128
|
when "$and" then And.new(value, document)
|
129
|
+
when "$nor" then Nor.new(value, document)
|
127
130
|
else Default.new(extract_attribute(document, key))
|
128
131
|
end
|
129
132
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
module Mongoid
|
4
|
+
module Matchable
|
5
|
+
|
6
|
+
# Defines behavior for handling $nor expressions in embedded documents.
|
7
|
+
class Nor < Default
|
8
|
+
|
9
|
+
# Does the supplied query match the attribute?
|
10
|
+
#
|
11
|
+
# Note: an empty array as an argument to $nor is prohibited by
|
12
|
+
# MongoDB server. Mongoid does allow this and returns false in this case.
|
13
|
+
#
|
14
|
+
# @example Does this match?
|
15
|
+
# matcher._matches?("$nor" => [ { field => value } ])
|
16
|
+
#
|
17
|
+
# @param [ Array ] conditions The or expression.
|
18
|
+
#
|
19
|
+
# @return [ true, false ] True if matches, false if not.
|
20
|
+
#
|
21
|
+
# @since 6.4.2/7.0.2/7.1.0
|
22
|
+
def _matches?(conditions)
|
23
|
+
if conditions.length == 0
|
24
|
+
# MongoDB does not allow $nor array to be empty, but
|
25
|
+
# Mongoid accepts an empty array for $or which MongoDB also
|
26
|
+
# prohibits
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
conditions.none? do |condition|
|
30
|
+
condition.all? do |key, value|
|
31
|
+
document._matches?(key => value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -25,15 +25,15 @@ module Mongoid
|
|
25
25
|
|
26
26
|
field_and_value_hash = hasherizer(field.split('.'), value)
|
27
27
|
field = field_and_value_hash.keys.first.to_s
|
28
|
+
value = field_and_value_hash[field]
|
28
29
|
|
29
|
-
if fields[field] && fields[field].type == Hash && attributes.key?(field) && !value.empty?
|
30
|
+
if fields[field] && fields[field].type == Hash && attributes.key?(field) && Hash === value && !value.empty?
|
30
31
|
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
31
|
-
value = (attributes[field] || {}).merge(
|
32
|
-
process_attribute(field.to_s, value)
|
33
|
-
else
|
34
|
-
process_attribute(field.to_s, field_and_value_hash[field])
|
32
|
+
value = (attributes[field] || {}).merge(value, &merger)
|
35
33
|
end
|
36
34
|
|
35
|
+
process_attribute(field.to_s, value)
|
36
|
+
|
37
37
|
unless relations.include?(field.to_s)
|
38
38
|
ops[atomic_attribute_name(field)] = attributes[field]
|
39
39
|
end
|
@@ -107,6 +107,10 @@ module Mongoid
|
|
107
107
|
#
|
108
108
|
# @since 6.0.0
|
109
109
|
def client
|
110
|
+
client_options = send(:client_options)
|
111
|
+
if client_options[:read].is_a?(Symbol)
|
112
|
+
client_options = client_options.merge(read: {mode: client_options[:read]})
|
113
|
+
end
|
110
114
|
@client ||= (client = Clients.with_name(client_name)
|
111
115
|
client = client.use(database_name) if database_name_option
|
112
116
|
client.with(client_options))
|
data/lib/mongoid/version.rb
CHANGED
@@ -132,8 +132,8 @@ describe Mongoid::Clients::Factory do
|
|
132
132
|
|
133
133
|
let(:config) do
|
134
134
|
{
|
135
|
-
default: { hosts: [ "127.0.0.1:
|
136
|
-
secondary: { uri: "mongodb://127.0.0.1:
|
135
|
+
default: { hosts: [ "127.0.0.1:1234" ], database: database_id },
|
136
|
+
secondary: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/mongoid_test" }
|
137
137
|
}
|
138
138
|
end
|
139
139
|
|
@@ -162,7 +162,7 @@ describe Mongoid::Clients::Factory do
|
|
162
162
|
end
|
163
163
|
|
164
164
|
it "sets the cluster's seeds" do
|
165
|
-
expect(seeds).to eq([ "127.0.0.1:
|
165
|
+
expect(seeds).to eq([ "127.0.0.1:1234", "127.0.0.1:5678" ])
|
166
166
|
end
|
167
167
|
end
|
168
168
|
end
|
@@ -177,25 +177,40 @@ describe Mongoid::Clients::Options do
|
|
177
177
|
|
178
178
|
context 'when returning a criteria' do
|
179
179
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
collection =
|
184
|
-
klass
|
180
|
+
shared_context 'applies secondary read preference' do
|
181
|
+
|
182
|
+
let(:context_and_criteria) do
|
183
|
+
collection = nil
|
184
|
+
cxt = Band.with(read_secondary_option) do |klass|
|
185
|
+
collection = klass.all.collection
|
186
|
+
klass.persistence_context
|
187
|
+
end
|
188
|
+
[ cxt, collection ]
|
185
189
|
end
|
186
|
-
[ cxt, collection ]
|
187
|
-
end
|
188
190
|
|
189
|
-
|
190
|
-
|
191
|
+
let(:persistence_context) do
|
192
|
+
context_and_criteria[0]
|
193
|
+
end
|
194
|
+
|
195
|
+
let(:client) do
|
196
|
+
context_and_criteria[1].client
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'applies the options to the criteria client' do
|
200
|
+
expect(client.options['read']).to eq('mode' => :secondary)
|
201
|
+
end
|
191
202
|
end
|
192
203
|
|
193
|
-
|
194
|
-
|
204
|
+
context 'read: :secondary shorthand' do
|
205
|
+
let(:read_secondary_option) { {read: :secondary} }
|
206
|
+
|
207
|
+
it_behaves_like 'applies secondary read preference'
|
195
208
|
end
|
196
209
|
|
197
|
-
|
198
|
-
|
210
|
+
context 'read: {mode: :secondary}' do
|
211
|
+
let(:read_secondary_option) { {read: {mode: :secondary}} }
|
212
|
+
|
213
|
+
it_behaves_like 'applies secondary read preference'
|
199
214
|
end
|
200
215
|
end
|
201
216
|
|
@@ -16,17 +16,17 @@ describe Mongoid::Clients::Sessions do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
let(:subscriber) do
|
19
|
-
Mongoid::Clients.with_name(:other).
|
19
|
+
Mongoid::Clients.with_name(:other).send(:monitoring).subscribers['Command'].find do |s|
|
20
20
|
s.is_a?(EventSubscriber)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
let(:insert_events) do
|
25
|
-
subscriber.started_events.select { |event| event.command_name ==
|
25
|
+
subscriber.started_events.select { |event| event.command_name == 'insert' }
|
26
26
|
end
|
27
27
|
|
28
28
|
let(:update_events) do
|
29
|
-
subscriber.started_events.select { |event| event.command_name ==
|
29
|
+
subscriber.started_events.select { |event| event.command_name == 'update' }
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'when a session is used on a model class' do
|
@@ -1471,11 +1471,15 @@ describe Mongoid::Criteria::Modifiable do
|
|
1471
1471
|
{ 'username' => 'Turnip' }
|
1472
1472
|
end
|
1473
1473
|
|
1474
|
-
it '
|
1475
|
-
expect(Person.create_with(attrs).selector).to
|
1474
|
+
it 'does not modify the selector' do
|
1475
|
+
expect(Person.create_with(attrs).selector[:username]).to be_nil
|
1476
1476
|
end
|
1477
1477
|
|
1478
|
-
|
1478
|
+
it 'create_attrs is modified' do
|
1479
|
+
expect(Person.create_with(attrs).create_attrs).to eq(attrs)
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
context 'when a create is chained' do
|
1479
1483
|
|
1480
1484
|
context 'when a write method is chained' do
|
1481
1485
|
|
@@ -1499,6 +1503,25 @@ describe Mongoid::Criteria::Modifiable do
|
|
1499
1503
|
expect(new_person.age).to eq(50)
|
1500
1504
|
end
|
1501
1505
|
|
1506
|
+
context 'when a matching document is already in the collection' do
|
1507
|
+
let(:query) do
|
1508
|
+
{ 'username' => 'foo', 'age' => 12 }
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
let(:person) do
|
1512
|
+
Person.create!(query)
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
let(:found_person) do
|
1516
|
+
Person.create_with(attrs).find_or_create_by(query)
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
it 'finds the matching document' do
|
1520
|
+
person
|
1521
|
+
expect(found_person.id).to eq(person.id)
|
1522
|
+
end
|
1523
|
+
end
|
1524
|
+
|
1502
1525
|
context 'when the attributes are shared with the write method args' do
|
1503
1526
|
|
1504
1527
|
let(:query) do
|
@@ -1509,7 +1532,7 @@ describe Mongoid::Criteria::Modifiable do
|
|
1509
1532
|
Person.create_with(attrs).find_or_create_by(query)
|
1510
1533
|
end
|
1511
1534
|
|
1512
|
-
it 'gives the
|
1535
|
+
it 'gives the find method args precedence' do
|
1513
1536
|
expect(new_person.username).to eq('Beet')
|
1514
1537
|
expect(new_person.age).to eq(50)
|
1515
1538
|
end
|
@@ -1536,8 +1559,12 @@ describe Mongoid::Criteria::Modifiable do
|
|
1536
1559
|
{ 'username' => 'Beet', 'age' => 50 }
|
1537
1560
|
end
|
1538
1561
|
|
1562
|
+
it 'does not modify the selector' do
|
1563
|
+
expect(criteria.create_with(attrs).selector).to eq(criteria_selector)
|
1564
|
+
end
|
1565
|
+
|
1539
1566
|
it 'overwrites all the original attributes' do
|
1540
|
-
expect(criteria.create_with(attrs).
|
1567
|
+
expect(criteria.create_with(attrs).create_attrs).to eq(attrs)
|
1541
1568
|
end
|
1542
1569
|
end
|
1543
1570
|
end
|
@@ -1548,8 +1575,12 @@ describe Mongoid::Criteria::Modifiable do
|
|
1548
1575
|
{ 'username' => 'Beet' }
|
1549
1576
|
end
|
1550
1577
|
|
1578
|
+
it 'does not modify the selector' do
|
1579
|
+
expect(criteria.create_with(attrs).selector).to eq(criteria_selector)
|
1580
|
+
end
|
1581
|
+
|
1551
1582
|
it 'only overwrites the shared attributes' do
|
1552
|
-
expect(criteria.create_with(attrs).
|
1583
|
+
expect(criteria.create_with(attrs).create_attrs).to eq(attrs)
|
1553
1584
|
end
|
1554
1585
|
end
|
1555
1586
|
|
@@ -1558,12 +1589,11 @@ describe Mongoid::Criteria::Modifiable do
|
|
1558
1589
|
let(:attrs) do
|
1559
1590
|
{ 'username' => 'Turnip' }
|
1560
1591
|
end
|
1561
|
-
|
1562
1592
|
let(:query) do
|
1563
1593
|
{ 'username' => 'Beet', 'age' => 50 }
|
1564
1594
|
end
|
1565
1595
|
|
1566
|
-
context 'when a
|
1596
|
+
context 'when a create method is chained' do
|
1567
1597
|
|
1568
1598
|
it 'executes the method' do
|
1569
1599
|
expect(criteria.create_with(attrs).new.username).to eq('Turnip')
|
@@ -1577,9 +1607,28 @@ describe Mongoid::Criteria::Modifiable do
|
|
1577
1607
|
criteria.create_with(attrs).find_or_create_by(query)
|
1578
1608
|
end
|
1579
1609
|
|
1580
|
-
it '
|
1610
|
+
it 'gives the find method arg precedence' do
|
1581
1611
|
expect(new_person.username).to eq('Beet')
|
1582
|
-
expect(new_person.age).to
|
1612
|
+
expect(new_person.age).to be(50)
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
context 'when a matching document is already in the collection' do
|
1616
|
+
let(:query) do
|
1617
|
+
{ 'username' => 'foo', 'age' => 12 }
|
1618
|
+
end
|
1619
|
+
|
1620
|
+
let(:person) do
|
1621
|
+
Person.create!(query)
|
1622
|
+
end
|
1623
|
+
|
1624
|
+
let(:found_person) do
|
1625
|
+
criteria.create_with(attrs).find_or_create_by(query)
|
1626
|
+
end
|
1627
|
+
|
1628
|
+
it 'finds the matching document' do
|
1629
|
+
person
|
1630
|
+
expect(found_person.id).to eq(person.id)
|
1631
|
+
end
|
1583
1632
|
end
|
1584
1633
|
end
|
1585
1634
|
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Mongoid::Matchable::Nor do
|
6
|
+
|
7
|
+
let(:target) do
|
8
|
+
Person.new
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:matcher) do
|
12
|
+
described_class.new("value", target)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#_matches?" do
|
16
|
+
|
17
|
+
context "when provided a simple expression" do
|
18
|
+
|
19
|
+
context "when one of the hashes does not match model" do
|
20
|
+
|
21
|
+
let(:matches) do
|
22
|
+
matcher._matches?(
|
23
|
+
[ { title: "Sir" }, { title: "King" } ]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:target) do
|
28
|
+
Person.new(title: 'Queen')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns true" do
|
32
|
+
expect(matches).to be true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when all of the hashes match different fields in model" do
|
37
|
+
let(:matches) do
|
38
|
+
matcher._matches?(
|
39
|
+
[ { age: 10 }, { title: "King" } ]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:target) do
|
44
|
+
Person.new(title: 'King', age: 10)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns false" do
|
48
|
+
expect(matches).to be false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when one of the hashes matches an array field in model" do
|
53
|
+
let(:matches) do
|
54
|
+
matcher._matches?(
|
55
|
+
[ { af: "Sir" }, { af: "King" } ]
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
let(:target) do
|
60
|
+
ArrayField.new(af: ['King'])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns false" do
|
64
|
+
expect(matches).to be false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when none of the hashes matches an array field in model" do
|
69
|
+
let(:matches) do
|
70
|
+
matcher._matches?(
|
71
|
+
[ { af: "Sir" }, { af: "King" } ]
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:target) do
|
76
|
+
ArrayField.new(af: ['Boo'])
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns true" do
|
80
|
+
expect(matches).to be true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when there are no criteria" do
|
85
|
+
|
86
|
+
it "returns false" do
|
87
|
+
expect(matcher._matches?([])).to be false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# $nor with $not is a double negation.
|
92
|
+
# Whatever the argument of $not is is what the overall condition
|
93
|
+
# is looking for.
|
94
|
+
context "when the expression is a $not" do
|
95
|
+
|
96
|
+
let(:matches) do
|
97
|
+
matcher._matches?([ { title: {:$not => /Foobar/ } }])
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when the value does not match $not argument" do
|
101
|
+
|
102
|
+
let(:target) do
|
103
|
+
Person.new(title: 'test')
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns false" do
|
107
|
+
expect(matches).to be false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "when the value matches $not argument" do
|
112
|
+
|
113
|
+
let(:target) do
|
114
|
+
Person.new(title: 'Foobar baz')
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns true" do
|
118
|
+
expect(matches).to be true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when provided a complex expression" do
|
125
|
+
|
126
|
+
context "when none of the model values match criteria values" do
|
127
|
+
|
128
|
+
let(:matches) do
|
129
|
+
matcher._matches?(
|
130
|
+
[
|
131
|
+
{ title: { "$in" => [ "Sir", "Madam" ] } },
|
132
|
+
{ title: "King" }
|
133
|
+
]
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:target) do
|
138
|
+
Person.new(title: 'Queen')
|
139
|
+
end
|
140
|
+
|
141
|
+
it "returns true" do
|
142
|
+
expect(matches).to be true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when there is a matching value" do
|
147
|
+
|
148
|
+
let(:matches) do
|
149
|
+
matcher._matches?(
|
150
|
+
[
|
151
|
+
{ title: { "$in" => [ "Prince", "Madam" ] } },
|
152
|
+
{ title: "King" }
|
153
|
+
]
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
let(:target) do
|
158
|
+
Person.new(title: 'Prince')
|
159
|
+
end
|
160
|
+
|
161
|
+
it "returns false" do
|
162
|
+
expect(matches).to be false
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when expression contain multiple fields" do
|
167
|
+
|
168
|
+
let(:matches) do
|
169
|
+
matcher._matches?(
|
170
|
+
[
|
171
|
+
{ title: "Sir", age: 23 },
|
172
|
+
{ title: "King", age: 100 }
|
173
|
+
]
|
174
|
+
)
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'and model has different values in all of the fields' do
|
178
|
+
let(:target) do
|
179
|
+
Person.new(title: 'Queen', age: 10)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "returns true" do
|
183
|
+
expect(matches).to be true
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'and model has identical value in one of the fields' do
|
188
|
+
let(:target) do
|
189
|
+
Person.new(title: 'Queen', age: 23)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns true" do
|
193
|
+
expect(matches).to be true
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'and model has identical values in all of the fields' do
|
198
|
+
let(:target) do
|
199
|
+
Person.new(title: 'Sir', age: 23)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "returns false" do
|
203
|
+
expect(matches).to be false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|