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.
Files changed (91) 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 +13 -12
  20. data/lib/view_model/active_record/association_data.rb +3 -2
  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 +2 -2
  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 +1 -1
  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 +92 -97
  86. data/test/unit/view_model/traversal_context_test.rb +4 -5
  87. data/test/unit/view_model_test.rb +18 -16
  88. metadata +36 -12
  89. data/.travis.yml +0 -31
  90. data/appveyor.yml +0 -22
  91. 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