mongoid 7.0.5 → 7.0.6
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 +0 -0
- data/LICENSE +1 -0
- data/README.md +2 -1
- data/lib/mongoid.rb +1 -0
- data/lib/mongoid/attributes.rb +28 -20
- data/lib/mongoid/attributes/dynamic.rb +15 -14
- data/lib/mongoid/config/environment.rb +21 -8
- data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
- data/lib/mongoid/criteria/queryable/selectable.rb +2 -3
- data/lib/mongoid/matchable.rb +14 -15
- data/lib/mongoid/matchable/all.rb +4 -3
- data/lib/mongoid/matchable/default.rb +71 -24
- data/lib/mongoid/version.rb +2 -1
- data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
- data/spec/integration/matchable_spec.rb +680 -0
- data/spec/lite_spec_helper.rb +4 -1
- data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
- data/spec/mongoid/attributes_spec.rb +19 -7
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
- data/spec/mongoid/document_fields_spec.rb +88 -0
- data/spec/mongoid/matchable/default_spec.rb +9 -2
- data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
- data/spec/support/expectations.rb +17 -3
- metadata +457 -442
- metadata.gz.sig +0 -0
@@ -1079,7 +1079,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
1079
1079
|
:location.within_box => [[ 1, 10 ], [ 2, 10 ]]
|
1080
1080
|
)
|
1081
1081
|
end
|
1082
|
-
|
1082
|
+
|
1083
1083
|
it "adds the $geoIntersects expression" do
|
1084
1084
|
expect(selection.selector).to eq({
|
1085
1085
|
"location" => {
|
@@ -2428,7 +2428,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
2428
2428
|
end
|
2429
2429
|
end
|
2430
2430
|
|
2431
|
-
context "when
|
2431
|
+
context "when chaining the criterion" do
|
2432
2432
|
|
2433
2433
|
context "when the criterion are for different fields" do
|
2434
2434
|
|
@@ -2665,225 +2665,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
2665
2665
|
end
|
2666
2666
|
end
|
2667
2667
|
|
2668
|
-
describe "#not" do
|
2669
|
-
|
2670
|
-
context "when provided no criterion" do
|
2671
|
-
|
2672
|
-
let(:selection) do
|
2673
|
-
query.not
|
2674
|
-
end
|
2675
|
-
|
2676
|
-
it "does not add any criterion" do
|
2677
|
-
expect(selection.selector).to eq({})
|
2678
|
-
end
|
2679
|
-
|
2680
|
-
it "returns the query" do
|
2681
|
-
expect(selection).to eq(query)
|
2682
|
-
end
|
2683
|
-
|
2684
|
-
it "returns a non cloned query" do
|
2685
|
-
expect(selection).to equal(query)
|
2686
|
-
end
|
2687
|
-
|
2688
|
-
context "when the following criteria is a query method" do
|
2689
|
-
|
2690
|
-
let(:selection) do
|
2691
|
-
query.not.all(field: [ 1, 2 ])
|
2692
|
-
end
|
2693
|
-
|
2694
|
-
it "negates the all selection" do
|
2695
|
-
expect(selection.selector).to eq(
|
2696
|
-
{ "field" => { "$not" => { "$all" => [ 1, 2 ] }}}
|
2697
|
-
)
|
2698
|
-
end
|
2699
|
-
|
2700
|
-
it "returns a cloned query" do
|
2701
|
-
expect(selection).to_not equal(query)
|
2702
|
-
end
|
2703
|
-
|
2704
|
-
it "removes the negation on the clone" do
|
2705
|
-
expect(selection).to_not be_negating
|
2706
|
-
end
|
2707
|
-
end
|
2708
|
-
|
2709
|
-
context "when the following criteria is a gt method" do
|
2710
|
-
|
2711
|
-
let(:selection) do
|
2712
|
-
query.not.gt(age: 50)
|
2713
|
-
end
|
2714
|
-
|
2715
|
-
it "negates the gt selection" do
|
2716
|
-
expect(selection.selector).to eq(
|
2717
|
-
{ "age" => { "$not" => { "$gt" => 50 }}}
|
2718
|
-
)
|
2719
|
-
end
|
2720
|
-
|
2721
|
-
it "returns a coned query" do
|
2722
|
-
expect(selection).to_not eq(query)
|
2723
|
-
end
|
2724
|
-
|
2725
|
-
it "removes the negation on the clone" do
|
2726
|
-
expect(selection).to_not be_negating
|
2727
|
-
end
|
2728
|
-
end
|
2729
|
-
|
2730
|
-
context "when the following criteria is a where" do
|
2731
|
-
|
2732
|
-
let(:selection) do
|
2733
|
-
query.not.where(field: 1, :other.in => [ 1, 2 ])
|
2734
|
-
end
|
2735
|
-
|
2736
|
-
it "negates the selection with an operator" do
|
2737
|
-
expect(selection.selector).to eq(
|
2738
|
-
{ "field" => { "$ne" => 1 }, "other" => { "$not" => { "$in" => [ 1, 2 ] }}}
|
2739
|
-
)
|
2740
|
-
end
|
2741
|
-
|
2742
|
-
it "returns a cloned query" do
|
2743
|
-
expect(selection).to_not equal(query)
|
2744
|
-
end
|
2745
|
-
|
2746
|
-
it "removes the negation on the clone" do
|
2747
|
-
expect(selection).to_not be_negating
|
2748
|
-
end
|
2749
|
-
end
|
2750
|
-
|
2751
|
-
context "when the following criteria is a where with a regexp" do
|
2752
|
-
|
2753
|
-
let(:selection) do
|
2754
|
-
query.not.where(field: 1, other: /test/)
|
2755
|
-
end
|
2756
|
-
|
2757
|
-
it "negates the selection with an operator" do
|
2758
|
-
expect(selection.selector).to eq(
|
2759
|
-
{ "field" => { "$ne" => 1 }, "other" => { "$not" => /test/ } }
|
2760
|
-
)
|
2761
|
-
end
|
2762
|
-
|
2763
|
-
it "returns a cloned query" do
|
2764
|
-
expect(selection).to_not equal(query)
|
2765
|
-
end
|
2766
|
-
|
2767
|
-
it "removes the negation on the clone" do
|
2768
|
-
expect(selection).to_not be_negating
|
2769
|
-
end
|
2770
|
-
|
2771
|
-
end
|
2772
|
-
end
|
2773
|
-
|
2774
|
-
context "when provided nil" do
|
2775
|
-
|
2776
|
-
let(:selection) do
|
2777
|
-
query.not(nil)
|
2778
|
-
end
|
2779
|
-
|
2780
|
-
it "does not add any criterion" do
|
2781
|
-
expect(selection.selector).to eq({})
|
2782
|
-
end
|
2783
|
-
|
2784
|
-
it "returns the query" do
|
2785
|
-
expect(selection).to eq(query)
|
2786
|
-
end
|
2787
|
-
|
2788
|
-
it "returns a cloned query" do
|
2789
|
-
expect(selection).to_not equal(query)
|
2790
|
-
end
|
2791
|
-
end
|
2792
|
-
|
2793
|
-
context "when provided a single criterion" do
|
2794
|
-
|
2795
|
-
let(:selection) do
|
2796
|
-
query.not(field: /test/)
|
2797
|
-
end
|
2798
|
-
|
2799
|
-
it "adds the $not selector" do
|
2800
|
-
expect(selection.selector).to eq({
|
2801
|
-
"field" => { "$not" => /test/ }
|
2802
|
-
})
|
2803
|
-
end
|
2804
|
-
|
2805
|
-
it "returns a cloned query" do
|
2806
|
-
expect(selection).to_not equal(query)
|
2807
|
-
end
|
2808
|
-
end
|
2809
|
-
|
2810
|
-
context "when provided multiple criterion" do
|
2811
|
-
|
2812
|
-
context "when the criterion are for different fields" do
|
2813
|
-
|
2814
|
-
let(:selection) do
|
2815
|
-
query.not(first: /1/, second: /2/)
|
2816
|
-
end
|
2817
|
-
|
2818
|
-
it "adds the $not selectors" do
|
2819
|
-
expect(selection.selector).to eq({
|
2820
|
-
"first" => { "$not" => /1/ },
|
2821
|
-
"second" => { "$not" => /2/ }
|
2822
|
-
})
|
2823
|
-
end
|
2824
|
-
|
2825
|
-
it "returns a cloned query" do
|
2826
|
-
expect(selection).to_not equal(query)
|
2827
|
-
end
|
2828
|
-
end
|
2829
|
-
end
|
2830
|
-
|
2831
|
-
context "when chaining the criterion" do
|
2832
|
-
|
2833
|
-
context "when the criterion are for different fields" do
|
2834
|
-
|
2835
|
-
let(:selection) do
|
2836
|
-
query.not(first: /1/).not(second: /2/)
|
2837
|
-
end
|
2838
|
-
|
2839
|
-
it "adds the $not selectors" do
|
2840
|
-
expect(selection.selector).to eq({
|
2841
|
-
"first" => { "$not" => /1/ },
|
2842
|
-
"second" => { "$not" => /2/ }
|
2843
|
-
})
|
2844
|
-
end
|
2845
|
-
|
2846
|
-
it "returns a cloned query" do
|
2847
|
-
expect(selection).to_not equal(query)
|
2848
|
-
end
|
2849
|
-
end
|
2850
|
-
|
2851
|
-
context "when the criterion are on the same field" do
|
2852
|
-
|
2853
|
-
let(:selection) do
|
2854
|
-
query.not(first: /1/).not(first: /2/)
|
2855
|
-
end
|
2856
|
-
|
2857
|
-
it "overwrites the first $not selector" do
|
2858
|
-
expect(selection.selector).to eq({
|
2859
|
-
"first" => { "$not" => /2/ }
|
2860
|
-
})
|
2861
|
-
end
|
2862
|
-
|
2863
|
-
it "returns a cloned query" do
|
2864
|
-
expect(selection).to_not equal(query)
|
2865
|
-
end
|
2866
|
-
end
|
2867
|
-
|
2868
|
-
context "when the criterion are a double negative" do
|
2869
|
-
|
2870
|
-
let(:selection) do
|
2871
|
-
query.not.where(:first.not => /1/)
|
2872
|
-
end
|
2873
|
-
|
2874
|
-
it "does not double the $not selector" do
|
2875
|
-
expect(selection.selector).to eq({
|
2876
|
-
"first" => { "$not" => /1/ }
|
2877
|
-
})
|
2878
|
-
end
|
2879
|
-
|
2880
|
-
it "returns a cloned query" do
|
2881
|
-
expect(selection).to_not equal(query)
|
2882
|
-
end
|
2883
|
-
end
|
2884
|
-
end
|
2885
|
-
end
|
2886
|
-
|
2887
2668
|
describe "#or" do
|
2888
2669
|
|
2889
2670
|
context "when provided no criterion" do
|
@@ -4198,7 +3979,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
4198
3979
|
|
4199
3980
|
context "when using the strategies via methods" do
|
4200
3981
|
|
4201
|
-
context "when
|
3982
|
+
context "when different operators are specified" do
|
4202
3983
|
|
4203
3984
|
let(:selection) do
|
4204
3985
|
query.gt(field: 5).lt(field: 10).ne(field: 7)
|
@@ -4211,7 +3992,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
4211
3992
|
end
|
4212
3993
|
end
|
4213
3994
|
|
4214
|
-
context "when the
|
3995
|
+
context "when the same operator is specified" do
|
4215
3996
|
|
4216
3997
|
let(:selection) do
|
4217
3998
|
query.where(field: 5).where(field: 10)
|
@@ -4225,7 +4006,7 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
4225
4006
|
|
4226
4007
|
context "when using the strategies via #where" do
|
4227
4008
|
|
4228
|
-
context "when
|
4009
|
+
context "when using complex keys with different operators" do
|
4229
4010
|
|
4230
4011
|
let(:selection) do
|
4231
4012
|
query.where(:field.gt => 5, :field.lt => 10, :field.ne => 7)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
describe Mongoid::Document do
|
7
|
+
|
8
|
+
describe 'BSON::Binary field' do
|
9
|
+
context 'when assigned a BSON::Binary instance' do
|
10
|
+
let(:data) do
|
11
|
+
BSON::Binary.new("hello world")
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:registry) do
|
15
|
+
Registry.new(data: data)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'does not freeze the specified data' do
|
19
|
+
registry
|
20
|
+
|
21
|
+
data.should_not be_frozen
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'persists' do
|
25
|
+
registry.save!
|
26
|
+
|
27
|
+
_registry = Registry.find(registry.id)
|
28
|
+
_registry.data.should == data
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when assigned a binary string' do
|
33
|
+
let(:data) do
|
34
|
+
# Frozen string literals do not allow setting encoding on a string
|
35
|
+
# literal - work around by composing the string at runtime
|
36
|
+
([0, 253, 254] * 2).map(&:chr).join.force_encoding('BINARY')
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:registry) do
|
40
|
+
Registry.new(data: data)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'assigns as a BSON::Binary object' do
|
44
|
+
pending 'https://jira.mongodb.org/browse/MONGOID-4823'
|
45
|
+
|
46
|
+
registry.data.should be_a(BSON::Binary)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'persists' do
|
50
|
+
pending 'https://jira.mongodb.org/browse/MONGOID-4823'
|
51
|
+
|
52
|
+
registry.save!
|
53
|
+
|
54
|
+
_registry = Registry.find(registry.id)
|
55
|
+
_registry.data.should == BSON::Binary.new(data)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'Hash field' do
|
61
|
+
context 'with symbol key and value' do
|
62
|
+
let(:church) do
|
63
|
+
Church.create!(location: {state: :ny})
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:found_church) do
|
67
|
+
Church.find(church.id)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'round-trips the value' do
|
71
|
+
found_church.location[:state].should == :ny
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'stringifies the key' do
|
75
|
+
found_church.location.keys.should == %w(state)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'retrieves value as symbol via driver' do
|
79
|
+
Church.delete_all
|
80
|
+
|
81
|
+
church
|
82
|
+
|
83
|
+
v = Church.collection.find.first
|
84
|
+
v['location'].should == {'state' => :ny}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -112,14 +112,21 @@ describe Mongoid::Matchable::Default do
|
|
112
112
|
described_class.new(["Test1", "Test2", "Test3"])
|
113
113
|
end
|
114
114
|
|
115
|
-
context "when the attribute
|
115
|
+
context "when the attribute equals the value" do
|
116
116
|
|
117
117
|
it "returns true" do
|
118
118
|
expect(matcher._matches?(["Test1", "Test2", "Test3"])).to be true
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
context "when the attribute
|
122
|
+
context "when the value contains same items as attribute but in different order" do
|
123
|
+
|
124
|
+
it "returns false" do
|
125
|
+
expect(matcher._matches?(["Test1", "Test3", "Test2"])).to be false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when the value is a subset of attribute" do
|
123
130
|
|
124
131
|
it "returns false" do
|
125
132
|
expect(matcher._matches?(["Test1", "Test2"])).to be false
|
@@ -796,20 +796,47 @@ describe Mongoid::Validatable::UniquenessValidator do
|
|
796
796
|
end
|
797
797
|
end
|
798
798
|
|
799
|
-
context "when a range
|
799
|
+
context "when a range condition is provided" do
|
800
800
|
|
801
801
|
before do
|
802
|
-
Dictionary.validates_uniqueness_of(:name,
|
803
|
-
|
804
|
-
Dictionary.create(name: "French-English", year: 1960)
|
802
|
+
Dictionary.validates_uniqueness_of(:name,
|
803
|
+
conditions: -> { Dictionary.where(:year.gte => 1900, :year.lt => 2000) })
|
805
804
|
end
|
806
805
|
|
807
806
|
after do
|
808
807
|
Dictionary.reset_callbacks(:validate)
|
809
808
|
end
|
810
809
|
|
811
|
-
|
812
|
-
|
810
|
+
context 'when multiple documents would match the condition' do
|
811
|
+
it "prevents creation of new document" do
|
812
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
813
|
+
|
814
|
+
expect do
|
815
|
+
Dictionary.create!(name: "French-English", year: 1960)
|
816
|
+
end.to raise_error(Mongoid::Errors::Validations, /Name is already taken/)
|
817
|
+
|
818
|
+
expect(Dictionary.all.size).to eq(1)
|
819
|
+
end
|
820
|
+
end
|
821
|
+
|
822
|
+
context 'when only new document would match the condition' do
|
823
|
+
it 'creates the new document' do
|
824
|
+
Dictionary.create!(name: "French-English", year: 950)
|
825
|
+
expect do
|
826
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
827
|
+
end.not_to raise_error
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
context 'when only existing document matches the condition' do
|
832
|
+
it 'creates the new document' do
|
833
|
+
pending 'https://jira.mongodb.org/browse/MONGOID-4815'
|
834
|
+
|
835
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
836
|
+
expect do
|
837
|
+
Dictionary.create!(name: "French-English", year: 950)
|
838
|
+
end.not_to raise_error
|
839
|
+
end
|
813
840
|
end
|
814
841
|
end
|
815
842
|
|
@@ -1,10 +1,24 @@
|
|
1
1
|
module Mongoid
|
2
2
|
module Expectations
|
3
3
|
|
4
|
+
def connection_class
|
5
|
+
if defined?(Mongo::Server::ConnectionBase)
|
6
|
+
Mongo::Server::ConnectionBase
|
7
|
+
else
|
8
|
+
# Pre-2.8 drivers
|
9
|
+
Mongo::Server::Connection
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
def expect_query(number)
|
5
|
-
|
6
|
-
|
7
|
-
|
14
|
+
RSpec::Mocks.with_temporary_scope do
|
15
|
+
if number > 0
|
16
|
+
expect_any_instance_of(connection_class).to receive(:command_started).exactly(number).times.and_call_original
|
17
|
+
else
|
18
|
+
expect_any_instance_of(connection_class).not_to receive(:command_started)
|
19
|
+
end
|
20
|
+
yield
|
21
|
+
end
|
8
22
|
end
|
9
23
|
|
10
24
|
def expect_no_queries(&block)
|