mongoid 7.0.4 → 7.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -0
  5. data/README.md +3 -2
  6. data/Rakefile +26 -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/atomic.rb +13 -3
  12. data/lib/mongoid/atomic/paths/embedded.rb +1 -1
  13. data/lib/mongoid/attributes.rb +28 -20
  14. data/lib/mongoid/attributes/dynamic.rb +15 -14
  15. data/lib/mongoid/clients/sessions.rb +20 -4
  16. data/lib/mongoid/config/environment.rb +21 -8
  17. data/lib/mongoid/criteria.rb +7 -1
  18. data/lib/mongoid/criteria/modifiable.rb +13 -2
  19. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  20. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  21. data/lib/mongoid/criteria/queryable/extensions/time.rb +1 -1
  22. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
  23. data/lib/mongoid/criteria/queryable/key.rb +67 -8
  24. data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
  25. data/lib/mongoid/criteria/queryable/selectable.rb +3 -4
  26. data/lib/mongoid/criteria/queryable/selector.rb +9 -31
  27. data/lib/mongoid/extensions/hash.rb +4 -2
  28. data/lib/mongoid/extensions/regexp.rb +1 -1
  29. data/lib/mongoid/extensions/string.rb +2 -2
  30. data/lib/mongoid/fields.rb +2 -1
  31. data/lib/mongoid/matchable.rb +14 -15
  32. data/lib/mongoid/matchable/all.rb +4 -3
  33. data/lib/mongoid/matchable/default.rb +71 -24
  34. data/lib/mongoid/matchable/regexp.rb +2 -2
  35. data/lib/mongoid/persistable/pushable.rb +11 -2
  36. data/lib/mongoid/persistence_context.rb +6 -6
  37. data/lib/mongoid/positional.rb +1 -1
  38. data/lib/mongoid/query_cache.rb +24 -11
  39. data/lib/mongoid/validatable/macros.rb +1 -1
  40. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  41. data/lib/mongoid/version.rb +2 -1
  42. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  43. data/spec/README.md +18 -0
  44. data/spec/app/models/delegating_patient.rb +16 -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/date_field_spec.rb +41 -0
  48. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  49. data/spec/integration/document_spec.rb +22 -0
  50. data/spec/integration/matchable_spec.rb +680 -0
  51. data/spec/lite_spec_helper.rb +15 -5
  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_spec.rb +0 -2
  55. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +140 -1
  56. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
  57. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
  58. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  59. data/spec/mongoid/attributes_spec.rb +19 -7
  60. data/spec/mongoid/clients/factory_spec.rb +2 -2
  61. data/spec/mongoid/clients/options_spec.rb +4 -4
  62. data/spec/mongoid/clients/sessions_spec.rb +20 -7
  63. data/spec/mongoid/clients/transactions_spec.rb +36 -15
  64. data/spec/mongoid/clients_spec.rb +2 -2
  65. data/spec/mongoid/contextual/atomic_spec.rb +20 -10
  66. data/spec/mongoid/contextual/geo_near_spec.rb +12 -2
  67. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  68. data/spec/mongoid/contextual/mongo_spec.rb +76 -53
  69. data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
  70. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  71. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  72. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
  73. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
  74. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
  75. data/spec/mongoid/criteria/queryable/key_spec.rb +48 -6
  76. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
  77. data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
  78. data/spec/mongoid/criteria/queryable/selector_spec.rb +37 -0
  79. data/spec/mongoid/criteria_spec.rb +7 -2
  80. data/spec/mongoid/document_fields_spec.rb +88 -0
  81. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  82. data/spec/mongoid/indexable_spec.rb +6 -4
  83. data/spec/mongoid/matchable/default_spec.rb +10 -3
  84. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  85. data/spec/mongoid/matchable_spec.rb +2 -2
  86. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  87. data/spec/mongoid/query_cache_spec.rb +62 -8
  88. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  89. data/spec/mongoid/scopable_spec.rb +2 -1
  90. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  91. data/spec/mongoid/tasks/database_spec.rb +1 -1
  92. data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
  93. data/spec/spec_helper.rb +4 -37
  94. data/spec/support/child_process_helper.rb +76 -0
  95. data/spec/support/cluster_config.rb +158 -0
  96. data/spec/support/constraints.rb +201 -30
  97. data/spec/support/expectations.rb +17 -3
  98. data/spec/support/spec_config.rb +12 -4
  99. metadata +490 -454
  100. 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 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