iknow_view_models 3.1.8 → 3.2.4
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 +6 -6
- data/.rubocop.yml +18 -0
- data/Appraisals +6 -6
- data/Gemfile +6 -2
- data/Rakefile +5 -5
- data/gemfiles/rails_5_2.gemfile +5 -5
- data/gemfiles/rails_6_0.gemfile +9 -0
- data/iknow_view_models.gemspec +40 -38
- data/lib/iknow_view_models.rb +9 -7
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model.rb +31 -17
- data/lib/view_model/access_control.rb +5 -2
- data/lib/view_model/access_control/composed.rb +10 -9
- data/lib/view_model/access_control/open.rb +2 -0
- data/lib/view_model/access_control/read_only.rb +2 -0
- data/lib/view_model/access_control/tree.rb +11 -6
- data/lib/view_model/access_control_error.rb +4 -1
- data/lib/view_model/active_record.rb +17 -15
- data/lib/view_model/active_record/association_data.rb +2 -1
- data/lib/view_model/active_record/association_manipulation.rb +6 -4
- data/lib/view_model/active_record/cache.rb +114 -34
- data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
- data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
- data/lib/view_model/active_record/controller.rb +68 -1
- data/lib/view_model/active_record/controller_base.rb +4 -1
- data/lib/view_model/active_record/nested_controller_base.rb +1 -0
- data/lib/view_model/active_record/update_context.rb +8 -6
- data/lib/view_model/active_record/update_data.rb +32 -30
- data/lib/view_model/active_record/update_operation.rb +17 -13
- data/lib/view_model/active_record/visitor.rb +0 -1
- data/lib/view_model/after_transaction_runner.rb +0 -1
- data/lib/view_model/callbacks.rb +3 -1
- data/lib/view_model/controller.rb +13 -3
- data/lib/view_model/deserialization_error.rb +15 -12
- data/lib/view_model/error.rb +12 -10
- data/lib/view_model/error_view.rb +3 -1
- data/lib/view_model/migratable_view.rb +78 -0
- data/lib/view_model/migration.rb +48 -0
- data/lib/view_model/migration/no_path_error.rb +26 -0
- data/lib/view_model/migration/one_way_error.rb +24 -0
- data/lib/view_model/migration/unspecified_version_error.rb +24 -0
- data/lib/view_model/migrator.rb +108 -0
- data/lib/view_model/record.rb +15 -14
- data/lib/view_model/reference.rb +3 -1
- data/lib/view_model/references.rb +8 -5
- data/lib/view_model/registry.rb +14 -2
- data/lib/view_model/schemas.rb +9 -4
- data/lib/view_model/serialization_error.rb +4 -1
- data/lib/view_model/serialize_context.rb +4 -4
- data/lib/view_model/test_helpers.rb +8 -3
- data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
- data/lib/view_model/traversal_context.rb +2 -1
- data/nix/dependencies.nix +5 -0
- data/nix/gem/generate.rb +2 -1
- data/shell.nix +8 -3
- data/test/.rubocop.yml +14 -0
- data/test/helpers/arvm_test_models.rb +12 -9
- data/test/helpers/arvm_test_utilities.rb +5 -3
- data/test/helpers/controller_test_helpers.rb +55 -32
- data/test/helpers/match_enumerator.rb +1 -0
- data/test/helpers/query_logging.rb +2 -1
- data/test/helpers/test_access_control.rb +5 -3
- data/test/helpers/viewmodel_spec_helpers.rb +88 -22
- data/test/unit/view_model/access_control_test.rb +144 -144
- data/test/unit/view_model/active_record/alias_test.rb +15 -13
- data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
- data/test/unit/view_model/active_record/cache_test.rb +68 -31
- data/test/unit/view_model/active_record/cloner_test.rb +67 -63
- data/test/unit/view_model/active_record/controller_test.rb +113 -65
- data/test/unit/view_model/active_record/counter_test.rb +10 -9
- data/test/unit/view_model/active_record/customization_test.rb +59 -58
- data/test/unit/view_model/active_record/has_many_test.rb +112 -111
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
- data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
- data/test/unit/view_model/active_record/has_one_test.rb +37 -36
- data/test/unit/view_model/active_record/migration_test.rb +161 -0
- data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
- data/test/unit/view_model/active_record/poly_test.rb +44 -45
- data/test/unit/view_model/active_record/shared_test.rb +30 -28
- data/test/unit/view_model/active_record/version_test.rb +9 -7
- data/test/unit/view_model/active_record_test.rb +72 -72
- data/test/unit/view_model/callbacks_test.rb +19 -15
- data/test/unit/view_model/controller_test.rb +4 -2
- data/test/unit/view_model/record_test.rb +158 -145
- data/test/unit/view_model/registry_test.rb +38 -0
- data/test/unit/view_model/traversal_context_test.rb +4 -5
- data/test/unit/view_model_test.rb +18 -16
- metadata +38 -12
- data/.travis.yml +0 -31
- data/appveyor.yml +0 -22
- data/gemfiles/rails_6_0_beta.gemfile +0 -9
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
require_relative "../../../helpers/arvm_test_models.rb"
|
3
|
-
require_relative "../../../helpers/viewmodel_spec_helpers.rb"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
3
|
+
require_relative '../../../helpers/arvm_test_utilities'
|
4
|
+
require_relative '../../../helpers/arvm_test_models'
|
5
|
+
require_relative '../../../helpers/viewmodel_spec_helpers'
|
6
6
|
|
7
|
-
require
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
require 'view_model/active_record'
|
8
10
|
|
9
11
|
class ViewModel::ActiveRecord::Alias < ActiveSupport::TestCase
|
10
12
|
include ARVMTestUtilities
|
@@ -14,18 +16,18 @@ class ViewModel::ActiveRecord::Alias < ActiveSupport::TestCase
|
|
14
16
|
|
15
17
|
def child_attributes
|
16
18
|
super.merge(
|
17
|
-
viewmodel: ->(
|
18
|
-
add_view_alias
|
19
|
-
add_view_alias
|
20
|
-
end
|
19
|
+
viewmodel: ->(_v) do
|
20
|
+
add_view_alias 'ChildA'
|
21
|
+
add_view_alias 'ChildB'
|
22
|
+
end,
|
21
23
|
)
|
22
24
|
end
|
23
25
|
|
24
|
-
it
|
25
|
-
%w
|
26
|
+
it 'permits association types to be aliased' do
|
27
|
+
%w[Child ChildA ChildB].each do |view_alias|
|
26
28
|
view = {
|
27
|
-
|
28
|
-
|
29
|
+
'_type' => viewmodel_class.view_name,
|
30
|
+
'child' => { '_type' => view_alias },
|
29
31
|
}
|
30
32
|
|
31
33
|
parent = viewmodel_class.deserialize_from_view(view).model
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
require_relative "../../../helpers/arvm_test_models.rb"
|
3
|
-
require_relative '../../../helpers/viewmodel_spec_helpers.rb'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
3
|
+
require_relative '../../../helpers/arvm_test_utilities'
|
4
|
+
require_relative '../../../helpers/arvm_test_models'
|
5
|
+
require_relative '../../../helpers/viewmodel_spec_helpers'
|
6
6
|
|
7
|
-
require
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
require 'view_model/active_record'
|
8
10
|
|
9
11
|
class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
10
12
|
include ARVMTestUtilities
|
@@ -14,13 +16,13 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
14
16
|
def setup
|
15
17
|
super
|
16
18
|
|
17
|
-
# TODO make a `has_list?` that allows a parent to set all children as an array
|
18
|
-
@model1 = model_class.new(name:
|
19
|
-
child: child_model_class.new(name:
|
19
|
+
# TODO: make a `has_list?` that allows a parent to set all children as an array
|
20
|
+
@model1 = model_class.new(name: 'p1',
|
21
|
+
child: child_model_class.new(name: 'p1l'))
|
20
22
|
@model1.save!
|
21
23
|
|
22
|
-
@model2 = model_class.new(name:
|
23
|
-
child: child_model_class.new(name:
|
24
|
+
@model2 = model_class.new(name: 'p2',
|
25
|
+
child: child_model_class.new(name: 'p2l'))
|
24
26
|
|
25
27
|
@model2.save!
|
26
28
|
|
@@ -30,14 +32,14 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
30
32
|
def test_serialize_view
|
31
33
|
view, _refs = serialize_with_references(ModelView.new(@model1))
|
32
34
|
|
33
|
-
assert_equal({
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
assert_equal({ '_type' => 'Model',
|
36
|
+
'_version' => 1,
|
37
|
+
'id' => @model1.id,
|
38
|
+
'name' => @model1.name,
|
39
|
+
'child' => { '_type' => 'Child',
|
40
|
+
'_version' => 1,
|
41
|
+
'id' => @model1.child.id,
|
42
|
+
'name' => @model1.child.name },
|
41
43
|
},
|
42
44
|
view)
|
43
45
|
end
|
@@ -53,9 +55,9 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
53
55
|
|
54
56
|
def test_create_from_view
|
55
57
|
view = {
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
'_type' => 'Model',
|
59
|
+
'name' => 'p',
|
60
|
+
'child' => { '_type' => 'Child', 'name' => 'l' },
|
59
61
|
}
|
60
62
|
|
61
63
|
pv = ModelView.deserialize_from_view(view)
|
@@ -64,10 +66,10 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
64
66
|
assert(!p.changed?)
|
65
67
|
assert(!p.new_record?)
|
66
68
|
|
67
|
-
assert_equal(
|
69
|
+
assert_equal('p', p.name)
|
68
70
|
|
69
71
|
assert(p.child.present?)
|
70
|
-
assert_equal(
|
72
|
+
assert_equal('l', p.child.name)
|
71
73
|
end
|
72
74
|
|
73
75
|
def test_create_belongs_to_nil
|
@@ -86,7 +88,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
86
88
|
def test_belongs_to_create
|
87
89
|
@model1.update(child: nil)
|
88
90
|
|
89
|
-
alter_by_view!(ModelView, @model1) do |view,
|
91
|
+
alter_by_view!(ModelView, @model1) do |view, _refs|
|
90
92
|
view['child'] = { '_type' => 'Child', 'name' => 'cheese' }
|
91
93
|
end
|
92
94
|
|
@@ -96,7 +98,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
96
98
|
def test_belongs_to_replace
|
97
99
|
old_child = @model1.child
|
98
100
|
|
99
|
-
alter_by_view!(ModelView, @model1) do |view,
|
101
|
+
alter_by_view!(ModelView, @model1) do |view, _refs|
|
100
102
|
view['child'] = { '_type' => 'Child', 'name' => 'cheese' }
|
101
103
|
end
|
102
104
|
|
@@ -108,7 +110,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
108
110
|
old_p1_child = @model1.child
|
109
111
|
old_p2_child = @model2.child
|
110
112
|
|
111
|
-
set_by_view!(ModelView, [@model1, @model2]) do |(p1, p2),
|
113
|
+
set_by_view!(ModelView, [@model1, @model2]) do |(p1, p2), _refs|
|
112
114
|
p1['child'] = nil
|
113
115
|
p2['child'] = update_hash_for(ChildView, old_p1_child)
|
114
116
|
end
|
@@ -122,7 +124,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
122
124
|
old_p1_child = @model1.child
|
123
125
|
old_p2_child = @model2.child
|
124
126
|
|
125
|
-
alter_by_view!(ModelView, [@model1, @model2]) do |(p1, p2),
|
127
|
+
alter_by_view!(ModelView, [@model1, @model2]) do |(p1, p2), _refs|
|
126
128
|
p1['child'] = update_hash_for(ChildView, old_p2_child)
|
127
129
|
p2['child'] = update_hash_for(ChildView, old_p1_child)
|
128
130
|
end
|
@@ -136,22 +138,22 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
136
138
|
d_context = ModelView.new_deserialize_context
|
137
139
|
|
138
140
|
target_child = Child.create
|
139
|
-
from_model
|
140
|
-
to_model
|
141
|
+
from_model = Model.create(name: 'from', child: target_child)
|
142
|
+
to_model = Model.create(name: 'p3')
|
141
143
|
|
142
144
|
alter_by_view!(
|
143
145
|
ModelView, [from_model, to_model],
|
144
146
|
deserialize_context: d_context
|
145
|
-
) do |(from, to),
|
147
|
+
) do |(from, to), _refs|
|
146
148
|
from['child'] = nil
|
147
149
|
to['child'] = update_hash_for(ChildView, target_child)
|
148
150
|
end
|
149
151
|
|
150
152
|
assert_equal(target_child, to_model.child, 'target child moved')
|
151
153
|
assert_equal([ViewModel::Reference.new(ModelView, from_model.id),
|
152
|
-
ViewModel::Reference.new(ModelView, to_model.id)],
|
154
|
+
ViewModel::Reference.new(ModelView, to_model.id),],
|
153
155
|
d_context.valid_edit_refs,
|
154
|
-
|
156
|
+
'only models are checked for change; child was not')
|
155
157
|
end
|
156
158
|
|
157
159
|
def test_implicit_release_invalid_belongs_to
|
@@ -174,11 +176,11 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
174
176
|
t.integer :deleted_child_id
|
175
177
|
t.integer :ignored_child_id
|
176
178
|
end,
|
177
|
-
model: ->(
|
179
|
+
model: ->(_m) do
|
178
180
|
belongs_to :deleted_child, class_name: Child.name, dependent: :delete
|
179
181
|
belongs_to :ignored_child, class_name: Child.name
|
180
182
|
end,
|
181
|
-
viewmodel: ->(
|
183
|
+
viewmodel: ->(_v) do
|
182
184
|
associations :deleted_child, :ignored_child
|
183
185
|
end)
|
184
186
|
end
|
@@ -198,7 +200,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
198
200
|
end
|
199
201
|
|
200
202
|
def test_no_gc_dependent_ignore
|
201
|
-
model = model_class.create(ignored_child: Child.new(name:
|
203
|
+
model = model_class.create(ignored_child: Child.new(name: 'one'))
|
202
204
|
old_child = model.ignored_child
|
203
205
|
|
204
206
|
alter_by_view!(ModelView, model) do |ov, _refs|
|
@@ -232,7 +234,7 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
232
234
|
end
|
233
235
|
|
234
236
|
def test_renamed_roundtrip
|
235
|
-
alter_by_view!(ModelView, @model) do |view,
|
237
|
+
alter_by_view!(ModelView, @model) do |view, _refs|
|
236
238
|
assert_equal({ 'id' => @model.child.id,
|
237
239
|
'_type' => 'Child',
|
238
240
|
'_version' => 1,
|
@@ -284,7 +286,6 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
284
286
|
end
|
285
287
|
end
|
286
288
|
|
287
|
-
|
288
289
|
# Do we support replacing a node in the tree and remodeling its children
|
289
290
|
# back to it? In theory we want to, but currently we don't: the child node
|
290
291
|
# is unresolvable.
|
@@ -299,8 +300,8 @@ class ViewModel::ActiveRecord::BelongsToTest < ActiveSupport::TestCase
|
|
299
300
|
def test_move
|
300
301
|
model = Aye.create(bee: Bee.new(cee: Cee.new))
|
301
302
|
assert_raises(ViewModel::DeserializationError::ParentNotFound) do
|
302
|
-
alter_by_view!(AyeView, model) do |view,
|
303
|
-
view['bee'].delete(
|
303
|
+
alter_by_view!(AyeView, model) do |view, _refs|
|
304
|
+
view['bee'].delete('id')
|
304
305
|
end
|
305
306
|
end
|
306
307
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/unit'
|
5
|
+
require 'minitest/hooks'
|
6
6
|
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
7
|
+
require_relative '../../../helpers/arvm_test_models'
|
8
|
+
require_relative '../../../helpers/arvm_test_utilities'
|
9
|
+
require_relative '../../../helpers/viewmodel_spec_helpers'
|
10
10
|
|
11
|
-
require
|
12
|
-
require
|
11
|
+
require 'view_model'
|
12
|
+
require 'view_model/active_record'
|
13
13
|
|
14
14
|
# IknowCache uses Rails.cache: create a dummy cache.
|
15
15
|
|
@@ -34,7 +34,7 @@ class ViewModel::ActiveRecord
|
|
34
34
|
# Defines a cacheable parent Model with a owned Child and a cachable shared Shared.
|
35
35
|
module CacheableParentAndChildren
|
36
36
|
extend ActiveSupport::Concern
|
37
|
-
include ViewModelSpecHelpers::
|
37
|
+
include ViewModelSpecHelpers::ParentAndBelongsToChildWithMigration
|
38
38
|
|
39
39
|
def model_attributes
|
40
40
|
super.merge(
|
@@ -43,7 +43,7 @@ class ViewModel::ActiveRecord
|
|
43
43
|
viewmodel: ->(_) {
|
44
44
|
association :shared
|
45
45
|
cacheable!
|
46
|
-
}
|
46
|
+
},
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
@@ -64,8 +64,18 @@ class ViewModel::ActiveRecord
|
|
64
64
|
|
65
65
|
define_viewmodel do
|
66
66
|
root!
|
67
|
+
self.schema_version = 2
|
67
68
|
attributes :name
|
68
69
|
cacheable!(cache_group: shared_cache_group)
|
70
|
+
migrates from: 1, to: 2 do
|
71
|
+
up do |view, _references|
|
72
|
+
view['name'] = view.delete('old_name')
|
73
|
+
end
|
74
|
+
|
75
|
+
down do |view, _references|
|
76
|
+
view['old_name'] = view.delete('name')
|
77
|
+
end
|
78
|
+
end
|
69
79
|
end
|
70
80
|
end
|
71
81
|
end
|
@@ -81,8 +91,8 @@ class ViewModel::ActiveRecord
|
|
81
91
|
end
|
82
92
|
|
83
93
|
included do
|
84
|
-
let(:shared) { shared_model_class.create!(name:
|
85
|
-
let(:root) { model_class.create!(name:
|
94
|
+
let(:shared) { shared_model_class.create!(name: 'shared1') }
|
95
|
+
let(:root) { model_class.create!(name: 'root1', child: Child.new(name: 'owned1'), shared: shared) }
|
86
96
|
let(:root_view) { viewmodel_class.new(root) }
|
87
97
|
end
|
88
98
|
end
|
@@ -91,10 +101,17 @@ class ViewModel::ActiveRecord
|
|
91
101
|
DUMMY_RAILS_CACHE.clear
|
92
102
|
end
|
93
103
|
|
104
|
+
# Request serializations to be migrated to the specified versions
|
105
|
+
let(:migration_versions) { {} }
|
106
|
+
|
94
107
|
# Extract the iKnowCaches to verify their contents
|
95
108
|
def read_cache(viewmodel_class, id)
|
96
109
|
vm_cache = viewmodel_class.viewmodel_cache
|
97
|
-
vm_cache.
|
110
|
+
cache_migration_version = vm_cache.migrated_cache_version(migration_versions)
|
111
|
+
|
112
|
+
key = vm_cache.key_for(id, cache_migration_version)
|
113
|
+
iknow_cache = vm_cache.cache_for(cache_migration_version)
|
114
|
+
iknow_cache.read(key)
|
98
115
|
end
|
99
116
|
|
100
117
|
def serialize_from_database
|
@@ -102,6 +119,12 @@ class ViewModel::ActiveRecord
|
|
102
119
|
context = viewmodel_class.new_serialize_context
|
103
120
|
data = ViewModel.serialize_to_hash([view], serialize_context: context)
|
104
121
|
refs = context.serialize_references_to_hash
|
122
|
+
|
123
|
+
if migration_versions.present?
|
124
|
+
migrator = ViewModel::DownMigrator.new(migration_versions)
|
125
|
+
migrator.migrate!([data, refs], references: refs)
|
126
|
+
end
|
127
|
+
|
105
128
|
[data, refs]
|
106
129
|
end
|
107
130
|
|
@@ -113,7 +136,7 @@ class ViewModel::ActiveRecord
|
|
113
136
|
end
|
114
137
|
|
115
138
|
def fetch_with_cache
|
116
|
-
viewmodel_class.viewmodel_cache.fetch([root.id])
|
139
|
+
viewmodel_class.viewmodel_cache.fetch([root.id], migration_versions: migration_versions)
|
117
140
|
end
|
118
141
|
|
119
142
|
def serialize_with_cache
|
@@ -160,13 +183,14 @@ class ViewModel::ActiveRecord
|
|
160
183
|
|
161
184
|
# The cached reference must correspond to the returned data.
|
162
185
|
parsed_data = JSON.parse(ref_data)
|
163
|
-
value(parsed_data[
|
164
|
-
value(parsed_data[
|
186
|
+
value(parsed_data['id']).must_equal(id)
|
187
|
+
value(parsed_data['_type']).must_equal(view_name)
|
165
188
|
|
166
189
|
# When the cached reference is to independently cached data
|
167
190
|
# (SharedView in this test), make sure that data is correctly
|
168
191
|
# cached.
|
169
|
-
next unless view_name ==
|
192
|
+
next unless view_name == 'Shared'
|
193
|
+
|
170
194
|
value(id).must_equal(shared.id)
|
171
195
|
cached_shared = read_cache(shared_viewmodel_class, id)
|
172
196
|
value(cached_shared).must_be(:present?)
|
@@ -179,7 +203,20 @@ class ViewModel::ActiveRecord
|
|
179
203
|
|
180
204
|
describe 'with owned and shared children' do
|
181
205
|
include CacheableParentAndChildren
|
182
|
-
|
206
|
+
|
207
|
+
describe 'without migrations' do
|
208
|
+
include BehavesLikeACache
|
209
|
+
end
|
210
|
+
|
211
|
+
describe 'with migrations' do
|
212
|
+
let(:migration_versions) { { viewmodel_class => 1, child_viewmodel_class => 2 } }
|
213
|
+
include BehavesLikeACache
|
214
|
+
end
|
215
|
+
|
216
|
+
describe 'with shared migrations' do
|
217
|
+
let(:migration_versions) { { shared_viewmodel_class => 1 } }
|
218
|
+
include BehavesLikeACache
|
219
|
+
end
|
183
220
|
|
184
221
|
describe 'with a record in the cache' do
|
185
222
|
# Fetch the root record to ensure it's in the cache
|
@@ -188,8 +225,8 @@ class ViewModel::ActiveRecord
|
|
188
225
|
end
|
189
226
|
|
190
227
|
def change_in_database
|
191
|
-
root.update_attribute(:name,
|
192
|
-
shared.update_attribute(:name,
|
228
|
+
root.update_attribute(:name, 'CHANGEDROOT')
|
229
|
+
shared.update_attribute(:name, 'CHANGEDSHARED')
|
193
230
|
end
|
194
231
|
|
195
232
|
it 'resolves from the cache' do
|
@@ -207,7 +244,7 @@ class ViewModel::ActiveRecord
|
|
207
244
|
viewmodel_class.viewmodel_cache.clear
|
208
245
|
|
209
246
|
cache_data, cache_refs = serialize_with_cache
|
210
|
-
value(cache_data[0][
|
247
|
+
value(cache_data[0]['name']).must_equal('CHANGEDROOT') # Root view invalidated
|
211
248
|
value(cache_refs).must_equal(before_refs) # Shared view not invalidated
|
212
249
|
end
|
213
250
|
|
@@ -265,7 +302,7 @@ class ViewModel::ActiveRecord
|
|
265
302
|
viewmodel_class.viewmodel_cache.delete(root.id)
|
266
303
|
|
267
304
|
cache_data, cache_refs = serialize_with_cache
|
268
|
-
value(cache_data[0][
|
305
|
+
value(cache_data[0]['name']).must_equal('CHANGEDROOT')
|
269
306
|
value(cache_refs).must_equal(before_refs)
|
270
307
|
end
|
271
308
|
|
@@ -275,8 +312,8 @@ class ViewModel::ActiveRecord
|
|
275
312
|
|
276
313
|
# Shared view invalidated, but root view not
|
277
314
|
cache_data, cache_hrefs = serialize_with_cache
|
278
|
-
value(cache_data[0][
|
279
|
-
value(cache_hrefs.values[0][
|
315
|
+
value(cache_data[0]['name']).must_equal('root1')
|
316
|
+
value(cache_hrefs.values[0]['name']).must_equal('CHANGEDSHARED')
|
280
317
|
end
|
281
318
|
|
282
319
|
it 'can clear a cache via its external cache group' do
|
@@ -285,12 +322,12 @@ class ViewModel::ActiveRecord
|
|
285
322
|
|
286
323
|
# Shared view invalidated, but root view not
|
287
324
|
cache_data, cache_hrefs = serialize_with_cache
|
288
|
-
value(cache_data[0][
|
289
|
-
value(cache_hrefs.values[0][
|
325
|
+
value(cache_data[0]['name']).must_equal('root1')
|
326
|
+
value(cache_hrefs.values[0]['name']).must_equal('CHANGEDSHARED')
|
290
327
|
end
|
291
328
|
|
292
329
|
describe 'and a record not in the cache' do
|
293
|
-
let(:root2) { model_class.create!(name:
|
330
|
+
let(:root2) { model_class.create!(name: 'root2', child: Child.new(name: 'owned2'), shared: shared) }
|
294
331
|
|
295
332
|
def serialize_from_database
|
296
333
|
views = model_class.find(root.id, root2.id).map { |r| viewmodel_class.new(r) }
|
@@ -318,21 +355,21 @@ class ViewModel::ActiveRecord
|
|
318
355
|
change_in_database
|
319
356
|
|
320
357
|
cache_data, cache_refs = serialize_with_cache
|
321
|
-
value(cache_data[0][
|
322
|
-
value(cache_data[1][
|
358
|
+
value(cache_data[0]['name']).must_equal('root1')
|
359
|
+
value(cache_data[1]['name']).must_equal('root2')
|
323
360
|
value(cache_refs).must_equal(refs)
|
324
361
|
end
|
325
362
|
end
|
326
363
|
end
|
327
364
|
end
|
328
365
|
|
329
|
-
describe
|
366
|
+
describe 'with a non-cacheable shared child' do
|
330
367
|
include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
|
331
368
|
def model_attributes
|
332
369
|
super.merge(viewmodel: ->(_) { cacheable! })
|
333
370
|
end
|
334
371
|
|
335
|
-
let(:root) { model_class.create!(name:
|
372
|
+
let(:root) { model_class.create!(name: 'root1', child: Child.new(name: 'owned1')) }
|
336
373
|
let(:root_view) { viewmodel_class.new(root) }
|
337
374
|
|
338
375
|
include BehavesLikeACache
|