mongoid 7.2.6 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +16 -0
  5. data/lib/config/locales/en.yml +2 -15
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +11 -4
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +7 -2
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  18. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  19. data/lib/mongoid/association/relatable.rb +0 -2
  20. data/lib/mongoid/attributes/projector.rb +120 -0
  21. data/lib/mongoid/attributes.rb +24 -13
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients/factory.rb +22 -8
  24. data/lib/mongoid/clients.rb +1 -1
  25. data/lib/mongoid/config/environment.rb +1 -9
  26. data/lib/mongoid/config.rb +19 -2
  27. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  28. data/lib/mongoid/contextual/atomic.rb +2 -7
  29. data/lib/mongoid/contextual/none.rb +0 -3
  30. data/lib/mongoid/copyable.rb +1 -1
  31. data/lib/mongoid/criteria/findable.rb +1 -1
  32. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  33. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  34. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  35. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  36. data/lib/mongoid/criteria/queryable/selectable.rb +10 -10
  37. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  38. data/lib/mongoid/criteria.rb +5 -6
  39. data/lib/mongoid/document.rb +3 -18
  40. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors.rb +0 -2
  43. data/lib/mongoid/evolvable.rb +1 -1
  44. data/lib/mongoid/extensions/boolean.rb +1 -2
  45. data/lib/mongoid/extensions/false_class.rb +1 -1
  46. data/lib/mongoid/extensions/hash.rb +2 -2
  47. data/lib/mongoid/extensions/true_class.rb +1 -1
  48. data/lib/mongoid/fields.rb +43 -5
  49. data/lib/mongoid/inspectable.rb +1 -1
  50. data/lib/mongoid/interceptable.rb +1 -1
  51. data/lib/mongoid/matcher/bits.rb +41 -0
  52. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  53. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  54. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  55. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  56. data/lib/mongoid/matcher/expression.rb +4 -0
  57. data/lib/mongoid/matcher/field_operator.rb +6 -0
  58. data/lib/mongoid/matcher/mod.rb +17 -0
  59. data/lib/mongoid/matcher/type.rb +99 -0
  60. data/lib/mongoid/matcher.rb +7 -0
  61. data/lib/mongoid/persistable/deletable.rb +1 -2
  62. data/lib/mongoid/persistable/destroyable.rb +8 -2
  63. data/lib/mongoid/persistable/updatable.rb +27 -2
  64. data/lib/mongoid/persistence_context.rb +1 -3
  65. data/lib/mongoid/query_cache.rb +36 -40
  66. data/lib/mongoid/selectable.rb +5 -7
  67. data/lib/mongoid/shardable.rb +21 -5
  68. data/lib/mongoid/tasks/database.rb +1 -1
  69. data/lib/mongoid/touchable.rb +23 -4
  70. data/lib/mongoid/validatable/associated.rb +1 -1
  71. data/lib/mongoid/validatable/presence.rb +3 -3
  72. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  73. data/lib/mongoid/version.rb +1 -1
  74. data/lib/mongoid.rb +0 -1
  75. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  76. data/spec/integration/app_spec.rb +0 -3
  77. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  78. data/spec/integration/associations/has_one_spec.rb +48 -0
  79. data/spec/integration/criteria/date_field_spec.rb +1 -1
  80. data/spec/integration/document_spec.rb +9 -0
  81. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  82. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  83. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  84. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  85. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  86. data/spec/integration/matcher_operator_data/in.yml +16 -0
  87. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  88. data/spec/integration/matcher_operator_data/type.yml +70 -0
  89. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  90. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  91. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  92. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  94. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  95. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  96. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  97. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  98. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  100. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  102. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  104. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  105. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  106. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  107. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  108. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  109. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  110. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  111. data/spec/lite_spec_helper.rb +2 -0
  112. data/spec/mongoid/association/depending_spec.rb +391 -352
  113. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4 -17
  114. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  115. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -25
  116. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +0 -20
  117. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  118. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  119. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  120. data/spec/mongoid/association/referenced/has_many_models.rb +0 -17
  121. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  122. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  123. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  124. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  125. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  126. data/spec/mongoid/attributes_spec.rb +98 -6
  127. data/spec/mongoid/clients/factory_spec.rb +51 -9
  128. data/spec/mongoid/clients/options_spec.rb +3 -11
  129. data/spec/mongoid/config/environment_spec.rb +8 -86
  130. data/spec/mongoid/config_spec.rb +32 -0
  131. data/spec/mongoid/contextual/atomic_spec.rb +25 -64
  132. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  133. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  134. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  135. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  136. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  137. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  138. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  139. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  140. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  141. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  142. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  143. data/spec/mongoid/criteria_spec.rb +0 -279
  144. data/spec/mongoid/document_query_spec.rb +0 -51
  145. data/spec/mongoid/document_spec.rb +14 -34
  146. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  147. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -20
  148. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  149. data/spec/mongoid/extensions/string_spec.rb +5 -5
  150. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  151. data/spec/mongoid/fields/localized_spec.rb +4 -4
  152. data/spec/mongoid/fields_spec.rb +4 -4
  153. data/spec/mongoid/inspectable_spec.rb +12 -4
  154. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  155. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  156. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  157. data/spec/mongoid/persistable/updatable_spec.rb +0 -2
  158. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  159. data/spec/mongoid/persistable_spec.rb +2 -2
  160. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  161. data/spec/mongoid/query_cache_spec.rb +0 -24
  162. data/spec/mongoid/reloadable_spec.rb +18 -1
  163. data/spec/mongoid/shardable_spec.rb +44 -0
  164. data/spec/mongoid/touchable_spec.rb +104 -16
  165. data/spec/mongoid/touchable_spec_models.rb +52 -0
  166. data/spec/mongoid/validatable_spec.rb +1 -1
  167. data/spec/shared/lib/mrss/cluster_config.rb +3 -8
  168. data/spec/shared/lib/mrss/constraints.rb +10 -41
  169. data/spec/shared/lib/mrss/docker_runner.rb +1 -7
  170. data/spec/shared/lib/mrss/server_version_registry.rb +12 -17
  171. data/spec/shared/lib/mrss/spec_organizer.rb +1 -18
  172. data/spec/shared/share/Dockerfile.erb +33 -125
  173. data/spec/shared/shlib/server.sh +23 -100
  174. data/spec/shared/shlib/set_env.sh +1 -4
  175. data/spec/spec_helper.rb +7 -3
  176. data/spec/support/client_registry.rb +9 -0
  177. data/spec/support/models/address.rb +0 -4
  178. data/spec/support/models/bolt.rb +8 -0
  179. data/spec/support/models/hole.rb +13 -0
  180. data/spec/support/models/mop.rb +0 -1
  181. data/spec/support/models/nut.rb +8 -0
  182. data/spec/support/models/person.rb +6 -9
  183. data/spec/support/models/sealer.rb +8 -0
  184. data/spec/support/models/shirt.rb +12 -0
  185. data/spec/support/models/spacer.rb +8 -0
  186. data/spec/support/models/threadlocker.rb +8 -0
  187. data/spec/support/models/washer.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +609 -545
  190. metadata.gz.sig +0 -0
  191. data/lib/mongoid/errors/empty_config_file.rb +0 -26
  192. data/lib/mongoid/errors/invalid_config_file.rb +0 -26
  193. data/spec/integration/contextual/empty_spec.rb +0 -142
  194. data/spec/mongoid/errors/invalid_config_file_spec.rb +0 -32
  195. data/spec/shared/bin/s3-copy +0 -45
  196. data/spec/shared/bin/s3-upload +0 -69
  197. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  198. data/spec/shared/share/haproxy-1.conf +0 -16
  199. data/spec/shared/share/haproxy-2.conf +0 -17
  200. data/spec/support/cluster_config.rb +0 -158
@@ -2449,26 +2449,13 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2449
2449
  end
2450
2450
 
2451
2451
  context "when providing a criteria class method" do
2452
- context "without keyword arguments" do
2453
2452
 
2454
- let(:addresses) do
2455
- person.addresses.california
2456
- end
2457
-
2458
- it "applies the criteria to the documents" do
2459
- expect(addresses).to eq([ address_one ])
2460
- end
2453
+ let(:addresses) do
2454
+ person.addresses.california
2461
2455
  end
2462
2456
 
2463
- context "with keyword arguments" do
2464
-
2465
- let(:addresses) do
2466
- person.addresses.city_and_state(city: "Sacramento", state: "CA")
2467
- end
2468
-
2469
- it "applies the criteria to the documents" do
2470
- expect(addresses).to eq([])
2471
- end
2457
+ it "applies the criteria to the documents" do
2458
+ expect(addresses).to eq([ address_one ])
2472
2459
  end
2473
2460
  end
2474
2461
 
@@ -137,20 +137,24 @@ describe Mongoid::Association::Nested::One do
137
137
  { allow_destroy: true }
138
138
  end
139
139
 
140
- let(:builder) do
141
- described_class.new(association, {
142
- id: name.id,
143
- last_name: "Lang",
144
- _destroy: true
145
- }, options)
146
- end
147
-
148
- before do
149
- builder.build(person)
150
- end
151
-
152
- it "deletes the relation" do
153
- expect(person.name).to be_nil
140
+ %i(id _id).each do |id_field|
141
+ context "#{id_field}" do
142
+ let(:builder) do
143
+ described_class.new(association, {
144
+ id_field => name.id,
145
+ last_name: "Lang",
146
+ _destroy: true
147
+ }, options)
148
+ end
149
+
150
+ before do
151
+ builder.build(person)
152
+ end
153
+
154
+ it "deletes the relation" do
155
+ expect(person.name).to be_nil
156
+ end
157
+ end
154
158
  end
155
159
  end
156
160
  end
@@ -127,6 +127,23 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
127
127
  it "does not save the target" do
128
128
  expect(person).to_not be_persisted
129
129
  end
130
+
131
+ it "drops private visibility from private methods" do
132
+ # This is unfortunate but it appears that Ruby does not
133
+ # have a way to distinguish how method_missing was invoked
134
+ # (i.e. via an explicit send or method call).
135
+ # See https://jira.mongodb.org/browse/MONGOID-5009
136
+ game.person.secret_name.should == 'secret'
137
+ end
138
+
139
+ it "allows private methods to be invoked" do
140
+ game.person.send(:secret_name).should == 'secret'
141
+ end
142
+
143
+ it "properly exposes delegated methods visibility" do
144
+ expect(defined?(game.person.id)).to eq("method")
145
+ expect(defined?(game.person.secret_name)).to be_nil
146
+ end
130
147
  end
131
148
 
132
149
  context "when the child is not a new record" do
@@ -508,7 +525,7 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
508
525
  context "when child is destroyed" do
509
526
 
510
527
  before do
511
- account.delete
528
+ account.destroy
512
529
  end
513
530
 
514
531
  it "deletes child" do
@@ -548,7 +565,7 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
548
565
  context "when child is destroyed" do
549
566
 
550
567
  before do
551
- drug.delete
568
+ drug.destroy
552
569
  end
553
570
 
554
571
  it "deletes child" do
@@ -600,10 +617,10 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
600
617
 
601
618
  context "when parent is persisted" do
602
619
 
603
- context "when child is deleted" do
620
+ context "when child is destroyed" do
604
621
 
605
622
  before do
606
- account.delete
623
+ account.destroy
607
624
  end
608
625
 
609
626
  it "deletes child" do
@@ -643,7 +660,7 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
643
660
  context "when child is destroyed" do
644
661
 
645
662
  before do
646
- drug.delete
663
+ drug.destroy
647
664
  end
648
665
 
649
666
  it "deletes child" do
@@ -690,10 +707,10 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
690
707
 
691
708
  context "when parent is persisted" do
692
709
 
693
- context "when child is deleted" do
710
+ context "when child is destroyed" do
694
711
 
695
712
  before do
696
- account.delete
713
+ account.destroy
697
714
  end
698
715
 
699
716
  it "deletes child" do
@@ -732,7 +749,7 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
732
749
  context "when child is destroyed" do
733
750
 
734
751
  before do
735
- drug.delete
752
+ drug.destroy
736
753
  end
737
754
 
738
755
  it "deletes child" do
@@ -1332,21 +1349,4 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
1332
1349
  end
1333
1350
  end
1334
1351
  end
1335
-
1336
- describe "#method_missing" do
1337
- let!(:person) do
1338
- Person.create
1339
- end
1340
-
1341
- let!(:game) do
1342
- Game.create(person: person)
1343
- end
1344
-
1345
- it 'handles keyword args' do
1346
- expect do
1347
- game.person.set_personal_data(ssn: '123', age: 25)
1348
- end.not_to raise_error
1349
- end
1350
-
1351
- end
1352
1352
  end
@@ -35,24 +35,4 @@ describe Mongoid::Association::Referenced::BelongsTo do
35
35
  expect(school.team).to eq('Bulldogs')
36
36
  end
37
37
  end
38
-
39
- context 'when projecting with #only while having similar inverse_of candidates' do
40
- before do
41
- alice = HmmOwner.create!(name: 'Alice')
42
- bob = HmmOwner.create!(name: 'Bob')
43
-
44
- HmmPet.create!(name: 'Rex', current_owner: bob, previous_owner: alice)
45
- end
46
-
47
- let(:pet) { HmmPet.where(name: 'Rex').only(:name, :previous_owner_id, 'previous_owner.name').first }
48
-
49
- it 'populates specified fields' do
50
- expect(pet.name).to eq('Rex')
51
- expect(pet.previous_owner.name).to eq('Alice')
52
- end
53
-
54
- it 'does not try to load the inverse for an association that explicitly prevents it' do
55
- expect { pet.previous_owner.name }.not_to raise_error
56
- end
57
- end
58
38
  end
@@ -14,7 +14,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Binding do
14
14
  end
15
15
 
16
16
  let(:target) do
17
- Mongoid::Association::Referenced::HasMany::Targets::Enumerable.new([ preference ])
17
+ Mongoid::Association::Referenced::HasMany::Enumerable.new([ preference ])
18
18
  end
19
19
 
20
20
  let(:association) do
@@ -14,7 +14,7 @@ describe Mongoid::Association::Referenced::HasMany::Binding do
14
14
  end
15
15
 
16
16
  let(:target) do
17
- Mongoid::Association::Referenced::HasMany::Targets::Enumerable.new([ post ])
17
+ Mongoid::Association::Referenced::HasMany::Enumerable.new([ post ])
18
18
  end
19
19
 
20
20
  let(:association) do
@@ -3,7 +3,7 @@
3
3
 
4
4
  require "spec_helper"
5
5
 
6
- describe Mongoid::Association::Referenced::HasMany::Targets::Enumerable do
6
+ describe Mongoid::Association::Referenced::HasMany::Enumerable do
7
7
 
8
8
  describe "#==" do
9
9
 
@@ -24,23 +24,6 @@ class HmmAddress
24
24
  belongs_to :company, class_name: 'HmmCompany'
25
25
  end
26
26
 
27
- class HmmOwner
28
- include Mongoid::Document
29
-
30
- has_many :pets, class_name: 'HmmPet', inverse_of: :current_owner
31
-
32
- field :name, type: String
33
- end
34
-
35
- class HmmPet
36
- include Mongoid::Document
37
-
38
- belongs_to :current_owner, class_name: 'HmmOwner', inverse_of: :pets, optional: true
39
- belongs_to :previous_owner, class_name: 'HmmOwner', inverse_of: nil, optional: true
40
-
41
- field :name, type: String
42
- end
43
-
44
27
  class HmmSchool
45
28
  include Mongoid::Document
46
29
 
@@ -19,6 +19,14 @@ class HomAccreditation
19
19
 
20
20
  field :degree, type: String
21
21
  field :year, type: Integer, default: 2012
22
+
23
+ def format
24
+ 'fmt'
25
+ end
26
+
27
+ def price
28
+ 42
29
+ end
22
30
  end
23
31
 
24
32
  class HomAccreditation::Child
@@ -113,10 +113,33 @@ describe Mongoid::Atomic::Paths do
113
113
  person.addresses << address
114
114
  end
115
115
 
116
- it "returns the association with id.atomic_selector" do
117
- expect(address.atomic_selector).to eq(
118
- { "_id" => person.id, "addresses._id" => address.id }
119
- )
116
+ context 'when the parent is persisted' do
117
+
118
+ let(:person) do
119
+ Person.create!
120
+ end
121
+
122
+ before do
123
+ person.should be_persisted
124
+ end
125
+
126
+ it "returns the association with id.atomic_selector" do
127
+ expect(address.atomic_selector).to eq(
128
+ { "_id" => person.id, "addresses._id" => address.id }
129
+ )
130
+ end
131
+ end
132
+
133
+ context 'when the parent is not persisted' do
134
+ before do
135
+ person.should be_new_record
136
+ end
137
+
138
+ it "returns the association with id.atomic_selector" do
139
+ expect(address.atomic_selector).to eq(
140
+ { "_id" => person.id, "addresses._id" => address.id }
141
+ )
142
+ end
120
143
  end
121
144
  end
122
145
 
@@ -127,14 +150,43 @@ describe Mongoid::Atomic::Paths do
127
150
  person.addresses << address
128
151
  end
129
152
 
130
- it "returns the JSON notation to the document with ids" do
131
- expect(location.atomic_selector).to eq(
132
- {
133
- "_id" => person.id,
134
- "addresses._id" => address.id,
135
- "addresses.locations._id" => location.id
136
- }
137
- )
153
+ context 'when the parent is persisted' do
154
+
155
+ let(:person) do
156
+ Person.create!
157
+ end
158
+
159
+ before do
160
+ person.should be_persisted
161
+ end
162
+
163
+ it "returns the JSON notation to the document with ids" do
164
+ expect(location.atomic_selector).to eq(
165
+ {
166
+ "_id" => person.id,
167
+ "addresses._id" => address.id,
168
+ "addresses.0.locations._id" => location.id
169
+ }
170
+ )
171
+ end
172
+ end
173
+
174
+ context 'when the parent is not persisted' do
175
+ before do
176
+ person.should be_new_record
177
+ end
178
+
179
+ it "returns the JSON notation to the document with ids" do
180
+ expect(location.atomic_selector).to eq(
181
+ {
182
+ "_id" => person.id,
183
+ "addresses._id" => address.id,
184
+ # This condition is technically acceptable for finds
185
+ # but probably won't work for modifications of 'locations'.
186
+ "addresses.locations._id" => location.id
187
+ }
188
+ )
189
+ end
138
190
  end
139
191
  end
140
192
  end
@@ -0,0 +1,105 @@
1
+ - name: embedded field - inclusion
2
+ projection:
3
+ foo.bar: 1
4
+
5
+ queries: &embedded-field-inclusion-expectations
6
+ # Top-level field is allowed as a container
7
+ - query: foo
8
+ allowed: true
9
+
10
+ # Unmentioned field is not allowed
11
+ - query: bar
12
+ allowed: false
13
+
14
+ # A peer to the field isn't allowed
15
+ - query: foo.buck
16
+ allowed: false
17
+
18
+ # A more nested field is allowed
19
+ - query: foo.bar.baz
20
+ allowed: true
21
+
22
+ - name: embedded field - exclusion
23
+ projection:
24
+ foo.bar: 0
25
+
26
+ queries: &embedded-field-exclusion-expectations
27
+ # Top-level field is allowed
28
+ - query: foo
29
+ allowed: true
30
+
31
+ # Unmentioned field is allowed
32
+ - query: bar
33
+ allowed: true
34
+
35
+ # A peer to the excluded field is allowed
36
+ - query: foo.buck
37
+ allowed: true
38
+
39
+ # A more nested field is not allowed
40
+ - query: foo.bar.baz
41
+ allowed: false
42
+
43
+ - name: parent and child fields - inclusion
44
+ projection:
45
+ foo.bar: 1
46
+ foo.bar.baz: 1
47
+
48
+ queries:
49
+ # Top-level field is allowed
50
+ - query: foo
51
+ allowed: true
52
+
53
+ # Second-level field is allowed
54
+ - query: foo.bar
55
+ allowed: true
56
+
57
+ # Third-level field is also allowed
58
+ - query: foo.bar.baz
59
+ allowed: true
60
+
61
+ # Fourth-level field is still allowed
62
+ - query: foo.bar.baz.zzz
63
+ allowed: true
64
+
65
+ # Unmentioned siblings are not allowed
66
+ - query: buck
67
+ allowed: false
68
+ - query: foo.buck
69
+ allowed: false
70
+
71
+ # This sibling is under the second-level include and is allowed
72
+ - query: foo.bar.buck
73
+ allowed: true
74
+
75
+ - name: parent and child fields - exclusion
76
+ projection:
77
+ foo.bar: 0
78
+ foo.bar.baz: 0
79
+
80
+ queries:
81
+ # Top-level field is allowed
82
+ - query: foo
83
+ allowed: true
84
+
85
+ # Second-level field is not allowed
86
+ - query: foo.bar
87
+ allowed: false
88
+
89
+ # Third-level field is also not allowed
90
+ - query: foo.bar.baz
91
+ allowed: false
92
+
93
+ # Fourth-level field is still not allowed
94
+ - query: foo.bar.baz.zzz
95
+ allowed: false
96
+
97
+ # Unmentioned siblings are allowed
98
+ - query: buck
99
+ allowed: true
100
+ - query: foo.buck
101
+ allowed: true
102
+
103
+ # This sibling is under the second-level exclude and is disallowed
104
+ - query: foo.bar.buck
105
+ allowed: false
@@ -0,0 +1,93 @@
1
+ - name: simple inclusion - integer
2
+ projection:
3
+ foo: 1
4
+
5
+ queries: &field-inclusion-expectations
6
+ - query: foo
7
+ allowed: true
8
+ - query: bar
9
+ allowed: false
10
+
11
+ - name: simple inclusion - boolean
12
+ projection:
13
+ foo: true
14
+
15
+ queries: &field-inclusion-expectations
16
+ - query: foo
17
+ allowed: true
18
+ - query: bar
19
+ allowed: false
20
+
21
+ - name: positive integer - inclusion
22
+ projection:
23
+ foo: 2
24
+
25
+ queries: *field-inclusion-expectations
26
+
27
+ - name: simple exclusion - integer
28
+ projection:
29
+ foo: 0
30
+
31
+ queries: &field-exclusion-expectations
32
+ - query: foo
33
+ allowed: false
34
+ - query: bar
35
+ allowed: true
36
+
37
+ - name: simple exclusion - boolean
38
+ projection:
39
+ foo: false
40
+
41
+ queries: &field-exclusion-expectations
42
+ - query: foo
43
+ allowed: false
44
+ - query: bar
45
+ allowed: true
46
+
47
+ - name: negative integer - exclusion
48
+ projection:
49
+ foo: -2
50
+
51
+ queries: *field-exclusion-expectations
52
+
53
+ - name: field inclusion with _id exclusion
54
+ projection:
55
+ foo: 1
56
+ _id: 0
57
+
58
+ queries: &field-inclusion-with-id-exclusion-expectations
59
+ - query: foo
60
+ allowed: true
61
+
62
+ - query: bar
63
+ allowed: false
64
+
65
+ - query: _id
66
+ allowed: false
67
+
68
+ - name: _id exclusion with field inclusion
69
+ projection:
70
+ _id: 0
71
+ foo: 1
72
+
73
+ queries: *field-inclusion-with-id-exclusion-expectations
74
+
75
+ - name: id inclusion
76
+ projection:
77
+ _id: 1
78
+
79
+ queries:
80
+ - query: _id
81
+ allowed: true
82
+ - query: foo
83
+ allowed: false
84
+
85
+ - name: id exclusion
86
+ projection:
87
+ _id: false
88
+
89
+ queries:
90
+ - query: _id
91
+ allowed: false
92
+ - query: foo
93
+ allowed: true
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Attributes::Projector do
7
+ Dir[File.join(File.dirname(__FILE__), 'projector_data', '*.yml')].sort.each do |path|
8
+ context File.basename(path) do
9
+ specs = YAML.load(File.read(path))
10
+
11
+ specs.each do |spec|
12
+ context spec['name'] do
13
+
14
+ if spec['pending']
15
+ pending spec['pending'].to_s
16
+ end
17
+
18
+ let(:projection) do
19
+ spec['projection']
20
+ end
21
+
22
+ let(:projector) do
23
+ Mongoid::Attributes::Projector.new(projection)
24
+ end
25
+
26
+ spec.fetch('queries').each do |query_spec|
27
+ context query_spec.fetch('query').inspect do
28
+ let(:query) { query_spec['query'] }
29
+
30
+ context 'attribute_or_path_allowed?' do
31
+ it "is #{query_spec.fetch('allowed')}" do
32
+ projector.attribute_or_path_allowed?(query).should be query_spec['allowed']
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end