mongoid 7.2.0 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
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