iknow_view_models 2.10.1 → 3.0.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +119 -0
- data/.travis.yml +31 -0
- data/Appraisals +6 -16
- data/gemfiles/{rails_7_0.gemfile → rails_6_0_beta.gemfile} +2 -2
- data/iknow_view_models.gemspec +3 -5
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model/active_record/association_data.rb +206 -92
- data/lib/view_model/active_record/association_manipulation.rb +22 -12
- data/lib/view_model/active_record/cache/cacheable_view.rb +3 -13
- data/lib/view_model/active_record/cache.rb +2 -2
- data/lib/view_model/active_record/cloner.rb +11 -11
- data/lib/view_model/active_record/controller.rb +0 -2
- data/lib/view_model/active_record/update_context.rb +21 -3
- data/lib/view_model/active_record/update_data.rb +43 -45
- data/lib/view_model/active_record/update_operation.rb +265 -153
- data/lib/view_model/active_record/visitor.rb +9 -6
- data/lib/view_model/active_record.rb +94 -74
- data/lib/view_model/after_transaction_runner.rb +3 -18
- data/lib/view_model/callbacks.rb +2 -2
- data/lib/view_model/changes.rb +24 -16
- data/lib/view_model/config.rb +6 -2
- data/lib/view_model/deserialization_error.rb +31 -0
- data/lib/view_model/deserialize_context.rb +2 -6
- data/lib/view_model/error_view.rb +6 -5
- data/lib/view_model/record/attribute_data.rb +11 -6
- data/lib/view_model/record.rb +44 -24
- data/lib/view_model/serialize_context.rb +2 -63
- data/lib/view_model/test_helpers/arvm_builder.rb +2 -4
- data/lib/view_model/traversal_context.rb +2 -2
- data/lib/view_model.rb +21 -13
- data/shell.nix +1 -1
- data/test/helpers/arvm_test_models.rb +4 -12
- data/test/helpers/arvm_test_utilities.rb +6 -0
- data/test/helpers/controller_test_helpers.rb +6 -6
- data/test/helpers/viewmodel_spec_helpers.rb +63 -52
- data/test/unit/view_model/access_control_test.rb +88 -37
- data/test/unit/view_model/active_record/belongs_to_test.rb +110 -178
- data/test/unit/view_model/active_record/cache_test.rb +11 -5
- data/test/unit/view_model/active_record/cloner_test.rb +1 -1
- data/test/unit/view_model/active_record/controller_test.rb +12 -20
- data/test/unit/view_model/active_record/has_many_test.rb +540 -316
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +12 -15
- data/test/unit/view_model/active_record/has_many_through_test.rb +15 -58
- data/test/unit/view_model/active_record/has_one_test.rb +288 -135
- data/test/unit/view_model/active_record/poly_test.rb +0 -1
- data/test/unit/view_model/active_record/shared_test.rb +21 -39
- data/test/unit/view_model/active_record/version_test.rb +3 -2
- data/test/unit/view_model/active_record_test.rb +5 -63
- data/test/unit/view_model/callbacks_test.rb +1 -0
- data/test/unit/view_model/record_test.rb +0 -32
- data/test/unit/view_model/traversal_context_test.rb +13 -12
- metadata +15 -25
- data/.github/workflows/gem-push.yml +0 -31
- data/.github/workflows/test.yml +0 -65
- data/gemfiles/rails_6_0.gemfile +0 -9
- data/gemfiles/rails_6_1.gemfile +0 -9
- data/test/unit/view_model/active_record/optional_attribute_view_test.rb +0 -58
@@ -22,6 +22,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
define_viewmodel do
|
25
|
+
root!
|
25
26
|
attributes :name
|
26
27
|
end
|
27
28
|
end
|
@@ -43,8 +44,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
43
44
|
end
|
44
45
|
|
45
46
|
define_viewmodel do
|
47
|
+
root!
|
46
48
|
attributes :name
|
47
|
-
association :category
|
49
|
+
association :category
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -66,16 +68,11 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
66
68
|
enable_logging!
|
67
69
|
end
|
68
70
|
|
69
|
-
def serialize_context
|
70
|
-
ParentView.new_serialize_context(include: :category)
|
71
|
-
end
|
72
|
-
|
73
71
|
def test_loading_batching
|
74
72
|
Parent.create(category: Category.new)
|
75
73
|
|
76
74
|
log_queries do
|
77
|
-
serialize(ParentView.load(
|
78
|
-
serialize_context: serialize_context)
|
75
|
+
serialize(ParentView.load())
|
79
76
|
end
|
80
77
|
assert_equal(['Parent Load', 'Category Load'],
|
81
78
|
logged_load_queries)
|
@@ -104,7 +101,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
104
101
|
end
|
105
102
|
|
106
103
|
def test_serialize_view
|
107
|
-
view, refs = serialize_with_references(ParentView.new(@parent1)
|
104
|
+
view, refs = serialize_with_references(ParentView.new(@parent1))
|
108
105
|
cat1_ref = refs.detect { |_, v| v['_type'] == 'Category' }.first
|
109
106
|
|
110
107
|
assert_equal({cat1_ref => { '_type' => "Category",
|
@@ -122,20 +119,14 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
122
119
|
end
|
123
120
|
|
124
121
|
def test_shared_eager_include
|
125
|
-
|
126
|
-
|
127
|
-
assert_equal(DeepPreloader::Spec.new, parent_includes)
|
128
|
-
|
129
|
-
extra_includes = ParentView.eager_includes(serialize_context: ParentView.new_serialize_context(include: :category))
|
130
|
-
|
131
|
-
assert_equal(DeepPreloader::Spec.new('category' => DeepPreloader::Spec.new), extra_includes)
|
122
|
+
includes = ParentView.eager_includes
|
123
|
+
assert_equal(DeepPreloader::Spec.new('category' => DeepPreloader::Spec.new), includes)
|
132
124
|
end
|
133
125
|
|
134
126
|
def test_shared_serialize_interning
|
135
127
|
@parent2.update(category: @parent1.category)
|
136
128
|
view, refs = serialize_with_references([ParentView.new(@parent1),
|
137
|
-
ParentView.new(@parent2)]
|
138
|
-
serialize_context: ParentView.new_serialize_context(include: :category))
|
129
|
+
ParentView.new(@parent2)])
|
139
130
|
|
140
131
|
category_ref = view.first['category']['_ref']
|
141
132
|
|
@@ -144,7 +135,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
144
135
|
end
|
145
136
|
|
146
137
|
def test_shared_add_reference
|
147
|
-
alter_by_view!(ParentView, @parent2
|
138
|
+
alter_by_view!(ParentView, @parent2) do |p2view, refs|
|
148
139
|
p2view['category'] = { '_ref' => 'myref' }
|
149
140
|
refs['myref'] = update_hash_for(CategoryView, @category1)
|
150
141
|
end
|
@@ -153,7 +144,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
153
144
|
end
|
154
145
|
|
155
146
|
def test_shared_add_multiple_references
|
156
|
-
alter_by_view!(ParentView, [@parent1, @parent2]
|
147
|
+
alter_by_view!(ParentView, [@parent1, @parent2]) do |(p1view, p2view), refs|
|
157
148
|
refs.delete(p1view['category']['_ref'])
|
158
149
|
refs['myref'] = update_hash_for(CategoryView, @category1)
|
159
150
|
|
@@ -167,7 +158,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
167
158
|
|
168
159
|
def test_shared_requires_all_references
|
169
160
|
ex = assert_raises(ViewModel::DeserializationError::InvalidStructure) do
|
170
|
-
alter_by_view!(ParentView, @parent2
|
161
|
+
alter_by_view!(ParentView, @parent2) do |p2view, refs|
|
171
162
|
refs['spurious_ref'] = { '_type' => 'Parent', 'id' => @parent1.id }
|
172
163
|
end
|
173
164
|
end
|
@@ -176,8 +167,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
176
167
|
|
177
168
|
def test_shared_requires_valid_references
|
178
169
|
assert_raises(ViewModel::DeserializationError::InvalidSharedReference) do
|
179
|
-
|
180
|
-
alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
|
170
|
+
alter_by_view!(ParentView, @parent1) do |p1view, refs|
|
181
171
|
refs.clear # remove the expected serialized refs
|
182
172
|
end
|
183
173
|
end
|
@@ -185,8 +175,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
185
175
|
|
186
176
|
def test_shared_requires_assignable_type
|
187
177
|
ex = assert_raises(ViewModel::DeserializationError::InvalidAssociationType) do
|
188
|
-
|
189
|
-
alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
|
178
|
+
alter_by_view!(ParentView, @parent1) do |p1view, refs|
|
190
179
|
p1view['category'] = { '_ref' => 'p2' }
|
191
180
|
refs['p2'] = update_hash_for(ParentView, @parent2)
|
192
181
|
end
|
@@ -195,10 +184,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
195
184
|
end
|
196
185
|
|
197
186
|
def test_shared_requires_unique_references
|
198
|
-
serialize_context = ParentView.new_serialize_context(include: :category)
|
199
187
|
c1_ref = update_hash_for(CategoryView, @category1)
|
200
188
|
assert_raises(ViewModel::DeserializationError::DuplicateNodes) do
|
201
|
-
alter_by_view!(ParentView, [@parent1, @parent2]
|
189
|
+
alter_by_view!(ParentView, [@parent1, @parent2]) do |(p1view, p2view), refs|
|
202
190
|
refs['c_a'] = c1_ref.dup
|
203
191
|
refs['c_b'] = c1_ref.dup
|
204
192
|
p1view['category'] = { '_ref' => 'c_a' }
|
@@ -208,8 +196,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
208
196
|
end
|
209
197
|
|
210
198
|
def test_shared_updates_shared_data
|
211
|
-
|
212
|
-
alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
|
199
|
+
alter_by_view!(ParentView, @parent1) do |p1view, refs|
|
213
200
|
category_ref = p1view['category']['_ref']
|
214
201
|
refs[category_ref]['name'] = 'newcatname'
|
215
202
|
end
|
@@ -217,8 +204,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
217
204
|
end
|
218
205
|
|
219
206
|
def test_shared_delete_reference
|
220
|
-
|
221
|
-
alter_by_view!(ParentView, @parent1, serialize_context: serialize_context) do |p1view, refs|
|
207
|
+
alter_by_view!(ParentView, @parent1) do |p1view, refs|
|
222
208
|
category_ref = p1view['category']['_ref']
|
223
209
|
refs.delete(category_ref)
|
224
210
|
p1view['category'] = nil
|
@@ -228,10 +214,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
228
214
|
end
|
229
215
|
|
230
216
|
def test_child_edit_doesnt_editcheck_parent
|
231
|
-
serialize_context = ParentView.new_serialize_context(include: :category)
|
232
217
|
d_context = ParentView.new_deserialize_context
|
233
218
|
|
234
|
-
alter_by_view!(ParentView, @parent1,
|
219
|
+
alter_by_view!(ParentView, @parent1, deserialize_context: d_context) do |view, refs|
|
235
220
|
refs[view['category']["_ref"]]["name"] = "changed"
|
236
221
|
end
|
237
222
|
|
@@ -240,9 +225,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
240
225
|
end
|
241
226
|
|
242
227
|
def test_child_change_editchecks_parent
|
243
|
-
|
244
|
-
|
245
|
-
nv, d_context = alter_by_view!(ParentView, @parent1, serialize_context: s_context) do |view, refs|
|
228
|
+
nv, d_context = alter_by_view!(ParentView, @parent1) do |view, refs|
|
246
229
|
refs.delete(view['category']['_ref'])
|
247
230
|
view['category']['_ref'] = 'new_cat'
|
248
231
|
refs['new_cat'] = { '_type' => 'Category', 'name' => 'new category' }
|
@@ -253,10 +236,9 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
253
236
|
end
|
254
237
|
|
255
238
|
def test_child_delete_editchecks_parent
|
256
|
-
serialize_context = ParentView.new_serialize_context(include: :category)
|
257
239
|
d_context = ParentView.new_deserialize_context
|
258
240
|
|
259
|
-
alter_by_view!(ParentView, @parent1,
|
241
|
+
alter_by_view!(ParentView, @parent1, deserialize_context: d_context) do |view, refs|
|
260
242
|
refs.delete(view['category']['_ref'])
|
261
243
|
view['category'] = nil
|
262
244
|
end
|
@@ -268,7 +250,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
268
250
|
deps = ParentView.dependent_viewmodels
|
269
251
|
assert_equal([ParentView, CategoryView].to_set, deps)
|
270
252
|
|
271
|
-
deps = ParentView.dependent_viewmodels(
|
253
|
+
deps = ParentView.dependent_viewmodels(include_referenced: false)
|
272
254
|
assert_equal([ParentView].to_set, deps)
|
273
255
|
end
|
274
256
|
|
@@ -278,7 +260,7 @@ class ViewModel::ActiveRecord::SharedTest < ActiveSupport::TestCase
|
|
278
260
|
CategoryView.view_name => CategoryView.schema_version },
|
279
261
|
vers)
|
280
262
|
|
281
|
-
vers = ParentView.deep_schema_version(
|
263
|
+
vers = ParentView.deep_schema_version(include_referenced: false)
|
282
264
|
assert_equal({ ParentView.view_name => ParentView.schema_version },
|
283
265
|
vers)
|
284
266
|
end
|
@@ -21,13 +21,13 @@ class ViewModel::ActiveRecord::VersionTest < ActiveSupport::TestCase
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
build_viewmodel(:Target) do
|
26
25
|
define_schema {}
|
27
26
|
define_model do
|
28
27
|
has_one :parent, inverse_of: :target
|
29
28
|
end
|
30
29
|
define_viewmodel do
|
30
|
+
root!
|
31
31
|
self.schema_version = 20
|
32
32
|
end
|
33
33
|
end
|
@@ -44,8 +44,9 @@ class ViewModel::ActiveRecord::VersionTest < ActiveSupport::TestCase
|
|
44
44
|
end
|
45
45
|
define_viewmodel do
|
46
46
|
self.schema_version = 5
|
47
|
+
root!
|
47
48
|
association :child, viewmodels: [:ChildA]
|
48
|
-
association :target
|
49
|
+
association :target
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
@@ -17,7 +17,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
|
|
17
17
|
build_viewmodel(:Trivial) do
|
18
18
|
define_schema
|
19
19
|
define_model {}
|
20
|
-
define_viewmodel {}
|
20
|
+
define_viewmodel { root! }
|
21
21
|
end
|
22
22
|
|
23
23
|
build_viewmodel(:Parent) do
|
@@ -35,6 +35,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
define_viewmodel do
|
38
|
+
root!
|
38
39
|
attributes :name, :lock_version
|
39
40
|
attribute :one, read_only: true
|
40
41
|
end
|
@@ -376,66 +377,6 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
|
|
376
377
|
end
|
377
378
|
end
|
378
379
|
|
379
|
-
# Tests for functionality common to all ARVM instances, but require some kind
|
380
|
-
# of relationship.
|
381
|
-
class RelationshipTests < ActiveSupport::TestCase
|
382
|
-
include ARVMTestUtilities
|
383
|
-
|
384
|
-
def before_all
|
385
|
-
super
|
386
|
-
|
387
|
-
build_viewmodel(:Parent) do
|
388
|
-
define_schema do |t|
|
389
|
-
t.string :name
|
390
|
-
end
|
391
|
-
|
392
|
-
define_model do
|
393
|
-
has_many :children, dependent: :destroy, inverse_of: :parent
|
394
|
-
end
|
395
|
-
|
396
|
-
define_viewmodel do
|
397
|
-
attributes :name
|
398
|
-
associations :children
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
build_viewmodel(:Child) do
|
403
|
-
define_schema do |t|
|
404
|
-
t.references :parent, null: false, foreign_key: true
|
405
|
-
t.string :name
|
406
|
-
end
|
407
|
-
|
408
|
-
define_model do
|
409
|
-
belongs_to :parent, inverse_of: :children
|
410
|
-
end
|
411
|
-
|
412
|
-
define_viewmodel do
|
413
|
-
attributes :name
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
def test_updated_associations_returned
|
419
|
-
# This test ensures the data is passed back through the context. The tests
|
420
|
-
# for the values are in the relationship-specific tests.
|
421
|
-
|
422
|
-
updated_by_view = ->(view) do
|
423
|
-
context = ViewModelBase.new_deserialize_context
|
424
|
-
ParentView.deserialize_from_view(view, deserialize_context: context)
|
425
|
-
context.updated_associations
|
426
|
-
end
|
427
|
-
|
428
|
-
assert_equal({},
|
429
|
-
updated_by_view.({ '_type' => 'Parent',
|
430
|
-
'name' => 'p' }))
|
431
|
-
|
432
|
-
assert_equal({ 'children' => {} },
|
433
|
-
updated_by_view.({ '_type' => 'Parent',
|
434
|
-
'name' => 'p',
|
435
|
-
'children' => [] }))
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
380
|
# Parent view should be correctly passed down the tree when deserializing
|
440
381
|
class DeserializationParentContextTest < ActiveSupport::TestCase
|
441
382
|
include ARVMTestUtilities
|
@@ -499,7 +440,7 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
|
|
499
440
|
end
|
500
441
|
end
|
501
442
|
|
502
|
-
|
443
|
+
# Parent view should be correctly passed down the tree when deserializing
|
503
444
|
class DeferredConstraintTest < ActiveSupport::TestCase
|
504
445
|
include ARVMTestUtilities
|
505
446
|
|
@@ -516,7 +457,8 @@ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
|
|
516
457
|
end
|
517
458
|
|
518
459
|
define_viewmodel do
|
519
|
-
|
460
|
+
root!
|
461
|
+
association :child
|
520
462
|
end
|
521
463
|
end
|
522
464
|
List.connection.execute("ALTER TABLE lists ADD CONSTRAINT unique_child UNIQUE (child_id) DEFERRABLE INITIALLY DEFERRED")
|
@@ -348,6 +348,7 @@ class ViewModel::CallbacksTest < ActiveSupport::TestCase
|
|
348
348
|
alter_by_view!(viewmodel_class, vm.model) do |view, _refs|
|
349
349
|
view['next'] = nil
|
350
350
|
end
|
351
|
+
|
351
352
|
value(callback.hook_trace).must_equal(
|
352
353
|
[
|
353
354
|
visit(ViewModel::Callbacks::Hook::BeforeVisit, vm),
|
@@ -204,12 +204,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
|
|
204
204
|
assert_equal("unknown", ex.attribute)
|
205
205
|
end
|
206
206
|
|
207
|
-
it "can prune an attribute" do
|
208
|
-
h = viewmodel_class.new(default_model).to_hash(serialize_context: TestSerializeContext.new(prune: [:simple]))
|
209
|
-
pruned_view = default_view.tap { |v| v.delete("simple") }
|
210
|
-
assert_equal(pruned_view, h)
|
211
|
-
end
|
212
|
-
|
213
207
|
it "edit checks when creating empty" do
|
214
208
|
vm = viewmodel_class.deserialize_from_view(view_base, deserialize_context: create_context)
|
215
209
|
refute(default_model.equal?(vm.model), "returned model was the same")
|
@@ -377,24 +371,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
|
|
377
371
|
end
|
378
372
|
end
|
379
373
|
|
380
|
-
describe "with optional attributes" do
|
381
|
-
let(:attributes) { { optional: { optional: true } } }
|
382
|
-
|
383
|
-
include CanDeserializeToNew
|
384
|
-
include CanDeserializeToExisting
|
385
|
-
|
386
|
-
it "can serialize with the optional attribute" do
|
387
|
-
h = viewmodel_class.new(default_model).to_hash(serialize_context: TestSerializeContext.new(include: [:optional]))
|
388
|
-
assert_equal(default_view, h)
|
389
|
-
end
|
390
|
-
|
391
|
-
it "can serialize without the optional attribute" do
|
392
|
-
h = viewmodel_class.new(default_model).to_hash
|
393
|
-
pruned_view = default_view.tap { |v| v.delete("optional") }
|
394
|
-
assert_equal(pruned_view, h)
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
374
|
Nested = Struct.new(:member)
|
399
375
|
|
400
376
|
class NestedView < TestViewModel
|
@@ -448,14 +424,6 @@ class ViewModel::RecordTest < ActiveSupport::TestCase
|
|
448
424
|
assert_edited(vm, new: false, changed_attributes: [:nested])
|
449
425
|
assert_edited(vm.nested, new: true, changed_attributes: [:member])
|
450
426
|
end
|
451
|
-
|
452
|
-
it "can prune attributes in the nested value" do
|
453
|
-
h = viewmodel_class.new(default_model).to_hash(
|
454
|
-
serialize_context: TestSerializeContext.new(prune: { nested: [:member] }))
|
455
|
-
|
456
|
-
pruned_view = default_view.tap { |v| v["nested"].delete("member") }
|
457
|
-
assert_equal(pruned_view, h)
|
458
|
-
end
|
459
427
|
end
|
460
428
|
|
461
429
|
describe "with array of nested viewmodel" do
|
@@ -35,6 +35,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
35
35
|
after_visit do
|
36
36
|
ref = view.to_reference
|
37
37
|
raise RuntimeError.new('Visited twice') if details.has_key?(ref)
|
38
|
+
|
38
39
|
details[ref] = ContextDetail.new(
|
39
40
|
context.parent_viewmodel&.to_reference,
|
40
41
|
context.parent_association,
|
@@ -87,12 +88,12 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
87
88
|
# models have no more than one shared association, and if present it is the
|
88
89
|
# one under test.
|
89
90
|
def clear_subject_association(view, refs)
|
90
|
-
refs.clear if subject_association.
|
91
|
+
refs.clear if subject_association.referenced?
|
91
92
|
view[subject_association_name] = subject_association.collection? ? [] : nil
|
92
93
|
end
|
93
94
|
|
94
95
|
def set_subject_association(view, refs, value)
|
95
|
-
if subject_association.
|
96
|
+
if subject_association.referenced?
|
96
97
|
refs.clear
|
97
98
|
value = convert_to_refs(refs, value)
|
98
99
|
end
|
@@ -100,7 +101,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def add_to_subject_association(view, refs, value)
|
103
|
-
if subject_association.
|
104
|
+
if subject_association.referenced?
|
104
105
|
value = convert_to_refs(refs, value)
|
105
106
|
end
|
106
107
|
view[subject_association_name] << value
|
@@ -108,12 +109,12 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
108
109
|
|
109
110
|
def remove_from_subject_association(view, refs)
|
110
111
|
view[subject_association_name].reject! do |child|
|
111
|
-
if subject_association.
|
112
|
+
if subject_association.referenced?
|
112
113
|
ref = child[ViewModel::REFERENCE_ATTRIBUTE]
|
113
114
|
child = refs[ref]
|
114
115
|
end
|
115
116
|
match = yield(child)
|
116
|
-
if match && subject_association.
|
117
|
+
if match && subject_association.referenced?
|
117
118
|
refs.delete(ref)
|
118
119
|
end
|
119
120
|
match
|
@@ -167,7 +168,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
167
168
|
end
|
168
169
|
|
169
170
|
expected = expected_parent_details
|
170
|
-
expected = expected.merge(expected_children_details) unless subject_association.
|
171
|
+
expected = expected.merge(expected_children_details) unless subject_association.referenced?
|
171
172
|
assert_traversal_matches(expected, context_recorder.details)
|
172
173
|
end
|
173
174
|
|
@@ -179,7 +180,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
179
180
|
end
|
180
181
|
|
181
182
|
expected = expected_parent_details
|
182
|
-
expected = expected.merge(expected_children_details) unless subject_association.
|
183
|
+
expected = expected.merge(expected_children_details) unless subject_association.referenced?
|
183
184
|
expected = expected.merge(new_child_expected_details)
|
184
185
|
assert_traversal_matches(expected, context_recorder.details)
|
185
186
|
end
|
@@ -190,7 +191,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
190
191
|
vm.replace_associated(subject_association_name, replacement, deserialize_context: ctx)
|
191
192
|
|
192
193
|
expected = expected_parent_details
|
193
|
-
expected = expected.merge(expected_children_details) unless subject_association.
|
194
|
+
expected = expected.merge(expected_children_details) unless subject_association.referenced?
|
194
195
|
expected = expected.merge(new_child_expected_details)
|
195
196
|
assert_traversal_matches(expected, context_recorder.details)
|
196
197
|
end
|
@@ -224,7 +225,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
224
225
|
end
|
225
226
|
|
226
227
|
expected = expected_parent_details.merge(expected_children_details)
|
227
|
-
expected = expected.except(removed_child.to_reference) if subject_association.
|
228
|
+
expected = expected.except(removed_child.to_reference) if subject_association.referenced?
|
228
229
|
assert_traversal_matches(expected, context_recorder.details)
|
229
230
|
end
|
230
231
|
|
@@ -241,7 +242,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
241
242
|
vm.delete_associated(subject_association_name, removed_child.id, deserialize_context: ctx)
|
242
243
|
|
243
244
|
expected = expected_parent_details
|
244
|
-
expected = expected.merge(removed_child_expected_details) unless subject_association.
|
245
|
+
expected = expected.merge(removed_child_expected_details) unless subject_association.referenced?
|
245
246
|
assert_traversal_matches(expected, context_recorder.details)
|
246
247
|
end
|
247
248
|
end
|
@@ -265,7 +266,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
265
266
|
|
266
267
|
let(:root_detail) { ContextDetail.new(nil, nil, true) }
|
267
268
|
let(:child_detail) do
|
268
|
-
if subject_association.
|
269
|
+
if subject_association.referenced?
|
269
270
|
root_detail
|
270
271
|
else
|
271
272
|
ContextDetail.new(vm.to_reference, subject_association_name, false)
|
@@ -346,7 +347,7 @@ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
|
|
346
347
|
end
|
347
348
|
|
348
349
|
describe 'with parent and shared child' do
|
349
|
-
include ViewModelSpecHelpers::
|
350
|
+
include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
|
350
351
|
|
351
352
|
include BehavesLikeSerialization
|
352
353
|
include BehavesLikeDeserialization
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iknow_view_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iKnow Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.0.1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.0.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: iknow_cache
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,22 +84,16 @@ dependencies:
|
|
84
84
|
name: iknow_params
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 2.2.0
|
90
|
-
- - "<"
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: '2.4'
|
93
90
|
type: :runtime
|
94
91
|
prerelease: false
|
95
92
|
version_requirements: !ruby/object:Gem::Requirement
|
96
93
|
requirements:
|
97
|
-
- - "
|
94
|
+
- - "~>"
|
98
95
|
- !ruby/object:Gem::Version
|
99
96
|
version: 2.2.0
|
100
|
-
- - "<"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '2.4'
|
103
97
|
- !ruby/object:Gem::Dependency
|
104
98
|
name: safe_values
|
105
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -286,16 +280,16 @@ dependencies:
|
|
286
280
|
name: pg
|
287
281
|
requirement: !ruby/object:Gem::Requirement
|
288
282
|
requirements:
|
289
|
-
- - "
|
283
|
+
- - "~>"
|
290
284
|
- !ruby/object:Gem::Version
|
291
|
-
version: '0'
|
285
|
+
version: '0.18'
|
292
286
|
type: :development
|
293
287
|
prerelease: false
|
294
288
|
version_requirements: !ruby/object:Gem::Requirement
|
295
289
|
requirements:
|
296
|
-
- - "
|
290
|
+
- - "~>"
|
297
291
|
- !ruby/object:Gem::Version
|
298
|
-
version: '0'
|
292
|
+
version: '0.18'
|
299
293
|
- !ruby/object:Gem::Dependency
|
300
294
|
name: pry
|
301
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -359,11 +353,11 @@ executables: []
|
|
359
353
|
extensions: []
|
360
354
|
extra_rdoc_files: []
|
361
355
|
files:
|
356
|
+
- ".circleci/config.yml"
|
362
357
|
- ".envrc"
|
363
|
-
- ".github/workflows/gem-push.yml"
|
364
|
-
- ".github/workflows/test.yml"
|
365
358
|
- ".gitignore"
|
366
359
|
- ".idea/codeStyleSettings.xml"
|
360
|
+
- ".travis.yml"
|
367
361
|
- Appraisals
|
368
362
|
- Gemfile
|
369
363
|
- LICENSE.txt
|
@@ -371,9 +365,7 @@ files:
|
|
371
365
|
- Rakefile
|
372
366
|
- appveyor.yml
|
373
367
|
- gemfiles/rails_5_2.gemfile
|
374
|
-
- gemfiles/
|
375
|
-
- gemfiles/rails_6_1.gemfile
|
376
|
-
- gemfiles/rails_7_0.gemfile
|
368
|
+
- gemfiles/rails_6_0_beta.gemfile
|
377
369
|
- iknow_view_models.gemspec
|
378
370
|
- lib/iknow_view_models.rb
|
379
371
|
- lib/iknow_view_models/railtie.rb
|
@@ -446,7 +438,6 @@ files:
|
|
446
438
|
- test/unit/view_model/active_record/has_many_through_test.rb
|
447
439
|
- test/unit/view_model/active_record/has_one_test.rb
|
448
440
|
- test/unit/view_model/active_record/namespacing_test.rb
|
449
|
-
- test/unit/view_model/active_record/optional_attribute_view_test.rb
|
450
441
|
- test/unit/view_model/active_record/poly_test.rb
|
451
442
|
- test/unit/view_model/active_record/shared_test.rb
|
452
443
|
- test/unit/view_model/active_record/version_test.rb
|
@@ -469,14 +460,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
469
460
|
requirements:
|
470
461
|
- - ">="
|
471
462
|
- !ruby/object:Gem::Version
|
472
|
-
version:
|
463
|
+
version: '0'
|
473
464
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
474
465
|
requirements:
|
475
466
|
- - ">="
|
476
467
|
- !ruby/object:Gem::Version
|
477
468
|
version: '0'
|
478
469
|
requirements: []
|
479
|
-
rubygems_version: 3.
|
470
|
+
rubygems_version: 3.0.3
|
480
471
|
signing_key:
|
481
472
|
specification_version: 4
|
482
473
|
summary: ViewModels provide a means of encapsulating a collection of related data
|
@@ -504,7 +495,6 @@ test_files:
|
|
504
495
|
- test/unit/view_model/active_record/has_many_through_test.rb
|
505
496
|
- test/unit/view_model/active_record/has_one_test.rb
|
506
497
|
- test/unit/view_model/active_record/namespacing_test.rb
|
507
|
-
- test/unit/view_model/active_record/optional_attribute_view_test.rb
|
508
498
|
- test/unit/view_model/active_record/poly_test.rb
|
509
499
|
- test/unit/view_model/active_record/shared_test.rb
|
510
500
|
- test/unit/view_model/active_record/version_test.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
name: Publish Ruby Gem
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches: [ "v2.x" ]
|
6
|
-
|
7
|
-
jobs:
|
8
|
-
build:
|
9
|
-
name: Build + Publish
|
10
|
-
runs-on: ubuntu-latest
|
11
|
-
permissions:
|
12
|
-
contents: read
|
13
|
-
packages: write
|
14
|
-
|
15
|
-
steps:
|
16
|
-
- uses: actions/checkout@v3
|
17
|
-
- name: Set up Ruby 2.7
|
18
|
-
uses: ruby/setup-ruby@v1
|
19
|
-
with:
|
20
|
-
ruby-version: 2.7
|
21
|
-
|
22
|
-
- name: Publish to RubyGems
|
23
|
-
run: |
|
24
|
-
mkdir -p $HOME/.gem
|
25
|
-
touch $HOME/.gem/credentials
|
26
|
-
chmod 0600 $HOME/.gem/credentials
|
27
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
28
|
-
gem build *.gemspec
|
29
|
-
gem push *.gem
|
30
|
-
env:
|
31
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|