mongoid 7.0.5 → 7.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 chaninning the criterion" do
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 the values are a hash" do
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 values are not hashes" do
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 the values are a hash" do
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 contains the value" do
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 does not contain the value" do
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 scope is provided" do
799
+ context "when a range condition is provided" do
800
800
 
801
801
  before do
802
- Dictionary.validates_uniqueness_of(:name, :scope => Dictionary.where(:year.gte => 1900, :year.lt => 2000))
803
- Dictionary.create(name: "French-English", year: 1950)
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
- it "successfully prevents uniqueness violation" do
812
- expect(Dictionary.all.size).to eq(1)
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
- # There are both start and complete events for each query.
6
- expect(Mongo::Logger.logger).to receive(:debug?).exactly(number * 2).times.and_call_original
7
- yield
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)