mongoid 7.2.0 → 7.3.0

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 (191) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Rakefile +16 -0
  4. data/lib/config/locales/en.yml +2 -2
  5. data/lib/mongoid/association/accessors.rb +1 -1
  6. data/lib/mongoid/association/constrainable.rb +1 -1
  7. data/lib/mongoid/association/depending.rb +4 -4
  8. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  9. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  10. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  11. data/lib/mongoid/association/nested/many.rb +1 -1
  12. data/lib/mongoid/association/nested/one.rb +4 -2
  13. data/lib/mongoid/association/proxy.rb +6 -1
  14. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  15. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  16. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  17. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  18. data/lib/mongoid/attributes/projector.rb +120 -0
  19. data/lib/mongoid/attributes.rb +32 -14
  20. data/lib/mongoid/cacheable.rb +2 -2
  21. data/lib/mongoid/clients/factory.rb +22 -8
  22. data/lib/mongoid/clients.rb +1 -1
  23. data/lib/mongoid/config.rb +19 -2
  24. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  25. data/lib/mongoid/copyable.rb +1 -1
  26. data/lib/mongoid/criteria/findable.rb +1 -1
  27. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  28. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  29. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  30. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  31. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  32. data/lib/mongoid/criteria/queryable/selector.rb +0 -4
  33. data/lib/mongoid/criteria.rb +4 -5
  34. data/lib/mongoid/document.rb +4 -17
  35. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  36. data/lib/mongoid/evolvable.rb +1 -1
  37. data/lib/mongoid/extensions/boolean.rb +1 -2
  38. data/lib/mongoid/extensions/false_class.rb +1 -1
  39. data/lib/mongoid/extensions/hash.rb +2 -2
  40. data/lib/mongoid/extensions/true_class.rb +1 -1
  41. data/lib/mongoid/fields.rb +43 -5
  42. data/lib/mongoid/inspectable.rb +1 -1
  43. data/lib/mongoid/interceptable.rb +3 -1
  44. data/lib/mongoid/matcher/bits.rb +41 -0
  45. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  46. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  47. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  48. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  49. data/lib/mongoid/matcher/elem_match.rb +2 -1
  50. data/lib/mongoid/matcher/expression.rb +9 -14
  51. data/lib/mongoid/matcher/field_expression.rb +4 -5
  52. data/lib/mongoid/matcher/field_operator.rb +13 -11
  53. data/lib/mongoid/matcher/mod.rb +17 -0
  54. data/lib/mongoid/matcher/type.rb +99 -0
  55. data/lib/mongoid/matcher.rb +26 -43
  56. data/lib/mongoid/persistable/deletable.rb +1 -2
  57. data/lib/mongoid/persistable/destroyable.rb +8 -2
  58. data/lib/mongoid/persistable/updatable.rb +27 -2
  59. data/lib/mongoid/query_cache.rb +35 -29
  60. data/lib/mongoid/reloadable.rb +5 -0
  61. data/lib/mongoid/selectable.rb +5 -7
  62. data/lib/mongoid/shardable.rb +21 -5
  63. data/lib/mongoid/touchable.rb +23 -4
  64. data/lib/mongoid/version.rb +1 -1
  65. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  66. data/spec/integration/app_spec.rb +171 -84
  67. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  68. data/spec/integration/associations/has_one_spec.rb +48 -0
  69. data/spec/integration/callbacks_models.rb +49 -0
  70. data/spec/integration/callbacks_spec.rb +216 -0
  71. data/spec/integration/criteria/date_field_spec.rb +1 -1
  72. data/spec/integration/document_spec.rb +30 -0
  73. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  74. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  75. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  76. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  77. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  78. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  79. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  80. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  81. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  82. data/spec/integration/matcher_operator_data/in.yml +16 -0
  83. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  84. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  85. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  86. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  87. data/spec/integration/matcher_operator_data/type.yml +70 -0
  88. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  89. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  90. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  91. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  92. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  94. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  95. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  96. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  97. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  98. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  100. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  102. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  104. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  105. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  106. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  107. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  108. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  109. data/spec/lite_spec_helper.rb +5 -4
  110. data/spec/mongoid/association/depending_spec.rb +391 -352
  111. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
  112. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  113. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  114. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  115. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  116. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  117. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  118. data/spec/mongoid/atomic/paths_spec.rb +105 -12
  119. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  120. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  121. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  122. data/spec/mongoid/attributes_spec.rb +333 -0
  123. data/spec/mongoid/clients/factory_spec.rb +48 -0
  124. data/spec/mongoid/config_spec.rb +32 -0
  125. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  126. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  127. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  128. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  129. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  130. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  131. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +265 -24
  132. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  133. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  134. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  135. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  136. data/spec/mongoid/criteria_spec.rb +0 -275
  137. data/spec/mongoid/document_fields_spec.rb +26 -0
  138. data/spec/mongoid/document_spec.rb +13 -13
  139. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  140. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  141. data/spec/mongoid/extensions/string_spec.rb +5 -5
  142. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  143. data/spec/mongoid/fields/localized_spec.rb +4 -4
  144. data/spec/mongoid/fields_spec.rb +4 -4
  145. data/spec/mongoid/inspectable_spec.rb +12 -4
  146. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  147. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  148. data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
  149. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  150. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  151. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  152. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  153. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  154. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  155. data/spec/mongoid/reloadable_spec.rb +18 -1
  156. data/spec/mongoid/shardable_spec.rb +44 -0
  157. data/spec/mongoid/touchable_spec.rb +104 -16
  158. data/spec/mongoid/touchable_spec_models.rb +52 -0
  159. data/spec/mongoid/validatable_spec.rb +1 -1
  160. data/spec/shared/bin/get-mongodb-download-url +17 -0
  161. data/spec/shared/lib/mrss/cluster_config.rb +221 -0
  162. data/spec/shared/lib/mrss/constraints.rb +51 -0
  163. data/spec/shared/lib/mrss/docker_runner.rb +265 -0
  164. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  165. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  166. data/spec/shared/lib/mrss/spec_organizer.rb +14 -1
  167. data/spec/shared/lib/mrss/utils.rb +15 -0
  168. data/spec/shared/share/Dockerfile.erb +231 -0
  169. data/spec/shared/shlib/distro.sh +73 -0
  170. data/spec/shared/shlib/server.sh +290 -0
  171. data/spec/shared/shlib/set_env.sh +128 -0
  172. data/spec/spec_helper.rb +6 -2
  173. data/spec/support/client_registry.rb +9 -0
  174. data/spec/support/models/bolt.rb +8 -0
  175. data/spec/support/models/customer.rb +11 -0
  176. data/spec/support/models/customer_address.rb +12 -0
  177. data/spec/support/models/dictionary.rb +6 -0
  178. data/spec/support/models/hole.rb +13 -0
  179. data/spec/support/models/mop.rb +9 -0
  180. data/spec/support/models/nut.rb +8 -0
  181. data/spec/support/models/person.rb +6 -0
  182. data/spec/support/models/sealer.rb +8 -0
  183. data/spec/support/models/shirt.rb +12 -0
  184. data/spec/support/models/spacer.rb +8 -0
  185. data/spec/support/models/threadlocker.rb +8 -0
  186. data/spec/support/models/washer.rb +8 -0
  187. data/spec/support/spec_config.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +146 -14
  190. metadata.gz.sig +5 -2
  191. data/spec/support/cluster_config.rb +0 -158
@@ -85,4 +85,30 @@ describe Mongoid::Document do
85
85
  end
86
86
  end
87
87
  end
88
+
89
+ context 'Regexp field' do
90
+ shared_examples "persists strings as regexp" do |type|
91
+ it 'persists strings as regexp' do
92
+ mop = Mop.create!(regexp_field: 'foo')
93
+ expect(mop.regexp_field).to be_a Regexp
94
+ expect(Mop.find(mop.id).regexp_field).to be_a BSON::Regexp::Raw
95
+ expect(
96
+ Mop.collection.find(
97
+ "_id" => mop.id,
98
+ "regexp_field" => { "$type" => type }
99
+ ).count
100
+ ).to be == 1
101
+ end
102
+ end
103
+
104
+ context "< 3.2" do
105
+ max_server_version("3.1")
106
+ include_examples "persists strings as regexp", 11
107
+ end
108
+
109
+ context ">= 3.2" do
110
+ min_server_version("3.2")
111
+ it_behaves_like "persists strings as regexp", "regex"
112
+ end
113
+ end
88
114
  end
@@ -124,13 +124,13 @@ describe Mongoid::Document do
124
124
  describe "._mongoid_clear_types" do
125
125
 
126
126
  context "when changing the discriminator_value" do
127
-
128
- before do
127
+
128
+ before do
129
129
  Kangaroo._types
130
130
  Kangaroo.discriminator_value = "dvalue"
131
131
  end
132
132
 
133
- after do
133
+ after do
134
134
  Kangaroo.discriminator_value = nil
135
135
  end
136
136
 
@@ -140,13 +140,13 @@ describe Mongoid::Document do
140
140
  end
141
141
 
142
142
  context "when changing the discriminator_value in child" do
143
-
144
- before do
143
+
144
+ before do
145
145
  Shape._types
146
146
  Circle.discriminator_value = "dvalue"
147
147
  end
148
148
 
149
- after do
149
+ after do
150
150
  Circle.discriminator_value = nil
151
151
  end
152
152
 
@@ -924,7 +924,7 @@ describe Mongoid::Document do
924
924
  end
925
925
 
926
926
  context "when no embedded documents are present" do
927
- context "when using the default discriminator key" do
927
+ context "when using the default discriminator key" do
928
928
  let(:person) do
929
929
  manager.becomes(Person)
930
930
  end
@@ -948,12 +948,12 @@ describe Mongoid::Document do
948
948
  end
949
949
  end
950
950
 
951
- context "when using a custom discriminator key" do
952
- before do
951
+ context "when using a custom discriminator key" do
952
+ before do
953
953
  Person.discriminator_key = "dkey"
954
954
  end
955
955
 
956
- after do
956
+ after do
957
957
  Person.discriminator_key = nil
958
958
  end
959
959
 
@@ -962,13 +962,13 @@ describe Mongoid::Document do
962
962
  end
963
963
  end
964
964
 
965
- context "when using a custom discriminator key and discriminator value" do
966
- before do
965
+ context "when using a custom discriminator key and discriminator value" do
966
+ before do
967
967
  Person.discriminator_key = "dkey"
968
968
  Person.discriminator_value = "dvalue"
969
969
  end
970
970
 
971
- after do
971
+ after do
972
972
  Person.discriminator_key = nil
973
973
  Person.discriminator_value = nil
974
974
  end
@@ -13,7 +13,7 @@ describe Mongoid::Errors::DeleteRestriction do
13
13
 
14
14
  it "contains the problem in the message" do
15
15
  expect(error.message).to include(
16
- "Cannot delete Person because of dependent 'drugs'."
16
+ "Cannot destroy Person because of dependent 'drugs'."
17
17
  )
18
18
  end
19
19
 
@@ -17,7 +17,7 @@ describe Mongoid::Extensions::FalseClass do
17
17
  context "when provided a Boolean" do
18
18
 
19
19
  it "returns true" do
20
- expect(false.is_a?(Boolean)).to be true
20
+ expect(false.is_a?(Mongoid::Boolean)).to be true
21
21
  end
22
22
  end
23
23
 
@@ -158,16 +158,16 @@ describe Mongoid::Extensions::String do
158
158
  Time.now.utc_offset
159
159
  end
160
160
 
161
- before do
162
- expect(utc_offset).not_to eq(Time.zone.now.utc_offset)
163
- end
164
-
165
- let(:expected_time) { Time.parse("2010-11-19 00:24:49.123457 +0000").in_time_zone - utc_offset }
161
+ let(:expected_time) { Time.parse("2010-11-19 00:24:49.123457 +0000") - Time.parse(string).utc_offset }
166
162
 
167
163
  let(:mongoized) do
168
164
  string.__mongoize_time__
169
165
  end
170
166
 
167
+ it 'test operates in multiple time zones' do
168
+ expect(utc_offset).not_to eq(Time.zone.now.utc_offset)
169
+ end
170
+
171
171
  it_behaves_like 'mongoizes to Time'
172
172
  it_behaves_like 'maintains precision when mongoized'
173
173
  end
@@ -17,7 +17,7 @@ describe Mongoid::Extensions::TrueClass do
17
17
  context "when provided a Boolean" do
18
18
 
19
19
  it "returns true" do
20
- expect(true.is_a?(Boolean)).to be true
20
+ expect(true.is_a?(Mongoid::Boolean)).to be true
21
21
  end
22
22
  end
23
23
 
@@ -448,7 +448,7 @@ describe Mongoid::Fields::Localized do
448
448
  context "when the value is false" do
449
449
 
450
450
  let(:field) do
451
- described_class.new(:boolean_value, localize: true, type: Boolean)
451
+ described_class.new(:boolean_value, localize: true, type: Mongoid::Boolean)
452
452
  end
453
453
 
454
454
  let(:value) do
@@ -463,7 +463,7 @@ describe Mongoid::Fields::Localized do
463
463
  context "when the value is true" do
464
464
 
465
465
  let(:field) do
466
- described_class.new(:boolean_value, localize: true, type: Boolean)
466
+ described_class.new(:boolean_value, localize: true, type: Mongoid::Boolean)
467
467
  end
468
468
 
469
469
  let(:value) do
@@ -491,7 +491,7 @@ describe Mongoid::Fields::Localized do
491
491
  end
492
492
 
493
493
  let(:field) do
494
- described_class.new(:boolean_value, localize: true, type: Boolean)
494
+ described_class.new(:boolean_value, localize: true, type: Mongoid::Boolean)
495
495
  end
496
496
 
497
497
  let(:value) do
@@ -510,7 +510,7 @@ describe Mongoid::Fields::Localized do
510
510
  end
511
511
 
512
512
  let(:field) do
513
- described_class.new(:boolean_value, localize: true, type: Boolean)
513
+ described_class.new(:boolean_value, localize: true, type: Mongoid::Boolean)
514
514
  end
515
515
 
516
516
  let(:value) do
@@ -322,7 +322,7 @@ describe Mongoid::Fields do
322
322
  end
323
323
 
324
324
  it "converts to Mongoid::Boolean" do
325
- expect(klass.field(:test, type: Boolean).type).to be(Mongoid::Boolean)
325
+ expect(klass.field(:test, type: Mongoid::Boolean).type).to be(Mongoid::Boolean)
326
326
  end
327
327
  end
328
328
 
@@ -404,7 +404,7 @@ describe Mongoid::Fields do
404
404
  context "when the options are all standard" do
405
405
 
406
406
  before do
407
- Band.field :acceptable, type: Boolean
407
+ Band.field :acceptable, type: Mongoid::Boolean
408
408
  end
409
409
 
410
410
  after do
@@ -419,7 +419,7 @@ describe Mongoid::Fields do
419
419
  context "when a custom option is provided" do
420
420
 
421
421
  before do
422
- Band.field :acceptable, type: Boolean, custom: true
422
+ Band.field :acceptable, type: Mongoid::Boolean, custom: true
423
423
  end
424
424
 
425
425
  it "adds the field to the model" do
@@ -990,7 +990,7 @@ describe Mongoid::Fields do
990
990
  end
991
991
 
992
992
  before do
993
- Person.field :aliased, as: :alias, type: Boolean, overwrite: true
993
+ Person.field :aliased, as: :alias, type: Mongoid::Boolean, overwrite: true
994
994
  end
995
995
 
996
996
  it "uses the alias to write the attribute" do
@@ -33,18 +33,18 @@ describe Mongoid::Inspectable do
33
33
  expect(inspected).to include("t(test):")
34
34
  end
35
35
 
36
- it "displays the default discriminator key" do
36
+ it "displays the default discriminator key" do
37
37
  expect(inspected).to include(%q,_type: "Person",)
38
38
  end
39
39
  end
40
40
 
41
41
  context "when using a custom discriminator key" do
42
42
 
43
- before do
43
+ before do
44
44
  Person.discriminator_key = "dkey"
45
45
  end
46
46
 
47
- after do
47
+ after do
48
48
  Person.discriminator_key = nil
49
49
  end
50
50
 
@@ -56,7 +56,7 @@ describe Mongoid::Inspectable do
56
56
  person.inspect
57
57
  end
58
58
 
59
- it "displays the new discriminator key" do
59
+ it "displays the new discriminator key" do
60
60
  expect(inspected).to include(%q,dkey: "Person",)
61
61
  end
62
62
  end
@@ -75,5 +75,13 @@ describe Mongoid::Inspectable do
75
75
  expect(inspected).to include(%q,some_attribute: "foo",)
76
76
  end
77
77
  end
78
+
79
+ context 'when id is unaliased' do
80
+ let(:shirt) { Shirt.new(id: 1, _id: 2) }
81
+
82
+ it 'shows the correct _id and id values' do
83
+ shirt.inspect.should == "#<Shirt _id: 2, color: nil, id: \"1\">"
84
+ end
85
+ end
78
86
  end
79
87
  end
@@ -0,0 +1,104 @@
1
+ - name: string key - matches
2
+ document:
3
+ # Document field names in MongoDB are always strings.
4
+ '42': foo
5
+ # The paths are also always strings.
6
+ key: '42'
7
+
8
+ result:
9
+ - foo
10
+
11
+ - name: string key - does not match
12
+ document:
13
+ # Document field names in MongoDB are always strings.
14
+ '42': foo
15
+ # The paths are also always strings.
16
+ key: '4'
17
+
18
+ result: []
19
+
20
+ - name: array value - matches
21
+ document:
22
+ '42':
23
+ - foo
24
+ key: '42'
25
+
26
+ result:
27
+ - ['foo']
28
+
29
+ - name: subfield of numeric key - matches
30
+ document:
31
+ '42':
32
+ foo: bar
33
+ key: 42.foo
34
+
35
+ result:
36
+ - bar
37
+
38
+ - name: numeric key under array
39
+ document:
40
+ a:
41
+ -
42
+ '42': bar
43
+
44
+ key: a.42
45
+
46
+ result:
47
+ - bar
48
+
49
+ - name: multiple values under numeric key under array
50
+ document: &numeric-key-under-array
51
+ a:
52
+ -
53
+ '42': bar
54
+ -
55
+ '42': foo
56
+
57
+ key: a.42
58
+
59
+ result:
60
+ - bar
61
+ - foo
62
+
63
+ - name: array indexing with values under numeric key under array
64
+ document: *numeric-key-under-array
65
+
66
+ key: a.1
67
+
68
+ result:
69
+ -
70
+ '42': foo
71
+
72
+ - name: multiple values under array under numeric key
73
+ document:
74
+ a:
75
+ '42':
76
+ -
77
+ foo: bar
78
+ -
79
+ foo: baq
80
+
81
+ key: a.42.foo
82
+
83
+ result:
84
+ - bar
85
+ - baq
86
+
87
+ - name: path component interpretable as both array index and hash key
88
+ document:
89
+ a:
90
+ -
91
+ '1': bar
92
+ -
93
+ '1': foo
94
+
95
+ key: a.1
96
+
97
+ result:
98
+ # The order of these results isn't guaranteed:
99
+ # 1 interpreted as the array index:
100
+ -
101
+ '1': foo
102
+ # 1 interpreted as hash key:
103
+ - bar
104
+ - foo
@@ -3,9 +3,8 @@
3
3
  name: foo
4
4
  key: name
5
5
 
6
- exists: true
7
- value: foo
8
- expanded: false
6
+ result:
7
+ - foo
9
8
 
10
9
  - name: scalar leaf
11
10
  document: &foo-bar-foo-bar-2
@@ -16,20 +15,26 @@
16
15
  2
17
16
  key: foo.bar.foo.bar
18
17
 
19
- exists: true
20
- value: 2
21
- expanded: false
18
+ result:
19
+ - 2
22
20
 
23
21
  - name: scalar non-leaf
24
22
  document: *foo-bar-foo-bar-2
25
23
  key: foo.bar
26
24
 
27
- exists: true
28
- value:
29
- foo:
30
- bar:
31
- 2
32
- expanded: false
25
+ result:
26
+ -
27
+ foo:
28
+ bar:
29
+ 2
30
+
31
+ - name: null leaf
32
+ document:
33
+ name:
34
+ key: name
35
+
36
+ result:
37
+ - ~
33
38
 
34
39
  - name: array leaf
35
40
  document: &foo-bar-foo-bar-array-2
@@ -40,21 +45,18 @@
40
45
  - 2
41
46
  key: foo.bar.foo.bar
42
47
 
43
- exists: true
44
- value:
45
- - 2
46
- expanded: false
48
+ result:
49
+ - [2]
47
50
 
48
51
  - name: scalar non-leaf
49
52
  document: *foo-bar-foo-bar-array-2
50
53
  key: foo.bar
51
54
 
52
- exists: true
53
- value:
54
- foo:
55
- bar:
56
- - 2
57
- expanded: false
55
+ result:
56
+ -
57
+ foo:
58
+ bar:
59
+ - 2
58
60
 
59
61
  - name: array non-leaf
60
62
  document: &foo-bar-array-foo-bar-2
@@ -66,30 +68,24 @@
66
68
  2
67
69
  key: foo.bar.foo.bar
68
70
 
69
- exists: true
70
- value:
71
+ result:
71
72
  - 2
72
- expanded: true
73
73
 
74
74
  - name: array non-leaf with non-leaf query
75
75
  document: *foo-bar-array-foo-bar-2
76
76
  key: foo.bar
77
77
 
78
- exists: true
79
- value:
78
+ result:
80
79
  -
81
80
  foo:
82
81
  bar:
83
82
  2
84
- expanded: true
85
83
 
86
84
  - name: array non-leaf with query for missing non-leaf key
87
85
  document: *foo-bar-array-foo-bar-2
88
86
  key: foo.missing
89
87
 
90
- exists: false
91
- value: []
92
- expanded: true
88
+ result: []
93
89
 
94
90
  - name: path past end of document
95
91
  document: &foo-hello-world
@@ -97,17 +93,23 @@
97
93
  hello: world
98
94
  key: foo.bar.foo.bar
99
95
 
100
- exists: false
101
- value: ~
102
- expanded: false
96
+ result: []
103
97
 
104
98
  - name: query for missing leaf key
105
99
  document: *foo-hello-world
106
100
  key: foo.bar
107
101
 
108
- exists: false
109
- value: ~
110
- expanded: false
102
+ result: []
103
+
104
+ - name: numeric path component when traversing hash
105
+ document:
106
+ foo:
107
+ "10":
108
+ 42
109
+ key: "foo.10"
110
+
111
+ result:
112
+ - 42
111
113
 
112
114
  - name: array index - hash leaf
113
115
  document: &foo-one-two
@@ -117,42 +119,35 @@
117
119
  bar: [3, 4]
118
120
  key: foo.1.two
119
121
 
120
- exists: true
121
- value: 2
122
- expanded: false
122
+ result:
123
+ - 2
123
124
 
124
125
  - name: array index - hash non-leaf
125
126
  document: *foo-one-two
126
127
  key: foo.1
127
128
 
128
- exists: true
129
- value:
130
- two: 2
131
- expanded: false
129
+ result:
130
+ -
131
+ two: 2
132
132
 
133
133
  - name: array index - scalar leaf
134
134
  document: *foo-one-two
135
135
  key: bar.1
136
136
 
137
- exists: true
138
- value: 4
139
- expanded: false
137
+ result:
138
+ - 4
140
139
 
141
140
  - name: array index - scalar leaf - missing
142
141
  document: *foo-one-two
143
142
  key: bar.2
144
143
 
145
- exists: false
146
- value: ~
147
- expanded: false
144
+ result: []
148
145
 
149
146
  - name: array index - scalar leaf - missing with further hash subscription
150
147
  document: *foo-one-two
151
148
  key: bar.2.any
152
149
 
153
- exists: false
154
- value: ~
155
- expanded: false
150
+ result: []
156
151
 
157
152
  - name: non-sequential nested arrays - hash leaf - one value
158
153
  document: &books-authors
@@ -166,30 +161,27 @@
166
161
  - name: Pasha
167
162
  key: books.0.authors.name
168
163
 
169
- exists: true
170
- value: [Steve]
171
- expanded: true
164
+ result:
165
+ - Steve
172
166
 
173
167
  - name: non-sequential nested arrays - hash non-leaf - one value
174
168
  document: *books-authors
175
169
  key: books.0
176
170
 
177
- exists: true
178
- value:
179
- authors:
180
- - name: Steve
181
- expanded: false
171
+ result:
172
+ -
173
+ authors:
174
+ - name: Steve
182
175
 
183
176
  - name: non-sequential nested arrays - hash non-leaf - multiple values
184
177
  document: *books-authors
185
178
  key: books.1
186
179
 
187
- exists: true
188
- value:
189
- authors:
190
- - name: Boris
191
- - name: Pasha
192
- expanded: false
180
+ result:
181
+ -
182
+ authors:
183
+ - name: Boris
184
+ - name: Pasha
193
185
 
194
186
  - name: sequential nested arrays - numerically indexed leaf
195
187
  document: &groups
@@ -197,41 +189,32 @@
197
189
  - [1]
198
190
  key: groups.0.0
199
191
 
200
- exists: true
201
- value: 1
202
- expanded: false
192
+ result:
193
+ - 1
203
194
 
204
195
  - name: sequential nested arrays - numerically indexed leaf - missing
205
196
  document: *groups
206
197
  key: groups.0.1
207
198
 
208
- exists: false
209
- value: ~
210
- expanded: false
199
+ result: []
211
200
 
212
201
  - name: sequential nested arrays - missing hash path through non-leaf
213
202
  document: *groups
214
203
  key: groups.missing
215
204
 
216
- exists: false
217
- value: []
218
- expanded: true
205
+ result: []
219
206
 
220
207
  - name: sequential nested arrays - missing hash path through leaf
221
208
  document: *groups
222
209
  key: groups.0.missing
223
210
 
224
- exists: false
225
- value: []
226
- expanded: true
211
+ result: []
227
212
 
228
213
  - name: sequential nested arrays - missing hash path past leaf
229
214
  document: *groups
230
215
  key: groups.0.0.missing
231
216
 
232
- exists: false
233
- value: ~
234
- expanded: false
217
+ result: []
235
218
 
236
219
  - name: mix of arrays and hashes in an array
237
220
  document:
@@ -242,9 +225,8 @@
242
225
  - bar: 2
243
226
  key: foo.bar
244
227
 
245
- exists: true
246
- value: [2]
247
- expanded: true
228
+ result:
229
+ - 2
248
230
 
249
231
  - name: numeric index through a primitive value not supporting subscription operator
250
232
  document:
@@ -254,6 +236,4 @@
254
236
  key:
255
237
  occupants.0.age.0
256
238
 
257
- exists: false
258
- value: ~
259
- expanded: false
239
+ result: []
@@ -25,20 +25,10 @@ describe 'Matcher.extract_attribute' do
25
25
  Mongoid::Matcher.extract_attribute(document, key)
26
26
  end
27
27
 
28
- let(:expected_exists) { spec['exists'] }
29
- let(:expected_value) { spec['value'] }
30
- let(:expected_expanded) { spec['expanded'] }
28
+ let(:expected) { spec.fetch('result') }
31
29
 
32
- it 'has the expected exists flag' do
33
- actual[0].should == expected_exists
34
- end
35
-
36
- it 'has the expected value' do
37
- actual[1].should == expected_value
38
- end
39
-
40
- it 'has the expected expanded flag' do
41
- actual[2].should == expected_expanded
30
+ it 'has the expected result' do
31
+ actual.should == expected
42
32
  end
43
33
  end
44
34
  end