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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +6 -6
  3. data/.rubocop.yml +18 -0
  4. data/Appraisals +6 -6
  5. data/Gemfile +6 -2
  6. data/Rakefile +5 -5
  7. data/gemfiles/rails_5_2.gemfile +5 -5
  8. data/gemfiles/rails_6_0.gemfile +9 -0
  9. data/iknow_view_models.gemspec +40 -38
  10. data/lib/iknow_view_models.rb +9 -7
  11. data/lib/iknow_view_models/version.rb +1 -1
  12. data/lib/view_model.rb +31 -17
  13. data/lib/view_model/access_control.rb +5 -2
  14. data/lib/view_model/access_control/composed.rb +10 -9
  15. data/lib/view_model/access_control/open.rb +2 -0
  16. data/lib/view_model/access_control/read_only.rb +2 -0
  17. data/lib/view_model/access_control/tree.rb +11 -6
  18. data/lib/view_model/access_control_error.rb +4 -1
  19. data/lib/view_model/active_record.rb +17 -15
  20. data/lib/view_model/active_record/association_data.rb +2 -1
  21. data/lib/view_model/active_record/association_manipulation.rb +6 -4
  22. data/lib/view_model/active_record/cache.rb +114 -34
  23. data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
  24. data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
  25. data/lib/view_model/active_record/controller.rb +68 -1
  26. data/lib/view_model/active_record/controller_base.rb +4 -1
  27. data/lib/view_model/active_record/nested_controller_base.rb +1 -0
  28. data/lib/view_model/active_record/update_context.rb +8 -6
  29. data/lib/view_model/active_record/update_data.rb +32 -30
  30. data/lib/view_model/active_record/update_operation.rb +17 -13
  31. data/lib/view_model/active_record/visitor.rb +0 -1
  32. data/lib/view_model/after_transaction_runner.rb +0 -1
  33. data/lib/view_model/callbacks.rb +3 -1
  34. data/lib/view_model/controller.rb +13 -3
  35. data/lib/view_model/deserialization_error.rb +15 -12
  36. data/lib/view_model/error.rb +12 -10
  37. data/lib/view_model/error_view.rb +3 -1
  38. data/lib/view_model/migratable_view.rb +78 -0
  39. data/lib/view_model/migration.rb +48 -0
  40. data/lib/view_model/migration/no_path_error.rb +26 -0
  41. data/lib/view_model/migration/one_way_error.rb +24 -0
  42. data/lib/view_model/migration/unspecified_version_error.rb +24 -0
  43. data/lib/view_model/migrator.rb +108 -0
  44. data/lib/view_model/record.rb +15 -14
  45. data/lib/view_model/reference.rb +3 -1
  46. data/lib/view_model/references.rb +8 -5
  47. data/lib/view_model/registry.rb +14 -2
  48. data/lib/view_model/schemas.rb +9 -4
  49. data/lib/view_model/serialization_error.rb +4 -1
  50. data/lib/view_model/serialize_context.rb +4 -4
  51. data/lib/view_model/test_helpers.rb +8 -3
  52. data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
  53. data/lib/view_model/traversal_context.rb +2 -1
  54. data/nix/dependencies.nix +5 -0
  55. data/nix/gem/generate.rb +2 -1
  56. data/shell.nix +8 -3
  57. data/test/.rubocop.yml +14 -0
  58. data/test/helpers/arvm_test_models.rb +12 -9
  59. data/test/helpers/arvm_test_utilities.rb +5 -3
  60. data/test/helpers/controller_test_helpers.rb +55 -32
  61. data/test/helpers/match_enumerator.rb +1 -0
  62. data/test/helpers/query_logging.rb +2 -1
  63. data/test/helpers/test_access_control.rb +5 -3
  64. data/test/helpers/viewmodel_spec_helpers.rb +88 -22
  65. data/test/unit/view_model/access_control_test.rb +144 -144
  66. data/test/unit/view_model/active_record/alias_test.rb +15 -13
  67. data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
  68. data/test/unit/view_model/active_record/cache_test.rb +68 -31
  69. data/test/unit/view_model/active_record/cloner_test.rb +67 -63
  70. data/test/unit/view_model/active_record/controller_test.rb +113 -65
  71. data/test/unit/view_model/active_record/counter_test.rb +10 -9
  72. data/test/unit/view_model/active_record/customization_test.rb +59 -58
  73. data/test/unit/view_model/active_record/has_many_test.rb +112 -111
  74. data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
  75. data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
  76. data/test/unit/view_model/active_record/has_one_test.rb +37 -36
  77. data/test/unit/view_model/active_record/migration_test.rb +161 -0
  78. data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
  79. data/test/unit/view_model/active_record/poly_test.rb +44 -45
  80. data/test/unit/view_model/active_record/shared_test.rb +30 -28
  81. data/test/unit/view_model/active_record/version_test.rb +9 -7
  82. data/test/unit/view_model/active_record_test.rb +72 -72
  83. data/test/unit/view_model/callbacks_test.rb +19 -15
  84. data/test/unit/view_model/controller_test.rb +4 -2
  85. data/test/unit/view_model/record_test.rb +158 -145
  86. data/test/unit/view_model/registry_test.rb +38 -0
  87. data/test/unit/view_model/traversal_context_test.rb +4 -5
  88. data/test/unit/view_model_test.rb +18 -16
  89. metadata +38 -12
  90. data/.travis.yml +0 -31
  91. data/appveyor.yml +0 -22
  92. data/gemfiles/rails_6_0_beta.gemfile +0 -9
@@ -1,10 +1,12 @@
1
- require_relative "../../../helpers/arvm_test_utilities.rb"
2
- require_relative "../../../helpers/arvm_test_models.rb"
3
- require_relative "../../../helpers/viewmodel_spec_helpers.rb"
1
+ # frozen_string_literal: true
4
2
 
5
- require "minitest/autorun"
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 "view_model/active_record"
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: ->(v) do
18
- add_view_alias "ChildA"
19
- add_view_alias "ChildB"
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 "permits association types to be aliased" do
25
- %w(Child ChildA ChildB).each do |view_alias|
26
+ it 'permits association types to be aliased' do
27
+ %w[Child ChildA ChildB].each do |view_alias|
26
28
  view = {
27
- "_type" => viewmodel_class.view_name,
28
- "child" => { "_type" => view_alias },
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
- require_relative "../../../helpers/arvm_test_utilities.rb"
2
- require_relative "../../../helpers/arvm_test_models.rb"
3
- require_relative '../../../helpers/viewmodel_spec_helpers.rb'
1
+ # frozen_string_literal: true
4
2
 
5
- require "minitest/autorun"
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 "view_model/active_record"
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: "p1",
19
- child: child_model_class.new(name: "p1l"))
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: "p2",
23
- child: child_model_class.new(name: "p2l"))
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({ "_type" => "Model",
34
- "_version" => 1,
35
- "id" => @model1.id,
36
- "name" => @model1.name,
37
- "child" => { "_type" => "Child",
38
- "_version" => 1,
39
- "id" => @model1.child.id,
40
- "name" => @model1.child.name },
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
- "_type" => "Model",
57
- "name" => "p",
58
- "child" => { "_type" => "Child", "name" => "l" },
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("p", p.name)
69
+ assert_equal('p', p.name)
68
70
 
69
71
  assert(p.child.present?)
70
- assert_equal("l", p.child.name)
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, refs|
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, refs|
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), refs|
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), refs|
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 = Model.create(name: 'from', child: target_child)
140
- to_model = Model.create(name: 'p3')
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), refs|
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
- "only models are checked for change; child was not")
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: ->(m) do
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: ->(v) do
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: "one"))
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, refs|
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, refs|
303
- view['bee'].delete("id")
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 "minitest/autorun"
4
- require "minitest/unit"
5
- require "minitest/hooks"
3
+ require 'minitest/autorun'
4
+ require 'minitest/unit'
5
+ require 'minitest/hooks'
6
6
 
7
- require_relative "../../../helpers/arvm_test_models.rb"
8
- require_relative "../../../helpers/arvm_test_utilities.rb"
9
- require_relative "../../../helpers/viewmodel_spec_helpers.rb"
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 "view_model"
12
- require "view_model/active_record"
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::ParentAndBelongsToChild
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: "shared1") }
85
- let(:root) { model_class.create!(name: "root1", child: Child.new(name: "owned1"), shared: shared) }
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.send(:cache).read(vm_cache.key_for(id))
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["id"]).must_equal(id)
164
- value(parsed_data["_type"]).must_equal(view_name)
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 == "Shared"
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
- include BehavesLikeACache
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, "CHANGEDROOT")
192
- shared.update_attribute(:name, "CHANGEDSHARED")
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]["name"]).must_equal("CHANGEDROOT") # Root view invalidated
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]["name"]).must_equal("CHANGEDROOT")
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]["name"]).must_equal("root1")
279
- value(cache_hrefs.values[0]["name"]).must_equal("CHANGEDSHARED")
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]["name"]).must_equal("root1")
289
- value(cache_hrefs.values[0]["name"]).must_equal("CHANGEDSHARED")
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: "root2", child: Child.new(name: "owned2"), shared: shared) }
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]["name"]).must_equal("root1")
322
- value(cache_data[1]["name"]).must_equal("root2")
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 "with a non-cacheable shared child" do
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: "root1", child: Child.new(name: "owned1")) }
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