mongoid 7.2.6 → 7.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) 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 +13 -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 +490 -496
  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/atomic.rb +26 -2
  19. data/lib/mongoid/attributes/projector.rb +120 -0
  20. data/lib/mongoid/attributes.rb +24 -13
  21. data/lib/mongoid/cacheable.rb +2 -2
  22. data/lib/mongoid/clients/factory.rb +22 -8
  23. data/lib/mongoid/clients.rb +1 -1
  24. data/lib/mongoid/config.rb +19 -2
  25. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  26. data/lib/mongoid/copyable.rb +1 -1
  27. data/lib/mongoid/criteria/findable.rb +1 -1
  28. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  29. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  30. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  31. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  32. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  33. data/lib/mongoid/criteria.rb +4 -5
  34. data/lib/mongoid/document.rb +1 -15
  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/matcher/bits.rb +41 -0
  44. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  45. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  46. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  47. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  48. data/lib/mongoid/matcher/expression.rb +4 -0
  49. data/lib/mongoid/matcher/field_operator.rb +6 -0
  50. data/lib/mongoid/matcher/mod.rb +17 -0
  51. data/lib/mongoid/matcher/type.rb +99 -0
  52. data/lib/mongoid/matcher.rb +7 -0
  53. data/lib/mongoid/persistable/deletable.rb +1 -2
  54. data/lib/mongoid/persistable/destroyable.rb +8 -2
  55. data/lib/mongoid/persistable/updatable.rb +27 -2
  56. data/lib/mongoid/query_cache.rb +35 -29
  57. data/lib/mongoid/selectable.rb +5 -7
  58. data/lib/mongoid/shardable.rb +21 -5
  59. data/lib/mongoid/touchable.rb +33 -4
  60. data/lib/mongoid/version.rb +1 -1
  61. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  62. data/spec/integration/associations/has_one_spec.rb +48 -0
  63. data/spec/integration/criteria/date_field_spec.rb +1 -1
  64. data/spec/integration/document_spec.rb +9 -0
  65. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  66. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  67. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  68. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  69. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  70. data/spec/integration/matcher_operator_data/in.yml +16 -0
  71. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  72. data/spec/integration/matcher_operator_data/type.yml +70 -0
  73. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  74. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  75. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  76. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  77. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  78. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  79. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  80. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  81. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  82. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  83. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  84. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  85. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  86. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  87. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  88. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  89. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  90. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  91. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  92. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  93. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  94. data/spec/lite_spec_helper.rb +2 -0
  95. data/spec/mongoid/association/depending_spec.rb +391 -352
  96. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  97. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  98. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  99. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  100. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +245 -93
  101. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +6 -6
  102. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  103. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  104. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  105. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  106. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  107. data/spec/mongoid/attributes_spec.rb +98 -6
  108. data/spec/mongoid/clients/factory_spec.rb +48 -0
  109. data/spec/mongoid/config_spec.rb +106 -1
  110. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  111. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  112. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  113. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  114. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  115. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  116. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  117. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  118. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  119. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  120. data/spec/mongoid/criteria_spec.rb +0 -275
  121. data/spec/mongoid/document_spec.rb +13 -13
  122. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  123. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  124. data/spec/mongoid/extensions/string_spec.rb +5 -5
  125. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  126. data/spec/mongoid/fields/localized_spec.rb +4 -4
  127. data/spec/mongoid/fields_spec.rb +4 -4
  128. data/spec/mongoid/inspectable_spec.rb +12 -4
  129. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  130. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  131. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  132. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  133. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  134. data/spec/mongoid/reloadable_spec.rb +18 -1
  135. data/spec/mongoid/shardable_spec.rb +44 -0
  136. data/spec/mongoid/touchable_spec.rb +122 -16
  137. data/spec/mongoid/touchable_spec_models.rb +54 -0
  138. data/spec/mongoid/validatable_spec.rb +1 -1
  139. data/spec/spec_helper.rb +6 -2
  140. data/spec/support/client_registry.rb +9 -0
  141. data/spec/support/models/bolt.rb +8 -0
  142. data/spec/support/models/hole.rb +13 -0
  143. data/spec/support/models/mop.rb +0 -1
  144. data/spec/support/models/nut.rb +8 -0
  145. data/spec/support/models/person.rb +6 -0
  146. data/spec/support/models/sealer.rb +8 -0
  147. data/spec/support/models/shirt.rb +12 -0
  148. data/spec/support/models/spacer.rb +8 -0
  149. data/spec/support/models/threadlocker.rb +8 -0
  150. data/spec/support/models/washer.rb +8 -0
  151. data.tar.gz.sig +0 -0
  152. metadata +97 -3
  153. metadata.gz.sig +0 -0
  154. data/spec/support/cluster_config.rb +0 -158
@@ -1568,12 +1568,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
1568
1568
  end
1569
1569
 
1570
1570
  context 'when association is not loaded' do
1571
- it 'queries database on each call' do
1572
- expect_query(1) do
1573
- movie.ratings.any?.should be true
1574
- end
1571
+ before do
1572
+ movie.ratings._loaded?.should be false
1573
+ end
1575
1574
 
1576
- expect_query(1) do
1575
+ it 'does not query the database because it knows about the added models' do
1576
+ expect_no_queries do
1577
1577
  movie.ratings.any?.should be true
1578
1578
  end
1579
1579
  end
@@ -1581,7 +1581,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
1581
1581
 
1582
1582
  context 'when association is loaded' do
1583
1583
  it 'does not query database' do
1584
- expect_query(1) do
1584
+ expect_no_queries do
1585
1585
  movie.ratings.any?.should be true
1586
1586
  end
1587
1587
 
@@ -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
@@ -96,6 +96,49 @@ describe Mongoid::Attributes do
96
96
  it "does not raise an error" do
97
97
  expect(from_db.map).to eq(map)
98
98
  end
99
+
100
+ context 'when only one of the hash fields is projected' do
101
+
102
+ let(:map) do
103
+ { 'dates' => { 'y' => { '2016' => 'Berlin', '2017' => 'Munich' } } }
104
+ end
105
+
106
+ let(:expected) do
107
+ { 'dates' => { 'y' => {
108
+ '2016' => 'Berlin',
109
+ } } }
110
+ end
111
+
112
+ it 'retrieves only the projected fields' do
113
+ expect(from_db.map).to eq(expected)
114
+ end
115
+ end
116
+
117
+ context 'when several of the hash fields is projected' do
118
+
119
+ let(:map) do
120
+ { 'dates' => { 'y' => {
121
+ '2016' => 'Berlin',
122
+ '2017' => 'Munich',
123
+ '2018' => 'Krakow',
124
+ } } }
125
+ end
126
+
127
+ let(:expected) do
128
+ { 'dates' => { 'y' => {
129
+ '2016' => 'Berlin',
130
+ '2018' => 'Krakow',
131
+ } } }
132
+ end
133
+
134
+ let(:from_db) do
135
+ Person.only('map.dates.y.2016', 'map.dates.y.2018').first
136
+ end
137
+
138
+ it 'retrieves only the projected fields' do
139
+ expect(from_db.map).to eq(expected)
140
+ end
141
+ end
99
142
  end
100
143
  end
101
144
 
@@ -298,16 +341,12 @@ describe Mongoid::Attributes do
298
341
  context 'when retrieving a field of the association using the dot notation' do
299
342
 
300
343
  it 'retrieves the field' do
301
- pending 'MONGOID-5032, fixed in 7.3'
302
-
303
344
  expect(from_db['name.first_name']).to eq 'Jose'
304
345
  end
305
346
  end
306
347
 
307
348
  context 'when retrieving a field of a nested association using the dot notation' do
308
349
  it 'retrieves the field' do
309
- pending 'MONGOID-5032, fixed in 7.3'
310
-
311
350
  expect(from_db['name.language.name']).to eq 'es'
312
351
  end
313
352
  end
@@ -320,8 +359,6 @@ describe Mongoid::Attributes do
320
359
 
321
360
  context 'when retrieving a field under the projected sub-association' do
322
361
  it 'retrieves the field' do
323
- pending 'MONGOID-5032, fixed in 7.3'
324
-
325
362
  expect(from_db['name.language.name']).to eq 'es'
326
363
  end
327
364
  end
@@ -1892,6 +1929,61 @@ describe Mongoid::Attributes do
1892
1929
  end
1893
1930
  end
1894
1931
 
1932
+ describe '#unalias_attribute' do
1933
+ let(:shirt) { Shirt.new }
1934
+ let(:id) { '1234' }
1935
+
1936
+ context 'when creating object' do
1937
+ let(:shirt) { Shirt.new(id: id) }
1938
+
1939
+ it 'id and _id are not the same' do
1940
+ expect(shirt.id).to eq(id)
1941
+ expect(shirt._id).not_to eq(id)
1942
+ end
1943
+ end
1944
+
1945
+ context 'update' do
1946
+ before do
1947
+ shirt.update(id: id)
1948
+ end
1949
+
1950
+ it 'updates id but not_id' do
1951
+ expect(shirt.id).to eq(id)
1952
+ expect(shirt._id).not_to eq(id)
1953
+ end
1954
+ end
1955
+
1956
+ context 'id=' do
1957
+ before do
1958
+ shirt.id = id
1959
+ end
1960
+
1961
+ it 'sets id and not _id' do
1962
+ expect(shirt.id).to eq(id)
1963
+ expect(shirt._id).not_to eq(id)
1964
+ end
1965
+ end
1966
+
1967
+ context 'id?' do
1968
+ context 'with null id' do
1969
+ it 'returns false' do
1970
+ expect(shirt.id?).to be false
1971
+ expect(shirt._id?).to be true
1972
+ end
1973
+ end
1974
+
1975
+ context 'with id' do
1976
+ before do
1977
+ shirt.id = id
1978
+ end
1979
+
1980
+ it 'returns true' do
1981
+ expect(shirt.id?).to be true
1982
+ end
1983
+ end
1984
+ end
1985
+ end
1986
+
1895
1987
  describe "#alias_attribute" do
1896
1988
 
1897
1989
  let(:product) do