mongoid 7.0.5 → 7.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|