iknow_view_models 3.1.6 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 +13 -12
- data/lib/view_model/active_record/association_data.rb +3 -2
- 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 +2 -2
- 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 +1 -1
- 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 +92 -97
- data/test/unit/view_model/traversal_context_test.rb +4 -5
- data/test/unit/view_model_test.rb +18 -16
- metadata +36 -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
|