mongoid-history 0.8.3 → 0.8.5

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -1
  3. data/.document +5 -5
  4. data/.github/workflows/test.yml +72 -0
  5. data/.gitignore +46 -46
  6. data/.rspec +2 -2
  7. data/.rubocop.yml +6 -6
  8. data/.rubocop_todo.yml +99 -99
  9. data/CHANGELOG.md +173 -163
  10. data/CONTRIBUTING.md +117 -118
  11. data/Dangerfile +1 -1
  12. data/Gemfile +49 -40
  13. data/LICENSE.txt +20 -20
  14. data/README.md +609 -608
  15. data/RELEASING.md +66 -67
  16. data/Rakefile +24 -24
  17. data/UPGRADING.md +53 -53
  18. data/lib/mongoid/history/attributes/base.rb +72 -72
  19. data/lib/mongoid/history/attributes/create.rb +45 -45
  20. data/lib/mongoid/history/attributes/destroy.rb +34 -34
  21. data/lib/mongoid/history/attributes/update.rb +104 -104
  22. data/lib/mongoid/history/options.rb +177 -177
  23. data/lib/mongoid/history/trackable.rb +588 -583
  24. data/lib/mongoid/history/tracker.rb +247 -247
  25. data/lib/mongoid/history/version.rb +5 -5
  26. data/lib/mongoid/history.rb +77 -77
  27. data/lib/mongoid-history.rb +1 -1
  28. data/mongoid-history.gemspec +25 -25
  29. data/perf/benchmark_modified_attributes_for_create.rb +65 -65
  30. data/perf/gc_suite.rb +21 -21
  31. data/spec/integration/embedded_in_polymorphic_spec.rb +112 -112
  32. data/spec/integration/integration_spec.rb +976 -976
  33. data/spec/integration/multi_relation_spec.rb +47 -47
  34. data/spec/integration/multiple_trackers_spec.rb +68 -68
  35. data/spec/integration/nested_embedded_documents_spec.rb +64 -64
  36. data/spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb +124 -124
  37. data/spec/integration/nested_embedded_polymorphic_documents_spec.rb +115 -115
  38. data/spec/integration/subclasses_spec.rb +47 -47
  39. data/spec/integration/track_history_order_spec.rb +84 -84
  40. data/spec/integration/validation_failure_spec.rb +76 -76
  41. data/spec/spec_helper.rb +32 -30
  42. data/spec/support/error_helpers.rb +7 -0
  43. data/spec/support/mongoid.rb +11 -11
  44. data/spec/support/mongoid_history.rb +12 -12
  45. data/spec/unit/attributes/base_spec.rb +141 -141
  46. data/spec/unit/attributes/create_spec.rb +342 -342
  47. data/spec/unit/attributes/destroy_spec.rb +228 -228
  48. data/spec/unit/attributes/update_spec.rb +342 -342
  49. data/spec/unit/callback_options_spec.rb +165 -165
  50. data/spec/unit/embedded_methods_spec.rb +87 -87
  51. data/spec/unit/history_spec.rb +58 -58
  52. data/spec/unit/my_instance_methods_spec.rb +555 -555
  53. data/spec/unit/options_spec.rb +365 -365
  54. data/spec/unit/singleton_methods_spec.rb +406 -406
  55. data/spec/unit/store/default_store_spec.rb +11 -11
  56. data/spec/unit/store/request_store_spec.rb +13 -13
  57. data/spec/unit/trackable_spec.rb +1057 -987
  58. data/spec/unit/tracker_spec.rb +190 -190
  59. metadata +9 -7
  60. data/.travis.yml +0 -36
@@ -1,365 +1,365 @@
1
- require 'spec_helper'
2
-
3
- describe Mongoid::History::Options do
4
- before :each do
5
- class ModelOne
6
- include Mongoid::Document
7
- include Mongoid::History::Trackable
8
-
9
- store_in collection: :model_ones
10
-
11
- field :foo
12
- field :b, as: :bar
13
-
14
- if Mongoid::Compatibility::Version.mongoid7_or_newer?
15
- embeds_one :emb_one
16
- embeds_one :emb_two, store_as: :emtw
17
- embeds_many :emb_threes
18
- embeds_many :emb_fours, store_as: :emfs
19
- else
20
- embeds_one :emb_one, inverse_class_name: 'EmbOne'
21
- embeds_one :emb_two, store_as: :emtw, inverse_class_name: 'EmbTwo'
22
- embeds_many :emb_threes, inverse_class_name: 'EmbThree'
23
- embeds_many :emb_fours, store_as: :emfs, inverse_class_name: 'EmbFour'
24
- end
25
-
26
- track_history
27
- end
28
-
29
- class EmbOne
30
- include Mongoid::Document
31
-
32
- field :f_em_foo
33
- field :fmb, as: :f_em_bar
34
-
35
- embedded_in :model_one
36
- end
37
-
38
- class EmbTwo
39
- include Mongoid::Document
40
-
41
- field :f_em_baz
42
- embedded_in :model_one
43
- end
44
-
45
- class EmbThree
46
- include Mongoid::Document
47
-
48
- field :f_em_foo
49
- field :fmb, as: :f_em_bar
50
-
51
- embedded_in :model_one
52
- end
53
-
54
- class EmbFour
55
- include Mongoid::Document
56
-
57
- field :f_em_baz
58
- embedded_in :model_one
59
- end
60
- end
61
-
62
- after :each do
63
- Object.send(:remove_const, :ModelOne)
64
- Object.send(:remove_const, :EmbOne)
65
- Object.send(:remove_const, :EmbTwo)
66
- Object.send(:remove_const, :EmbThree)
67
- Object.send(:remove_const, :EmbFour)
68
- end
69
-
70
- let(:options) { {} }
71
- let(:service) { described_class.new(ModelOne, options) }
72
-
73
- subject { service }
74
-
75
- it { is_expected.to respond_to :trackable }
76
- it { is_expected.to respond_to :options }
77
-
78
- describe '#initialize' do
79
- it { expect(service.trackable).to eq ModelOne }
80
- end
81
-
82
- describe '#scope' do
83
- it { expect(service.scope).to eq :model_one }
84
- end
85
-
86
- describe '#parse' do
87
- it 'does not mutate the original options' do
88
- original_options = service.options.dup
89
- service.prepared
90
- expect(service.options).to eq original_options
91
- end
92
-
93
- describe '#default_options' do
94
- let(:expected_options) do
95
- {
96
- on: :all,
97
- except: %i[created_at updated_at],
98
- tracker_class_name: nil,
99
- modifier_field: :modifier,
100
- version_field: :version,
101
- changes_method: :changes,
102
- scope: :model_one,
103
- track_create: true,
104
- track_update: true,
105
- track_destroy: true,
106
- format: nil
107
- }
108
- end
109
- it { expect(service.send(:default_options)).to eq expected_options }
110
- end
111
-
112
- describe '#prepare_skipped_fields' do
113
- let(:options) { { except: value } }
114
- subject { service.prepared }
115
-
116
- context 'with field' do
117
- let(:value) { :foo }
118
- it { expect(subject[:except]).to eq %w[foo] }
119
- end
120
-
121
- context 'with array of fields' do
122
- let(:value) { %i[foo] }
123
- it { expect(subject[:except]).to eq %w[foo] }
124
- end
125
-
126
- context 'with field alias' do
127
- let(:value) { %i[foo bar] }
128
- it { expect(subject[:except]).to eq %w[foo b] }
129
- end
130
-
131
- context 'with duplicate values' do
132
- let(:value) { %i[foo bar b] }
133
- it { expect(subject[:except]).to eq %w[foo b] }
134
- end
135
-
136
- context 'with blank values' do
137
- let(:value) { %i[foo] | [nil] }
138
- it { expect(subject[:except]).to eq %w[foo] }
139
- end
140
- end
141
-
142
- describe '#prepare_formatted_fields' do
143
- let(:options) { { format: value } }
144
- subject { service.prepared }
145
-
146
- context 'with non-hash' do
147
- let(:value) { :foo }
148
- it { expect(subject[:format]).to eq({}) }
149
- end
150
-
151
- context 'with a field format' do
152
- let(:value) { { foo: '&&&' } }
153
- it { expect(subject[:format]).to include 'foo' => '&&&' }
154
- end
155
-
156
- context 'with nested format' do
157
- let(:value) { { emb_one: { f_em_foo: '***' } } }
158
- it { expect(subject[:format]).to include 'emb_one' => { 'f_em_foo' => '***' } }
159
- end
160
- end
161
-
162
- describe '#parse_tracked_fields_and_relations' do
163
- context 'when options not passed' do
164
- let(:expected_options) do
165
- {
166
- on: %i[foo b],
167
- except: %w[created_at updated_at],
168
- tracker_class_name: nil,
169
- modifier_field: :modifier,
170
- version_field: :version,
171
- changes_method: :changes,
172
- scope: :model_one,
173
- track_create: true,
174
- track_update: true,
175
- track_destroy: true,
176
- fields: %w[foo b],
177
- dynamic: [],
178
- relations: { embeds_one: {}, embeds_many: {} },
179
- format: {}
180
- }
181
- end
182
- it { expect(service.prepared).to eq expected_options }
183
- end
184
-
185
- context 'when options passed' do
186
- subject { service.prepared }
187
-
188
- describe '@options' do
189
- let(:options) { { on: value } }
190
-
191
- context 'with field' do
192
- let(:value) { :foo }
193
- it { expect(subject[:on]).to eq %i[foo] }
194
- it { expect(subject[:fields]).to eq %w[foo] }
195
- end
196
-
197
- context 'with array of fields' do
198
- let(:value) { %i[foo] }
199
- it { expect(subject[:on]).to eq %i[foo] }
200
- it { expect(subject[:fields]).to eq %w[foo] }
201
- end
202
-
203
- context 'with embeds_one relation attributes' do
204
- let(:value) { { emb_one: %i[f_em_foo] } }
205
- it { expect(subject[:on]).to eq [[:emb_one, %i[f_em_foo]]] }
206
- end
207
-
208
- context 'with fields and embeds_one relation attributes' do
209
- let(:value) { [:foo, emb_one: %i[f_em_foo]] }
210
- it { expect(subject[:on]).to eq [:foo, emb_one: %i[f_em_foo]] }
211
- end
212
-
213
- context 'with :all' do
214
- let(:value) { :all }
215
- it { expect(subject[:on]).to eq %i[foo b] }
216
- end
217
-
218
- context 'with :fields' do
219
- let(:value) { :fields }
220
- it { expect(subject[:on]).to eq %i[foo b] }
221
- end
222
-
223
- describe '#categorize_tracked_option' do
224
- context 'with skipped field' do
225
- let(:options) { { on: %i[foo bar], except: :foo } }
226
- it { expect(subject[:fields]).to eq %w[b] }
227
- end
228
-
229
- context 'with skipped embeds_one relation' do
230
- let(:options) { { on: %i[fields emb_one emb_two], except: :emb_one } }
231
- it { expect(subject[:relations][:embeds_one]).to eq('emtw' => %w[_id f_em_baz]) }
232
- end
233
-
234
- context 'with skipped embeds_many relation' do
235
- let(:options) { { on: %i[fields emb_threes emb_fours], except: :emb_threes } }
236
- it { expect(subject[:relations][:embeds_many]).to eq('emfs' => %w[_id f_em_baz]) }
237
- end
238
-
239
- context 'with reserved field' do
240
- let(:options) { { on: %i[_id _type foo deleted_at] } }
241
- it { expect(subject[:fields]).to eq %w[foo] }
242
- end
243
-
244
- context 'when embeds_one attribute passed' do
245
- let(:options) { { on: { emb_one: :f_em_foo } } }
246
- it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo]) }
247
- end
248
-
249
- context 'when embeds_one attributes array passed' do
250
- let(:options) { { on: { emb_one: %i[f_em_foo] } } }
251
- it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo]) }
252
- end
253
-
254
- context 'when embeds_many attribute passed' do
255
- let(:options) { { on: { emb_threes: :f_em_foo } } }
256
- it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo]) }
257
- end
258
-
259
- context 'when embeds_many attributes array passed' do
260
- let(:options) { { on: { emb_threes: %i[f_em_foo] } } }
261
- it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo]) }
262
- end
263
-
264
- context 'when embeds_one attributes not passed' do
265
- let(:options) { { on: :emb_one } }
266
- it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo fmb]) }
267
- end
268
-
269
- context 'when embeds_many attributes not passed' do
270
- let(:options) { { on: :emb_threes } }
271
- it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo fmb]) }
272
- end
273
-
274
- context 'when embeds_one attribute alias passed' do
275
- let(:options) { { on: { emb_one: %i[f_em_bar] } } }
276
- it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id fmb]) }
277
- end
278
-
279
- context 'when embeds_many attribute alias passed' do
280
- let(:options) { { on: { emb_threes: %i[f_em_bar] } } }
281
- it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id fmb]) }
282
- end
283
-
284
- context 'with fields, and multiple embeds_one, and embeds_many relations' do
285
- let(:options) { { on: [:foo, :bar, :emb_two, { emb_threes: %i[f_em_foo f_em_bar], emb_fours: :f_em_baz }] } }
286
- it 'should categorize fields and associations correctly' do
287
- expect(subject[:fields]).to eq(%w[foo b])
288
- expect(subject[:relations][:embeds_one]).to eq('emtw' => %w[_id f_em_baz])
289
- expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo fmb], 'emfs' => %w[_id f_em_baz])
290
- end
291
- end
292
-
293
- context 'with field alias' do
294
- let(:options) { { on: :bar } }
295
- it { expect(subject[:fields]).to eq %w[b] }
296
- end
297
-
298
- context 'with dynamic field name' do
299
- let(:options) { { on: :my_field } }
300
- it { expect(subject[:dynamic]).to eq %w[my_field] }
301
- end
302
-
303
- context 'with relations' do
304
- let(:options) { { on: :embedded_relations } }
305
- it do
306
- expect(subject[:relations]).to eq(
307
- embeds_many: { 'emb_threes' => %w[_id f_em_foo fmb],
308
- 'emfs' => %w[_id f_em_baz] },
309
- embeds_one: { 'emb_one' => %w[_id f_em_foo fmb],
310
- 'emtw' => %w[_id f_em_baz] }
311
- )
312
- end
313
- end
314
- end
315
- end
316
-
317
- describe ':modifier_field' do
318
- let(:options) { { modifier_field: :my_modifier_field } }
319
- it { expect(subject[:modifier_field]).to eq :my_modifier_field }
320
- end
321
-
322
- describe ':version_field' do
323
- let(:options) { { version_field: :my_version_field } }
324
- it { expect(subject[:version_field]).to eq :my_version_field }
325
- end
326
-
327
- describe ':paranoia_field' do
328
- let(:options) { { paranoia_field: :my_paranoia_field } }
329
- it { expect(subject[:paranoia_field]).to eq :my_paranoia_field }
330
- end
331
-
332
- describe ':changes_method' do
333
- let(:options) { { changes_method: :my_changes_method } }
334
- it { expect(subject[:changes_method]).to eq :my_changes_method }
335
- end
336
-
337
- describe ':scope' do
338
- let(:options) { { scope: :my_scope } }
339
- it { expect(subject[:scope]).to eq :my_scope }
340
- end
341
-
342
- describe ':track_create' do
343
- let(:options) { { track_create: true } }
344
- it { expect(subject[:track_create]).to be true }
345
- end
346
-
347
- describe ':track_update' do
348
- let(:options) { { track_update: false } }
349
- it { expect(subject[:track_update]).to be false }
350
- end
351
-
352
- describe ':track_destroy' do
353
- let(:options) { { track_destroy: true } }
354
- it { expect(subject[:track_destroy]).to be true }
355
- end
356
-
357
- describe '#remove_reserved_fields' do
358
- let(:options) { { on: %i[_id _type foo version modifier_id] } }
359
- it { expect(subject[:fields]).to eq %w[foo] }
360
- it { expect(subject[:dynamic]).to eq [] }
361
- end
362
- end
363
- end
364
- end
365
- end
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Options do
4
+ before :each do
5
+ class ModelOne
6
+ include Mongoid::Document
7
+ include Mongoid::History::Trackable
8
+
9
+ store_in collection: :model_ones
10
+
11
+ field :foo
12
+ field :b, as: :bar
13
+
14
+ if Mongoid::Compatibility::Version.mongoid7_or_newer?
15
+ embeds_one :emb_one
16
+ embeds_one :emb_two, store_as: :emtw
17
+ embeds_many :emb_threes
18
+ embeds_many :emb_fours, store_as: :emfs
19
+ else
20
+ embeds_one :emb_one, inverse_class_name: 'EmbOne'
21
+ embeds_one :emb_two, store_as: :emtw, inverse_class_name: 'EmbTwo'
22
+ embeds_many :emb_threes, inverse_class_name: 'EmbThree'
23
+ embeds_many :emb_fours, store_as: :emfs, inverse_class_name: 'EmbFour'
24
+ end
25
+
26
+ track_history
27
+ end
28
+
29
+ class EmbOne
30
+ include Mongoid::Document
31
+
32
+ field :f_em_foo
33
+ field :fmb, as: :f_em_bar
34
+
35
+ embedded_in :model_one
36
+ end
37
+
38
+ class EmbTwo
39
+ include Mongoid::Document
40
+
41
+ field :f_em_baz
42
+ embedded_in :model_one
43
+ end
44
+
45
+ class EmbThree
46
+ include Mongoid::Document
47
+
48
+ field :f_em_foo
49
+ field :fmb, as: :f_em_bar
50
+
51
+ embedded_in :model_one
52
+ end
53
+
54
+ class EmbFour
55
+ include Mongoid::Document
56
+
57
+ field :f_em_baz
58
+ embedded_in :model_one
59
+ end
60
+ end
61
+
62
+ after :each do
63
+ Object.send(:remove_const, :ModelOne)
64
+ Object.send(:remove_const, :EmbOne)
65
+ Object.send(:remove_const, :EmbTwo)
66
+ Object.send(:remove_const, :EmbThree)
67
+ Object.send(:remove_const, :EmbFour)
68
+ end
69
+
70
+ let(:options) { {} }
71
+ let(:service) { described_class.new(ModelOne, options) }
72
+
73
+ subject { service }
74
+
75
+ it { is_expected.to respond_to :trackable }
76
+ it { is_expected.to respond_to :options }
77
+
78
+ describe '#initialize' do
79
+ it { expect(service.trackable).to eq ModelOne }
80
+ end
81
+
82
+ describe '#scope' do
83
+ it { expect(service.scope).to eq :model_one }
84
+ end
85
+
86
+ describe '#parse' do
87
+ it 'does not mutate the original options' do
88
+ original_options = service.options.dup
89
+ service.prepared
90
+ expect(service.options).to eq original_options
91
+ end
92
+
93
+ describe '#default_options' do
94
+ let(:expected_options) do
95
+ {
96
+ on: :all,
97
+ except: %i[created_at updated_at],
98
+ tracker_class_name: nil,
99
+ modifier_field: :modifier,
100
+ version_field: :version,
101
+ changes_method: :changes,
102
+ scope: :model_one,
103
+ track_create: true,
104
+ track_update: true,
105
+ track_destroy: true,
106
+ format: nil
107
+ }
108
+ end
109
+ it { expect(service.send(:default_options)).to eq expected_options }
110
+ end
111
+
112
+ describe '#prepare_skipped_fields' do
113
+ let(:options) { { except: value } }
114
+ subject { service.prepared }
115
+
116
+ context 'with field' do
117
+ let(:value) { :foo }
118
+ it { expect(subject[:except]).to eq %w[foo] }
119
+ end
120
+
121
+ context 'with array of fields' do
122
+ let(:value) { %i[foo] }
123
+ it { expect(subject[:except]).to eq %w[foo] }
124
+ end
125
+
126
+ context 'with field alias' do
127
+ let(:value) { %i[foo bar] }
128
+ it { expect(subject[:except]).to eq %w[foo b] }
129
+ end
130
+
131
+ context 'with duplicate values' do
132
+ let(:value) { %i[foo bar b] }
133
+ it { expect(subject[:except]).to eq %w[foo b] }
134
+ end
135
+
136
+ context 'with blank values' do
137
+ let(:value) { %i[foo] | [nil] }
138
+ it { expect(subject[:except]).to eq %w[foo] }
139
+ end
140
+ end
141
+
142
+ describe '#prepare_formatted_fields' do
143
+ let(:options) { { format: value } }
144
+ subject { service.prepared }
145
+
146
+ context 'with non-hash' do
147
+ let(:value) { :foo }
148
+ it { expect(subject[:format]).to eq({}) }
149
+ end
150
+
151
+ context 'with a field format' do
152
+ let(:value) { { foo: '&&&' } }
153
+ it { expect(subject[:format]).to include 'foo' => '&&&' }
154
+ end
155
+
156
+ context 'with nested format' do
157
+ let(:value) { { emb_one: { f_em_foo: '***' } } }
158
+ it { expect(subject[:format]).to include 'emb_one' => { 'f_em_foo' => '***' } }
159
+ end
160
+ end
161
+
162
+ describe '#parse_tracked_fields_and_relations' do
163
+ context 'when options not passed' do
164
+ let(:expected_options) do
165
+ {
166
+ on: %i[foo b],
167
+ except: %w[created_at updated_at],
168
+ tracker_class_name: nil,
169
+ modifier_field: :modifier,
170
+ version_field: :version,
171
+ changes_method: :changes,
172
+ scope: :model_one,
173
+ track_create: true,
174
+ track_update: true,
175
+ track_destroy: true,
176
+ fields: %w[foo b],
177
+ dynamic: [],
178
+ relations: { embeds_one: {}, embeds_many: {} },
179
+ format: {}
180
+ }
181
+ end
182
+ it { expect(service.prepared).to eq expected_options }
183
+ end
184
+
185
+ context 'when options passed' do
186
+ subject { service.prepared }
187
+
188
+ describe '@options' do
189
+ let(:options) { { on: value } }
190
+
191
+ context 'with field' do
192
+ let(:value) { :foo }
193
+ it { expect(subject[:on]).to eq %i[foo] }
194
+ it { expect(subject[:fields]).to eq %w[foo] }
195
+ end
196
+
197
+ context 'with array of fields' do
198
+ let(:value) { %i[foo] }
199
+ it { expect(subject[:on]).to eq %i[foo] }
200
+ it { expect(subject[:fields]).to eq %w[foo] }
201
+ end
202
+
203
+ context 'with embeds_one relation attributes' do
204
+ let(:value) { { emb_one: %i[f_em_foo] } }
205
+ it { expect(subject[:on]).to eq [[:emb_one, %i[f_em_foo]]] }
206
+ end
207
+
208
+ context 'with fields and embeds_one relation attributes' do
209
+ let(:value) { [:foo, emb_one: %i[f_em_foo]] }
210
+ it { expect(subject[:on]).to eq [:foo, emb_one: %i[f_em_foo]] }
211
+ end
212
+
213
+ context 'with :all' do
214
+ let(:value) { :all }
215
+ it { expect(subject[:on]).to eq %i[foo b] }
216
+ end
217
+
218
+ context 'with :fields' do
219
+ let(:value) { :fields }
220
+ it { expect(subject[:on]).to eq %i[foo b] }
221
+ end
222
+
223
+ describe '#categorize_tracked_option' do
224
+ context 'with skipped field' do
225
+ let(:options) { { on: %i[foo bar], except: :foo } }
226
+ it { expect(subject[:fields]).to eq %w[b] }
227
+ end
228
+
229
+ context 'with skipped embeds_one relation' do
230
+ let(:options) { { on: %i[fields emb_one emb_two], except: :emb_one } }
231
+ it { expect(subject[:relations][:embeds_one]).to eq('emtw' => %w[_id f_em_baz]) }
232
+ end
233
+
234
+ context 'with skipped embeds_many relation' do
235
+ let(:options) { { on: %i[fields emb_threes emb_fours], except: :emb_threes } }
236
+ it { expect(subject[:relations][:embeds_many]).to eq('emfs' => %w[_id f_em_baz]) }
237
+ end
238
+
239
+ context 'with reserved field' do
240
+ let(:options) { { on: %i[_id _type foo deleted_at] } }
241
+ it { expect(subject[:fields]).to eq %w[foo] }
242
+ end
243
+
244
+ context 'when embeds_one attribute passed' do
245
+ let(:options) { { on: { emb_one: :f_em_foo } } }
246
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo]) }
247
+ end
248
+
249
+ context 'when embeds_one attributes array passed' do
250
+ let(:options) { { on: { emb_one: %i[f_em_foo] } } }
251
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo]) }
252
+ end
253
+
254
+ context 'when embeds_many attribute passed' do
255
+ let(:options) { { on: { emb_threes: :f_em_foo } } }
256
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo]) }
257
+ end
258
+
259
+ context 'when embeds_many attributes array passed' do
260
+ let(:options) { { on: { emb_threes: %i[f_em_foo] } } }
261
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo]) }
262
+ end
263
+
264
+ context 'when embeds_one attributes not passed' do
265
+ let(:options) { { on: :emb_one } }
266
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id f_em_foo fmb]) }
267
+ end
268
+
269
+ context 'when embeds_many attributes not passed' do
270
+ let(:options) { { on: :emb_threes } }
271
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo fmb]) }
272
+ end
273
+
274
+ context 'when embeds_one attribute alias passed' do
275
+ let(:options) { { on: { emb_one: %i[f_em_bar] } } }
276
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w[_id fmb]) }
277
+ end
278
+
279
+ context 'when embeds_many attribute alias passed' do
280
+ let(:options) { { on: { emb_threes: %i[f_em_bar] } } }
281
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id fmb]) }
282
+ end
283
+
284
+ context 'with fields, and multiple embeds_one, and embeds_many relations' do
285
+ let(:options) { { on: [:foo, :bar, :emb_two, { emb_threes: %i[f_em_foo f_em_bar], emb_fours: :f_em_baz }] } }
286
+ it 'should categorize fields and associations correctly' do
287
+ expect(subject[:fields]).to eq(%w[foo b])
288
+ expect(subject[:relations][:embeds_one]).to eq('emtw' => %w[_id f_em_baz])
289
+ expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo fmb], 'emfs' => %w[_id f_em_baz])
290
+ end
291
+ end
292
+
293
+ context 'with field alias' do
294
+ let(:options) { { on: :bar } }
295
+ it { expect(subject[:fields]).to eq %w[b] }
296
+ end
297
+
298
+ context 'with dynamic field name' do
299
+ let(:options) { { on: :my_field } }
300
+ it { expect(subject[:dynamic]).to eq %w[my_field] }
301
+ end
302
+
303
+ context 'with relations' do
304
+ let(:options) { { on: :embedded_relations } }
305
+ it do
306
+ expect(subject[:relations]).to eq(
307
+ embeds_many: { 'emb_threes' => %w[_id f_em_foo fmb],
308
+ 'emfs' => %w[_id f_em_baz] },
309
+ embeds_one: { 'emb_one' => %w[_id f_em_foo fmb],
310
+ 'emtw' => %w[_id f_em_baz] }
311
+ )
312
+ end
313
+ end
314
+ end
315
+ end
316
+
317
+ describe ':modifier_field' do
318
+ let(:options) { { modifier_field: :my_modifier_field } }
319
+ it { expect(subject[:modifier_field]).to eq :my_modifier_field }
320
+ end
321
+
322
+ describe ':version_field' do
323
+ let(:options) { { version_field: :my_version_field } }
324
+ it { expect(subject[:version_field]).to eq :my_version_field }
325
+ end
326
+
327
+ describe ':paranoia_field' do
328
+ let(:options) { { paranoia_field: :my_paranoia_field } }
329
+ it { expect(subject[:paranoia_field]).to eq :my_paranoia_field }
330
+ end
331
+
332
+ describe ':changes_method' do
333
+ let(:options) { { changes_method: :my_changes_method } }
334
+ it { expect(subject[:changes_method]).to eq :my_changes_method }
335
+ end
336
+
337
+ describe ':scope' do
338
+ let(:options) { { scope: :my_scope } }
339
+ it { expect(subject[:scope]).to eq :my_scope }
340
+ end
341
+
342
+ describe ':track_create' do
343
+ let(:options) { { track_create: true } }
344
+ it { expect(subject[:track_create]).to be true }
345
+ end
346
+
347
+ describe ':track_update' do
348
+ let(:options) { { track_update: false } }
349
+ it { expect(subject[:track_update]).to be false }
350
+ end
351
+
352
+ describe ':track_destroy' do
353
+ let(:options) { { track_destroy: true } }
354
+ it { expect(subject[:track_destroy]).to be true }
355
+ end
356
+
357
+ describe '#remove_reserved_fields' do
358
+ let(:options) { { on: %i[_id _type foo version modifier_id] } }
359
+ it { expect(subject[:fields]).to eq %w[foo] }
360
+ it { expect(subject[:dynamic]).to eq [] }
361
+ end
362
+ end
363
+ end
364
+ end
365
+ end