iknow_view_models 3.2.5 → 3.2.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 054e6799ccf140f543987391ad729cb084aeb026c721a301b026d63dbe0239e2
4
- data.tar.gz: d5f49f2865e261862fdf6b91e04095418be559dc47a0417a0613c0efeda41a12
3
+ metadata.gz: 280c8d764916ec30bb500e2f0e982131416d27ea51a3a25d1cd7e3908bb4ad5b
4
+ data.tar.gz: 50d202b87cde141ac58ad82a5de6b73332f9b60a71c23fbbd378ba6c1def8184
5
5
  SHA512:
6
- metadata.gz: 8ba6fcabc99bc718d1814167b425a2e5cce46d8dc882c741ced4a3e016bf038f487eed71cb7d568ef2d1cee83236ceb08680de6d705e80faa27dbe22d660a539
7
- data.tar.gz: 8384c93cf1427bd45cd145df76cbe76b0df97f34fd63b89a8da7df3086e9c5548c82e2123f1756d56a03eb51255c3a8a17fdb2e640c0a39d1dffaa0e78589302
6
+ metadata.gz: 51333e3292118de4b71e8869ea4843be804ad2d24ce0c7296918c3f09b0df93740561afeb466b4a8874a1b5b667922b664745e994151b8fe47ce458bb087d14d
7
+ data.tar.gz: 999d1feb717d4ef5ce11b400abf67772c5b70fd7c91cf3e328f14e5ff66a373b7c98aa5f701cb436cf4bf7df448bc553fca96131de570cead59734e8131c4788
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IknowViewModels
4
- VERSION = '3.2.5'
4
+ VERSION = '3.2.10'
5
5
  end
@@ -243,9 +243,17 @@ class ViewModel
243
243
  schema_version == self.schema_version
244
244
  end
245
245
 
246
+ def schema_versions(viewmodels)
247
+ viewmodels.each_with_object({}) do |view, h|
248
+ h[view.view_name] = view.schema_version
249
+ end
250
+ end
251
+
246
252
  def schema_hash(schema_versions)
247
253
  version_string = schema_versions.to_a.sort.join(',')
248
- Base64.urlsafe_encode64(Digest::MD5.digest(version_string))
254
+ # We want a short hash value, as this will be used in cache keys
255
+ hash = Digest::SHA256.digest(version_string).byteslice(0, 16)
256
+ Base64.urlsafe_encode64(hash, padding: false)
249
257
  end
250
258
 
251
259
  def preload_for_serialization(viewmodels, serialize_context: new_serialize_context, include_referenced: true, lock: nil)
@@ -243,11 +243,10 @@ class ViewModel::ActiveRecord < ViewModel::Record
243
243
  end
244
244
 
245
245
  def deep_schema_version(include_referenced: true, include_external: true)
246
- (@deep_schema_version ||= {})[include_referenced] ||=
246
+ (@deep_schema_version ||= {})[[include_referenced, include_external]] ||=
247
247
  begin
248
- dependent_viewmodels(include_referenced: include_referenced, include_external: include_external).each_with_object({}) do |view, h|
249
- h[view.view_name] = view.schema_version
250
- end.freeze
248
+ vms = dependent_viewmodels(include_referenced: include_referenced, include_external: include_external)
249
+ ViewModel.schema_versions(vms).freeze
251
250
  end
252
251
  end
253
252
 
@@ -52,6 +52,9 @@ module ViewModel::MigratableView
52
52
 
53
53
  graph = RGL::DirectedAdjacencyGraph.new
54
54
 
55
+ # Add a vertex for the current version, in case no edges reach it
56
+ graph.add_vertex(self.schema_version)
57
+
55
58
  # Add edges backwards, as we care about paths from the latest version
56
59
  @migration_classes.each_key do |from, to|
57
60
  graph.add_edge(to, from)
@@ -60,7 +63,7 @@ module ViewModel::MigratableView
60
63
  paths = graph.dijkstra_shortest_paths(Hash.new { 1 }, self.schema_version)
61
64
 
62
65
  paths.each do |target_version, path|
63
- next if path.length == 1
66
+ next if path.nil? || path.length == 1
64
67
 
65
68
  # Store the path forwards rather than backwards
66
69
  path_migration_classes = path.reverse.each_cons(2).map do |from, to|
@@ -4,6 +4,7 @@ class ViewModel::Migration::NoPathError < ViewModel::AbstractError
4
4
  attr_reader :vm_name, :from, :to
5
5
 
6
6
  status 400
7
+ code 'Migration.NoPathError'
7
8
 
8
9
  def initialize(viewmodel, from, to)
9
10
  @vm_name = viewmodel.view_name
@@ -4,6 +4,7 @@ class ViewModel::Migration::OneWayError < ViewModel::AbstractError
4
4
  attr_reader :vm_name, :direction
5
5
 
6
6
  status 400
7
+ code 'Migration.OneWayError'
7
8
 
8
9
  def initialize(vm_name, direction)
9
10
  @vm_name = vm_name
@@ -4,6 +4,7 @@ class ViewModel::Migration::UnspecifiedVersionError < ViewModel::AbstractError
4
4
  attr_reader :vm_name, :version
5
5
 
6
6
  status 400
7
+ code 'Migration.UnspecifiedVersionError'
7
8
 
8
9
  def initialize(vm_name, version)
9
10
  @vm_name = vm_name
@@ -12,14 +12,21 @@ class ViewModel::ActiveRecord::Migration < ActiveSupport::TestCase
12
12
  include ARVMTestUtilities
13
13
  extend Minitest::Spec::DSL
14
14
 
15
- include ViewModelSpecHelpers::ParentAndBelongsToChildWithMigration
16
-
17
15
  def new_model
18
16
  model_class.new(name: 'm1', child: child_model_class.new(name: 'c1'))
19
17
  end
20
18
 
21
19
  let(:viewmodel) { create_viewmodel! }
22
20
 
21
+ let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 2 } }
22
+
23
+ let(:down_migrator) { ViewModel::DownMigrator.new(migration_versions) }
24
+ let(:up_migrator) { ViewModel::UpMigrator.new(migration_versions) }
25
+
26
+ def migrate!
27
+ migrator.migrate!(subject, references: {})
28
+ end
29
+
23
30
  let(:current_serialization) { ViewModel.serialize_to_hash(viewmodel) }
24
31
 
25
32
  let(:v2_serialization) do
@@ -39,120 +46,144 @@ class ViewModel::ActiveRecord::Migration < ActiveSupport::TestCase
39
46
  }
40
47
  end
41
48
 
42
- let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 2 } }
43
-
44
- let(:down_migrator) { ViewModel::DownMigrator.new(migration_versions) }
45
- let(:up_migrator) { ViewModel::UpMigrator.new(migration_versions) }
49
+ describe 'with defined migrations' do
50
+ include ViewModelSpecHelpers::ParentAndBelongsToChildWithMigration
46
51
 
47
- def migrate!
48
- migrator.migrate!(subject, references: {})
49
- end
52
+ describe 'downwards' do
53
+ let(:migrator) { down_migrator }
54
+ let(:subject) { current_serialization.deep_dup }
50
55
 
51
- describe 'downwards' do
52
- let(:migrator) { down_migrator }
53
- let(:subject) { current_serialization.deep_dup }
54
-
55
- let(:expected_result) do
56
- v2_serialization.deep_merge(
57
- {
58
- ViewModel::MIGRATED_ATTRIBUTE => true,
59
- 'old_field' => -1,
60
- 'child' => {
56
+ let(:expected_result) do
57
+ v2_serialization.deep_merge(
58
+ {
61
59
  ViewModel::MIGRATED_ATTRIBUTE => true,
62
- 'former_field' => 'reconstructed',
60
+ 'old_field' => -1,
61
+ 'child' => {
62
+ ViewModel::MIGRATED_ATTRIBUTE => true,
63
+ 'former_field' => 'reconstructed',
64
+ },
63
65
  },
64
- },
65
- )
66
- end
66
+ )
67
+ end
67
68
 
68
- it 'migrates' do
69
- migrate!
69
+ it 'migrates' do
70
+ migrate!
70
71
 
71
- assert_equal(expected_result, subject)
72
- end
72
+ assert_equal(expected_result, subject)
73
+ end
73
74
 
74
- describe 'to an unreachable version' do
75
- let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 1 } }
75
+ describe 'to an unreachable version' do
76
+ let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 1 } }
76
77
 
77
- it 'raises' do
78
- assert_raises(ViewModel::Migration::NoPathError) do
79
- migrate!
78
+ it 'raises' do
79
+ assert_raises(ViewModel::Migration::NoPathError) do
80
+ migrate!
81
+ end
80
82
  end
81
83
  end
82
84
  end
83
- end
84
85
 
85
- describe 'upwards' do
86
- let(:migrator) { up_migrator }
87
- let(:subject) { v2_serialization.deep_dup }
86
+ describe 'upwards' do
87
+ let(:migrator) { up_migrator }
88
+ let(:subject) { v2_serialization.deep_dup }
88
89
 
89
- let(:expected_result) do
90
- current_serialization.deep_merge(
91
- ViewModel::MIGRATED_ATTRIBUTE => true,
92
- 'new_field' => 3,
93
- 'child' => {
90
+ let(:expected_result) do
91
+ current_serialization.deep_merge(
94
92
  ViewModel::MIGRATED_ATTRIBUTE => true,
95
- },
96
- )
97
- end
98
-
99
- it 'migrates' do
100
- migrate!
101
-
102
- assert_equal(expected_result, subject)
103
- end
104
-
105
- describe 'with version unspecified' do
106
- let(:subject) do
107
- v2_serialization
108
- .except(ViewModel::VERSION_ATTRIBUTE)
93
+ 'new_field' => 3,
94
+ 'child' => {
95
+ ViewModel::MIGRATED_ATTRIBUTE => true,
96
+ },
97
+ )
109
98
  end
110
99
 
111
- it 'treats it as the requested version' do
100
+ it 'migrates' do
112
101
  migrate!
102
+
113
103
  assert_equal(expected_result, subject)
114
104
  end
115
- end
116
105
 
117
- describe 'with a version not in the specification' do
118
- let(:subject) do
119
- v2_serialization
120
- .except('old_field')
121
- .deep_merge(ViewModel::VERSION_ATTRIBUTE => 3, 'mid_field' => 1)
122
- end
106
+ describe 'with version unspecified' do
107
+ let(:subject) do
108
+ v2_serialization
109
+ .except(ViewModel::VERSION_ATTRIBUTE)
110
+ end
123
111
 
124
- it 'rejects it' do
125
- assert_raises(ViewModel::Migration::UnspecifiedVersionError) do
112
+ it 'treats it as the requested version' do
126
113
  migrate!
114
+ assert_equal(expected_result, subject)
127
115
  end
128
116
  end
129
- end
130
117
 
131
- describe 'from an unreachable version' do
132
- let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 1 } }
118
+ describe 'with a version not in the specification' do
119
+ let(:subject) do
120
+ v2_serialization
121
+ .except('old_field')
122
+ .deep_merge(ViewModel::VERSION_ATTRIBUTE => 3, 'mid_field' => 1)
123
+ end
133
124
 
134
- let(:subject) do
135
- v2_serialization.deep_merge(
136
- 'child' => { ViewModel::VERSION_ATTRIBUTE => 1 },
137
- )
125
+ it 'rejects it' do
126
+ assert_raises(ViewModel::Migration::UnspecifiedVersionError) do
127
+ migrate!
128
+ end
129
+ end
138
130
  end
139
131
 
140
- it 'raises' do
141
- assert_raises(ViewModel::Migration::NoPathError) do
142
- migrate!
132
+ describe 'from an unreachable version' do
133
+ let(:migration_versions) { { viewmodel_class => 2, child_viewmodel_class => 1 } }
134
+
135
+ let(:subject) do
136
+ v2_serialization.deep_merge(
137
+ 'child' => { ViewModel::VERSION_ATTRIBUTE => 1 },
138
+ )
139
+ end
140
+
141
+ it 'raises' do
142
+ assert_raises(ViewModel::Migration::NoPathError) do
143
+ migrate!
144
+ end
145
+ end
146
+ end
147
+
148
+ describe 'in an undefined direction' do
149
+ let(:migration_versions) { { viewmodel_class => 1, child_viewmodel_class => 2 } }
150
+
151
+ let(:subject) do
152
+ v2_serialization.except('old_field').merge(ViewModel::VERSION_ATTRIBUTE => 1)
153
+ end
154
+
155
+ it 'raises' do
156
+ assert_raises(ViewModel::Migration::OneWayError) do
157
+ migrate!
158
+ end
143
159
  end
144
160
  end
145
161
  end
162
+ end
146
163
 
147
- describe 'in an undefined direction' do
148
- let(:migration_versions) { { viewmodel_class => 1, child_viewmodel_class => 2 } }
164
+ describe 'without migrations' do
165
+ describe 'to an unreachable version' do
166
+ include ViewModelSpecHelpers::ParentAndBelongsToChild
167
+
168
+ def model_attributes
169
+ super.merge(viewmodel: ->(_v) {
170
+ self.schema_version = 4
171
+ # Define an unreachable migration to ensure that the view
172
+ # attempts to realize paths.
173
+ migrates from: 1, to: 2 do
174
+ end
175
+ })
176
+ end
149
177
 
150
- let(:subject) do
151
- v2_serialization.except('old_field').merge(ViewModel::VERSION_ATTRIBUTE => 1)
178
+ def child_attributes
179
+ super.merge(viewmodel: ->(_v) { self.schema_version = 3 })
152
180
  end
153
181
 
154
- it 'raises' do
155
- assert_raises(ViewModel::Migration::OneWayError) do
182
+ let(:migrator) { down_migrator }
183
+ let(:subject) { current_serialization.deep_dup }
184
+
185
+ it 'raises no path error' do
186
+ assert_raises(ViewModel::Migration::NoPathError) do
156
187
  migrate!
157
188
  end
158
189
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iknow_view_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.5
4
+ version: 3.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - iKnow Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-20 00:00:00.000000000 Z
11
+ date: 2021-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord