mongoid 7.0.3 → 7.0.8

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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +1 -0
  4. data/LICENSE +1 -0
  5. data/README.md +3 -2
  6. data/Rakefile +12 -0
  7. data/lib/mongoid.rb +2 -1
  8. data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
  9. data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
  10. data/lib/mongoid/association/proxy.rb +1 -1
  11. data/lib/mongoid/association/relatable.rb +23 -21
  12. data/lib/mongoid/atomic.rb +13 -3
  13. data/lib/mongoid/atomic/paths/embedded.rb +1 -1
  14. data/lib/mongoid/attributes.rb +28 -20
  15. data/lib/mongoid/attributes/dynamic.rb +15 -14
  16. data/lib/mongoid/config/environment.rb +21 -8
  17. data/lib/mongoid/copyable.rb +5 -1
  18. data/lib/mongoid/criteria.rb +7 -1
  19. data/lib/mongoid/criteria/modifiable.rb +13 -2
  20. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  21. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  22. data/lib/mongoid/criteria/queryable/key.rb +67 -8
  23. data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
  24. data/lib/mongoid/criteria/queryable/selectable.rb +3 -4
  25. data/lib/mongoid/criteria/queryable/selector.rb +9 -31
  26. data/lib/mongoid/extensions/hash.rb +4 -2
  27. data/lib/mongoid/extensions/regexp.rb +1 -1
  28. data/lib/mongoid/extensions/string.rb +5 -3
  29. data/lib/mongoid/fields.rb +2 -1
  30. data/lib/mongoid/matchable.rb +14 -15
  31. data/lib/mongoid/matchable/all.rb +4 -3
  32. data/lib/mongoid/matchable/default.rb +71 -24
  33. data/lib/mongoid/matchable/regexp.rb +2 -2
  34. data/lib/mongoid/persistable/pushable.rb +11 -2
  35. data/lib/mongoid/persistence_context.rb +6 -6
  36. data/lib/mongoid/positional.rb +1 -1
  37. data/lib/mongoid/query_cache.rb +3 -2
  38. data/lib/mongoid/validatable/macros.rb +1 -1
  39. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  40. data/lib/mongoid/version.rb +2 -1
  41. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  42. data/spec/README.md +18 -0
  43. data/spec/app/models/delegating_patient.rb +16 -0
  44. data/spec/app/models/other_owner_object.rb +2 -0
  45. data/spec/integration/app_spec.rb +192 -0
  46. data/spec/integration/associations/embedded_spec.rb +62 -0
  47. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  48. data/spec/integration/document_spec.rb +22 -0
  49. data/spec/integration/matchable_spec.rb +680 -0
  50. data/spec/lite_spec_helper.rb +15 -5
  51. data/spec/mongoid/association/embedded/embedded_in_spec.rb +58 -0
  52. data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
  53. data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
  54. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +6 -0
  55. data/spec/mongoid/association/embedded/embeds_one_models.rb +51 -0
  56. data/spec/mongoid/association/embedded/embeds_one_spec.rb +46 -0
  57. data/spec/mongoid/association/referenced/belongs_to_spec.rb +23 -6
  58. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +2 -1
  59. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
  60. data/spec/mongoid/association/referenced/has_one_spec.rb +12 -2
  61. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  62. data/spec/mongoid/attributes_spec.rb +19 -7
  63. data/spec/mongoid/clients/factory_spec.rb +2 -2
  64. data/spec/mongoid/clients/options_spec.rb +4 -4
  65. data/spec/mongoid/clients/sessions_spec.rb +20 -7
  66. data/spec/mongoid/clients/transactions_spec.rb +36 -15
  67. data/spec/mongoid/clients_spec.rb +2 -2
  68. data/spec/mongoid/contextual/atomic_spec.rb +20 -10
  69. data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
  70. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  71. data/spec/mongoid/contextual/mongo_spec.rb +76 -53
  72. data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
  73. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  74. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  75. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
  76. data/spec/mongoid/criteria/queryable/key_spec.rb +48 -6
  77. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
  78. data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
  79. data/spec/mongoid/criteria/queryable/selector_spec.rb +37 -0
  80. data/spec/mongoid/criteria_spec.rb +7 -2
  81. data/spec/mongoid/document_fields_spec.rb +88 -0
  82. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  83. data/spec/mongoid/extensions/string_spec.rb +35 -7
  84. data/spec/mongoid/indexable_spec.rb +6 -4
  85. data/spec/mongoid/matchable/default_spec.rb +10 -3
  86. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  87. data/spec/mongoid/matchable_spec.rb +2 -2
  88. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  89. data/spec/mongoid/query_cache_spec.rb +2 -1
  90. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  91. data/spec/mongoid/scopable_spec.rb +2 -1
  92. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  93. data/spec/mongoid/tasks/database_spec.rb +1 -1
  94. data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
  95. data/spec/spec_helper.rb +4 -37
  96. data/spec/support/child_process_helper.rb +76 -0
  97. data/spec/support/cluster_config.rb +158 -0
  98. data/spec/support/constraints.rb +29 -19
  99. data/spec/support/expectations.rb +17 -3
  100. data/spec/support/spec_config.rb +12 -4
  101. metadata +525 -464
  102. metadata.gz.sig +2 -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 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)
@@ -841,4 +841,41 @@ describe Mongoid::Criteria::Queryable::Selector do
841
841
  end
842
842
  end
843
843
  end
844
+
845
+ describe '#multi_selection?' do
846
+
847
+ let(:selector) do
848
+ described_class.new
849
+ end
850
+
851
+ context 'when key is $and' do
852
+ it 'returns true' do
853
+ expect(selector.send(:multi_selection?, '$and')).to be true
854
+ end
855
+ end
856
+
857
+ context 'when key is $or' do
858
+ it 'returns true' do
859
+ expect(selector.send(:multi_selection?, '$or')).to be true
860
+ end
861
+ end
862
+
863
+ context 'when key is $nor' do
864
+ it 'returns true' do
865
+ expect(selector.send(:multi_selection?, '$nor')).to be true
866
+ end
867
+ end
868
+
869
+ context 'when key includes $or but is not $or' do
870
+ it 'returns false' do
871
+ expect(selector.send(:multi_selection?, '$ore')).to be false
872
+ end
873
+ end
874
+
875
+ context 'when key is some other ey' do
876
+ it 'returns false' do
877
+ expect(selector.send(:multi_selection?, 'foo')).to be false
878
+ end
879
+ end
880
+ end
844
881
  end
@@ -990,6 +990,7 @@ describe Mongoid::Criteria do
990
990
  end
991
991
 
992
992
  describe "#geo_near" do
993
+ max_server_version '4.0'
993
994
 
994
995
  before do
995
996
  Bar.create_indexes
@@ -2333,7 +2334,7 @@ describe Mongoid::Criteria do
2333
2334
  end
2334
2335
 
2335
2336
  it "returns the map/reduce results" do
2336
- expect(map_reduce).to eq([
2337
+ expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
2337
2338
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
2338
2339
  { "_id" => "Tool", "value" => { "likes" => 100 }}
2339
2340
  ])
@@ -3336,6 +3337,8 @@ describe Mongoid::Criteria do
3336
3337
  end
3337
3338
 
3338
3339
  describe "#max_scan" do
3340
+ max_server_version '4.0'
3341
+
3339
3342
  let!(:band) do
3340
3343
  Band.create(name: "Depeche Mode")
3341
3344
  end
@@ -3496,7 +3499,8 @@ describe Mongoid::Criteria do
3496
3499
  end
3497
3500
  end
3498
3501
 
3499
- context "when querying on a BSON::Decimal128", if: decimal128_supported? do
3502
+ context "when querying on a BSON::Decimal128" do
3503
+ min_server_version '3.4'
3500
3504
 
3501
3505
  let(:decimal) do
3502
3506
  BSON::Decimal128.new("0.0005")
@@ -3550,6 +3554,7 @@ describe Mongoid::Criteria do
3550
3554
  end
3551
3555
 
3552
3556
  context "when the code has scope" do
3557
+ max_server_version '4.2'
3553
3558
 
3554
3559
  let(:criteria) do
3555
3560
  Band.for_js("this.name == param", param: "Depeche Mode")
@@ -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
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Document do
7
+
8
+ let(:klass) do
9
+ Person
10
+ end
11
+
12
+ let(:person) do
13
+ Person.new
14
+ end
15
+
16
+ describe '.client_name' do
17
+ it 'returns client name' do
18
+ Person.client_name.should == :default
19
+ end
20
+ end
21
+
22
+ describe '.database_name' do
23
+ it 'returns database name' do
24
+ Person.database_name.should == 'mongoid_test'
25
+ end
26
+ end
27
+
28
+ describe '.collection_name' do
29
+ it 'returns collection name' do
30
+ Person.collection_name.should == :people
31
+ end
32
+ end
33
+ end