iknow_view_models 2.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +115 -0
  3. data/.gitignore +36 -0
  4. data/.travis.yml +31 -0
  5. data/Appraisals +9 -0
  6. data/Gemfile +19 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +19 -0
  9. data/Rakefile +21 -0
  10. data/appveyor.yml +22 -0
  11. data/gemfiles/rails_5_2.gemfile +15 -0
  12. data/gemfiles/rails_6_0_beta.gemfile +15 -0
  13. data/iknow_view_models.gemspec +49 -0
  14. data/lib/iknow_view_models.rb +12 -0
  15. data/lib/iknow_view_models/railtie.rb +8 -0
  16. data/lib/iknow_view_models/version.rb +5 -0
  17. data/lib/view_model.rb +333 -0
  18. data/lib/view_model/access_control.rb +154 -0
  19. data/lib/view_model/access_control/composed.rb +216 -0
  20. data/lib/view_model/access_control/open.rb +13 -0
  21. data/lib/view_model/access_control/read_only.rb +13 -0
  22. data/lib/view_model/access_control/tree.rb +264 -0
  23. data/lib/view_model/access_control_error.rb +10 -0
  24. data/lib/view_model/active_record.rb +383 -0
  25. data/lib/view_model/active_record/association_data.rb +178 -0
  26. data/lib/view_model/active_record/association_manipulation.rb +389 -0
  27. data/lib/view_model/active_record/cache.rb +265 -0
  28. data/lib/view_model/active_record/cache/cacheable_view.rb +51 -0
  29. data/lib/view_model/active_record/cloner.rb +113 -0
  30. data/lib/view_model/active_record/collection_nested_controller.rb +100 -0
  31. data/lib/view_model/active_record/controller.rb +77 -0
  32. data/lib/view_model/active_record/controller_base.rb +185 -0
  33. data/lib/view_model/active_record/nested_controller_base.rb +93 -0
  34. data/lib/view_model/active_record/singular_nested_controller.rb +34 -0
  35. data/lib/view_model/active_record/update_context.rb +252 -0
  36. data/lib/view_model/active_record/update_data.rb +749 -0
  37. data/lib/view_model/active_record/update_operation.rb +810 -0
  38. data/lib/view_model/active_record/visitor.rb +77 -0
  39. data/lib/view_model/after_transaction_runner.rb +29 -0
  40. data/lib/view_model/callbacks.rb +219 -0
  41. data/lib/view_model/changes.rb +62 -0
  42. data/lib/view_model/config.rb +29 -0
  43. data/lib/view_model/controller.rb +142 -0
  44. data/lib/view_model/deserialization_error.rb +437 -0
  45. data/lib/view_model/deserialize_context.rb +16 -0
  46. data/lib/view_model/error.rb +191 -0
  47. data/lib/view_model/error_view.rb +35 -0
  48. data/lib/view_model/record.rb +367 -0
  49. data/lib/view_model/record/attribute_data.rb +48 -0
  50. data/lib/view_model/reference.rb +31 -0
  51. data/lib/view_model/references.rb +48 -0
  52. data/lib/view_model/registry.rb +73 -0
  53. data/lib/view_model/schemas.rb +45 -0
  54. data/lib/view_model/serialization_error.rb +10 -0
  55. data/lib/view_model/serialize_context.rb +118 -0
  56. data/lib/view_model/test_helpers.rb +103 -0
  57. data/lib/view_model/test_helpers/arvm_builder.rb +111 -0
  58. data/lib/view_model/traversal_context.rb +126 -0
  59. data/lib/view_model/utils.rb +24 -0
  60. data/lib/view_model/utils/collections.rb +49 -0
  61. data/test/helpers/arvm_test_models.rb +59 -0
  62. data/test/helpers/arvm_test_utilities.rb +187 -0
  63. data/test/helpers/callback_tracer.rb +27 -0
  64. data/test/helpers/controller_test_helpers.rb +270 -0
  65. data/test/helpers/match_enumerator.rb +58 -0
  66. data/test/helpers/query_logging.rb +71 -0
  67. data/test/helpers/test_access_control.rb +56 -0
  68. data/test/helpers/viewmodel_spec_helpers.rb +326 -0
  69. data/test/unit/view_model/access_control_test.rb +769 -0
  70. data/test/unit/view_model/active_record/alias_test.rb +35 -0
  71. data/test/unit/view_model/active_record/belongs_to_test.rb +376 -0
  72. data/test/unit/view_model/active_record/cache_test.rb +351 -0
  73. data/test/unit/view_model/active_record/cloner_test.rb +313 -0
  74. data/test/unit/view_model/active_record/controller_test.rb +561 -0
  75. data/test/unit/view_model/active_record/counter_test.rb +80 -0
  76. data/test/unit/view_model/active_record/customization_test.rb +388 -0
  77. data/test/unit/view_model/active_record/has_many_test.rb +957 -0
  78. data/test/unit/view_model/active_record/has_many_through_poly_test.rb +269 -0
  79. data/test/unit/view_model/active_record/has_many_through_test.rb +736 -0
  80. data/test/unit/view_model/active_record/has_one_test.rb +334 -0
  81. data/test/unit/view_model/active_record/namespacing_test.rb +75 -0
  82. data/test/unit/view_model/active_record/optional_attribute_view_test.rb +58 -0
  83. data/test/unit/view_model/active_record/poly_test.rb +320 -0
  84. data/test/unit/view_model/active_record/shared_test.rb +285 -0
  85. data/test/unit/view_model/active_record/version_test.rb +121 -0
  86. data/test/unit/view_model/active_record_test.rb +542 -0
  87. data/test/unit/view_model/callbacks_test.rb +582 -0
  88. data/test/unit/view_model/deserialization_error/unique_violation_test.rb +73 -0
  89. data/test/unit/view_model/record_test.rb +524 -0
  90. data/test/unit/view_model/traversal_context_test.rb +371 -0
  91. data/test/unit/view_model_test.rb +62 -0
  92. metadata +490 -0
@@ -0,0 +1,371 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/unit'
6
+ require 'minitest/hooks'
7
+
8
+ require_relative '../../helpers/match_enumerator.rb'
9
+ require_relative '../../helpers/arvm_test_utilities.rb'
10
+ require_relative '../../helpers/arvm_test_models.rb'
11
+ require_relative '../../helpers/viewmodel_spec_helpers.rb'
12
+
13
+ require 'view_model'
14
+ require 'view_model/record'
15
+
16
+ class ViewModel::TraversalContextTest < ActiveSupport::TestCase
17
+ include ARVMTestUtilities
18
+ extend Minitest::Spec::DSL
19
+
20
+ # Use a on-entry callback to ensure that views are visited with the expected
21
+ # local TraversalContext in various flows
22
+ ContextDetail = Value.new(:parent_ref, :parent_association, :root)
23
+
24
+ class ContextRecorder
25
+ include ViewModel::Callbacks
26
+ attr_reader :details
27
+
28
+ # Views are identified by their ref (type/id): this means that for the
29
+ # purposes of these tests, new models must all have an id specified.
30
+ def initialize
31
+ @details = {}
32
+ end
33
+
34
+ # record information after_visit: allows id of new models to be established
35
+ after_visit do
36
+ ref = view.to_reference
37
+ raise RuntimeError.new('Visited twice') if details.has_key?(ref)
38
+ details[ref] = ContextDetail.new(
39
+ context.parent_viewmodel&.to_reference,
40
+ context.parent_association,
41
+ context.root?)
42
+ end
43
+ end
44
+
45
+ let(:vm) { create_viewmodel! }
46
+
47
+ let(:context_recorder) { ContextRecorder.new }
48
+
49
+ # Set up serialization and deserialization helpers to use the recording callback
50
+ def vm_serialize_context(viewmodel_class, **args)
51
+ viewmodel_class.new_serialize_context(callbacks: [context_recorder], **args)
52
+ end
53
+
54
+ def vm_deserialize_context(viewmodel_class, **args)
55
+ viewmodel_class.new_deserialize_context(callbacks: [context_recorder], **args)
56
+ end
57
+
58
+ def serialize(view, serialize_context: vm_serialize_context(view.class))
59
+ super(view, serialize_context: serialize_context)
60
+ end
61
+
62
+ def serialize_with_references(view, serialize_context: vm_serialize_context(view.class))
63
+ super(view, serialize_context: serialize_context)
64
+ end
65
+
66
+ # use `alter_by_view` to test deserialization: only override the deserialize_context
67
+ def alter_by_view!(vm_class, model,
68
+ deserialize_context: vm_deserialize_context(vm_class),
69
+ **args,
70
+ &block)
71
+ super(vm_class, model, deserialize_context: deserialize_context, **args, &block)
72
+ end
73
+
74
+ module TraversalBehaviour
75
+ extend ActiveSupport::Concern
76
+ include Minitest::Hooks
77
+
78
+ def assert_traversal_matches(expected_details, recorded_details)
79
+ value(recorded_details.keys).must_contain_exactly(expected_details.keys)
80
+
81
+ recorded_details.each do |model_id, recorded_detail|
82
+ value(recorded_detail).must_equal(expected_details[model_id])
83
+ end
84
+ end
85
+
86
+ # Helpers to manipulate alter_by_view view hashes. Assumes that the test
87
+ # models have no more than one shared association, and if present it is the
88
+ # one under test.
89
+ def clear_subject_association(view, refs)
90
+ refs.clear if subject_association.shared?
91
+ view[subject_association_name] = subject_association.collection? ? [] : nil
92
+ end
93
+
94
+ def set_subject_association(view, refs, value)
95
+ if subject_association.shared?
96
+ refs.clear
97
+ value = convert_to_refs(refs, value)
98
+ end
99
+ view[subject_association_name] = value
100
+ end
101
+
102
+ def add_to_subject_association(view, refs, value)
103
+ if subject_association.shared?
104
+ value = convert_to_refs(refs, value)
105
+ end
106
+ view[subject_association_name] << value
107
+ end
108
+
109
+ def remove_from_subject_association(view, refs)
110
+ view[subject_association_name].reject! do |child|
111
+ if subject_association.shared?
112
+ ref = child[ViewModel::REFERENCE_ATTRIBUTE]
113
+ child = refs[ref]
114
+ end
115
+ match = yield(child)
116
+ if match && subject_association.shared?
117
+ refs.delete(ref)
118
+ end
119
+ match
120
+ end
121
+ end
122
+
123
+ def convert_to_refs(refs, value)
124
+ i = 0
125
+ ViewModel::Utils.map_one_or_many(value) do |v|
126
+ ref = "_child_ref_#{i += 1}"
127
+ refs[ref] = v
128
+ { ViewModel::REFERENCE_ATTRIBUTE => ref }
129
+ end
130
+ end
131
+ end
132
+
133
+ module BehavesLikeSerialization
134
+ extend ActiveSupport::Concern
135
+ include TraversalBehaviour
136
+ # requires :expected_parent_details, :expected_children_details
137
+
138
+ def self.included(base)
139
+ base.instance_eval do
140
+ it 'traverses as expected while serializing' do
141
+ serialize_with_references(vm)
142
+ expected = expected_parent_details.merge(expected_children_details)
143
+ assert_traversal_matches(expected, context_recorder.details)
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ module BehavesLikeDeserialization
150
+ extend ActiveSupport::Concern
151
+ include TraversalBehaviour
152
+ # requires
153
+ # :expected_parent_details, :expected_children_details
154
+ # :new_child_hash, :new_child_expected_details
155
+
156
+ def self.included(base)
157
+ base.instance_eval do
158
+ it 'traverses as expected while deserializing' do
159
+ alter_by_view!(viewmodel_class, vm.model) {}
160
+ expected = expected_parent_details.merge(expected_children_details)
161
+ assert_traversal_matches(expected, context_recorder.details)
162
+ end
163
+
164
+ it 'traverses as expected while clearing child(ren)' do
165
+ alter_by_view!(viewmodel_class, vm.model) do |view, refs|
166
+ clear_subject_association(view, refs)
167
+ end
168
+
169
+ expected = expected_parent_details
170
+ expected = expected.merge(expected_children_details) unless subject_association.shared?
171
+ assert_traversal_matches(expected, context_recorder.details)
172
+ end
173
+
174
+ it 'traverses as expected while replacing child(ren)' do
175
+ replacement = subject_association.collection? ? [new_child_hash] : new_child_hash
176
+
177
+ alter_by_view!(viewmodel_class, vm.model) do |view, refs|
178
+ set_subject_association(view, refs, replacement)
179
+ end
180
+
181
+ expected = expected_parent_details
182
+ expected = expected.merge(expected_children_details) unless subject_association.shared?
183
+ expected = expected.merge(new_child_expected_details)
184
+ assert_traversal_matches(expected, context_recorder.details)
185
+ end
186
+
187
+ it 'traverses as expected in replace_associated' do
188
+ ctx = vm_deserialize_context(viewmodel_class)
189
+ replacement = subject_association.collection? ? [new_child_hash] : new_child_hash
190
+ vm.replace_associated(subject_association_name, replacement, deserialize_context: ctx)
191
+
192
+ expected = expected_parent_details
193
+ expected = expected.merge(expected_children_details) unless subject_association.shared?
194
+ expected = expected.merge(new_child_expected_details)
195
+ assert_traversal_matches(expected, context_recorder.details)
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ module BehavesLikeCollectionDeserialization
202
+ extend ActiveSupport::Concern
203
+ include TraversalBehaviour
204
+
205
+ # requires :removed_child
206
+ def self.included(base)
207
+ base.instance_eval do
208
+ it 'traverses as expected when adding to children' do
209
+ alter_by_view!(viewmodel_class, vm.model) do |view, refs|
210
+ add_to_subject_association(view, refs, new_child_hash)
211
+ end
212
+
213
+ expected = expected_parent_details
214
+ .merge(expected_children_details)
215
+ .merge(new_child_expected_details)
216
+ assert_traversal_matches(expected, context_recorder.details)
217
+ end
218
+
219
+ it 'traverses as expected when removing from children' do
220
+ alter_by_view!(viewmodel_class, vm.model) do |view, refs|
221
+ remove_from_subject_association(view, refs) do |child|
222
+ child['id'] == removed_child.id
223
+ end
224
+ end
225
+
226
+ expected = expected_parent_details.merge(expected_children_details)
227
+ expected = expected.except(removed_child.to_reference) if subject_association.shared?
228
+ assert_traversal_matches(expected, context_recorder.details)
229
+ end
230
+
231
+ it 'traverses as expected in append_associated' do
232
+ ctx = vm_deserialize_context(viewmodel_class)
233
+ vm.append_associated(subject_association_name, [new_child_hash], deserialize_context: ctx)
234
+
235
+ expected = expected_parent_details.merge(new_child_expected_details)
236
+ assert_traversal_matches(expected, context_recorder.details)
237
+ end
238
+
239
+ it 'traverses as expected in delete_associated' do
240
+ ctx = vm_deserialize_context(viewmodel_class)
241
+ vm.delete_associated(subject_association_name, removed_child.id, deserialize_context: ctx)
242
+
243
+ expected = expected_parent_details
244
+ expected = expected.merge(removed_child_expected_details) unless subject_association.shared?
245
+ assert_traversal_matches(expected, context_recorder.details)
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ module BehavesLikeVisitor
252
+ def self.included(base)
253
+ base.instance_eval do
254
+ it 'traverses as expected while visiting' do
255
+ ViewModel::ActiveRecord::Visitor.new.visit(vm, context: vm_serialize_context(viewmodel_class))
256
+ expected = expected_parent_details.merge(expected_children_details)
257
+ assert_traversal_matches(expected, context_recorder.details)
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ # For each association type we want to make sure the traversal environment is
264
+ # as expected in every method of traversal.
265
+
266
+ let(:root_detail) { ContextDetail.new(nil, nil, true) }
267
+ let(:child_detail) do
268
+ if subject_association.shared?
269
+ root_detail
270
+ else
271
+ ContextDetail.new(vm.to_reference, subject_association_name, false)
272
+ end
273
+ end
274
+
275
+ let(:expected_parent_details) do
276
+ { vm.to_reference => root_detail }
277
+ end
278
+
279
+ let(:expected_children_details) do
280
+ children = {}
281
+ Array.wrap(vm.send(subject_association_name)).each do |child_vm|
282
+ children[child_vm.to_reference] = child_detail
283
+ end
284
+ children
285
+ end
286
+
287
+ before(:each) { expected_children_details }
288
+
289
+ let(:new_model) do
290
+ associated =
291
+ if subject_association.collection?
292
+ [child_model_class.new(name: 'b'), child_model_class.new(name: 'c')]
293
+ else
294
+ child_model_class.new(name: 'b')
295
+ end
296
+
297
+ model_class.new(name: 'a', subject_association_name => associated)
298
+ end
299
+
300
+ let(:new_child_id) { 9999 }
301
+ let(:new_child_ref) { ViewModel::Reference.new(child_viewmodel_class, new_child_id) }
302
+ let(:new_child_hash) do
303
+ {
304
+ '_type' => child_viewmodel_class.view_name,
305
+ 'id' => new_child_id,
306
+ '_new' => true,
307
+ 'name' => 'z',
308
+ }
309
+ end
310
+
311
+ let(:new_child_expected_details) do
312
+ { new_child_ref => child_detail }
313
+ end
314
+
315
+ let(:removed_child) do
316
+ Array.wrap(vm.send(subject_association_name)).first
317
+ end
318
+
319
+ let(:removed_child_expected_details) do
320
+ { removed_child.to_reference => child_detail }
321
+ end
322
+
323
+ describe 'with parent and belongs to child' do
324
+ include ViewModelSpecHelpers::ParentAndBelongsToChild
325
+
326
+ include BehavesLikeSerialization
327
+ include BehavesLikeDeserialization
328
+ include BehavesLikeVisitor
329
+ end
330
+
331
+ describe 'with parent and has_one child' do
332
+ include ViewModelSpecHelpers::ParentAndBelongsToChild
333
+
334
+ include BehavesLikeSerialization
335
+ include BehavesLikeDeserialization
336
+ include BehavesLikeVisitor
337
+ end
338
+
339
+ describe 'with parent and has_many children' do
340
+ include ViewModelSpecHelpers::ParentAndHasManyChildren
341
+
342
+ include BehavesLikeSerialization
343
+ include BehavesLikeDeserialization
344
+ include BehavesLikeCollectionDeserialization
345
+ include BehavesLikeVisitor
346
+ end
347
+
348
+ describe 'with parent and shared child' do
349
+ include ViewModelSpecHelpers::ParentAndSharedChild
350
+
351
+ include BehavesLikeSerialization
352
+ include BehavesLikeDeserialization
353
+ include BehavesLikeVisitor
354
+ end
355
+
356
+ describe 'with parent and has-many-through children' do
357
+ include ViewModelSpecHelpers::ParentAndHasManyThroughChildren
358
+ let(:new_model) do
359
+ model_class.new(name: 'a',
360
+ model_children: [
361
+ join_model_class.new(child: child_model_class.new(name: 'b')),
362
+ join_model_class.new(child: child_model_class.new(name: 'c')),
363
+ ])
364
+ end
365
+
366
+ include BehavesLikeSerialization
367
+ include BehavesLikeDeserialization
368
+ include BehavesLikeCollectionDeserialization
369
+ include BehavesLikeVisitor
370
+ end
371
+ end
@@ -0,0 +1,62 @@
1
+ require "bundler/setup"
2
+ Bundler.require
3
+
4
+ require "minitest/autorun"
5
+
6
+ class DefaultViewModel < ViewModel
7
+ self.view_name = 'DefaultViewModel'
8
+ attributes :foo, :bar
9
+ end
10
+
11
+ class TestViewModel < ViewModel
12
+ self.view_name = 'TestViewModel'
13
+
14
+ attributes :val
15
+ def serialize_view(json, **_options)
16
+ json.name val
17
+ end
18
+ end
19
+
20
+ class ViewModel::ActiveRecordTest < ActiveSupport::TestCase
21
+ def test_serialize
22
+ s = TestViewModel.new("a")
23
+ assert_equal(TestViewModel.serialize_to_hash(s),
24
+ { "name" => "a" })
25
+ end
26
+
27
+ def test_default_serialize
28
+ s = DefaultViewModel.new("a", 1)
29
+ assert_equal(TestViewModel.serialize_to_hash(s),
30
+ { "foo" => "a", "bar" => 1 })
31
+ end
32
+
33
+ def test_default_serialize_array
34
+ s = DefaultViewModel.new("a", [1,2])
35
+ assert_equal(TestViewModel.serialize_to_hash(s),
36
+ { "foo" => "a", "bar" => [1,2] })
37
+ end
38
+
39
+ def test_default_serialize_hash
40
+ s = DefaultViewModel.new("a", { "x" => "y" })
41
+ assert_equal(DefaultViewModel.serialize_to_hash(s),
42
+ { "foo" => "a", "bar" => { "x" => "y" } })
43
+ end
44
+
45
+ def test_default_serialize_empty_hash
46
+ s = DefaultViewModel.new("a", {})
47
+ assert_equal(DefaultViewModel.serialize_to_hash(s),
48
+ { "foo" => "a", "bar" => {} })
49
+ end
50
+
51
+ def test_default_serialize_viewmodel
52
+ s = DefaultViewModel.new("a", DefaultViewModel.new(1, 2))
53
+ assert_equal(DefaultViewModel.serialize_to_hash(s),
54
+ { "foo" => "a", "bar" => { "foo" => 1, "bar" => 2 } })
55
+ end
56
+
57
+ def test_default_serialize_array_of_viewmodel
58
+ s = DefaultViewModel.new("a", [TestViewModel.new("x"), TestViewModel.new("y")])
59
+ assert_equal(DefaultViewModel.serialize_to_hash(s),
60
+ { "foo" => "a", "bar" => [{"name" => "x"}, {"name" => "y"}] })
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,490 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iknow_view_models
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.8.4
5
+ platform: ruby
6
+ authors:
7
+ - iKnow Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: acts_as_manual_list
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: deep_preloader
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: iknow_cache
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: iknow_params
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: safe_values
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: keyword_builder
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: concurrent-ruby
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: jbuilder
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: json_schema
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: lazily
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: renum
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: appraisal
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: bundler
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: byebug
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: method_source
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: minitest-hooks
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: pg
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '0.18'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '0.18'
279
+ - !ruby/object:Gem::Dependency
280
+ name: pry
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :development
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
293
+ - !ruby/object:Gem::Dependency
294
+ name: rake
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
307
+ - !ruby/object:Gem::Dependency
308
+ name: rspec-expectations
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '0'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - ">="
319
+ - !ruby/object:Gem::Version
320
+ version: '0'
321
+ - !ruby/object:Gem::Dependency
322
+ name: sqlite3
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - ">="
326
+ - !ruby/object:Gem::Version
327
+ version: '0'
328
+ type: :development
329
+ prerelease: false
330
+ version_requirements: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - ">="
333
+ - !ruby/object:Gem::Version
334
+ version: '0'
335
+ description: ''
336
+ email:
337
+ - edge@iknow.jp
338
+ executables: []
339
+ extensions: []
340
+ extra_rdoc_files: []
341
+ files:
342
+ - ".circleci/config.yml"
343
+ - ".gitignore"
344
+ - ".idea/codeStyleSettings.xml"
345
+ - ".travis.yml"
346
+ - Appraisals
347
+ - Gemfile
348
+ - LICENSE.txt
349
+ - README.md
350
+ - Rakefile
351
+ - appveyor.yml
352
+ - gemfiles/rails_5_2.gemfile
353
+ - gemfiles/rails_6_0_beta.gemfile
354
+ - iknow_view_models.gemspec
355
+ - lib/iknow_view_models.rb
356
+ - lib/iknow_view_models/railtie.rb
357
+ - lib/iknow_view_models/version.rb
358
+ - lib/view_model.rb
359
+ - lib/view_model/access_control.rb
360
+ - lib/view_model/access_control/composed.rb
361
+ - lib/view_model/access_control/open.rb
362
+ - lib/view_model/access_control/read_only.rb
363
+ - lib/view_model/access_control/tree.rb
364
+ - lib/view_model/access_control_error.rb
365
+ - lib/view_model/active_record.rb
366
+ - lib/view_model/active_record/association_data.rb
367
+ - lib/view_model/active_record/association_manipulation.rb
368
+ - lib/view_model/active_record/cache.rb
369
+ - lib/view_model/active_record/cache/cacheable_view.rb
370
+ - lib/view_model/active_record/cloner.rb
371
+ - lib/view_model/active_record/collection_nested_controller.rb
372
+ - lib/view_model/active_record/controller.rb
373
+ - lib/view_model/active_record/controller_base.rb
374
+ - lib/view_model/active_record/nested_controller_base.rb
375
+ - lib/view_model/active_record/singular_nested_controller.rb
376
+ - lib/view_model/active_record/update_context.rb
377
+ - lib/view_model/active_record/update_data.rb
378
+ - lib/view_model/active_record/update_operation.rb
379
+ - lib/view_model/active_record/visitor.rb
380
+ - lib/view_model/after_transaction_runner.rb
381
+ - lib/view_model/callbacks.rb
382
+ - lib/view_model/changes.rb
383
+ - lib/view_model/config.rb
384
+ - lib/view_model/controller.rb
385
+ - lib/view_model/deserialization_error.rb
386
+ - lib/view_model/deserialize_context.rb
387
+ - lib/view_model/error.rb
388
+ - lib/view_model/error_view.rb
389
+ - lib/view_model/record.rb
390
+ - lib/view_model/record/attribute_data.rb
391
+ - lib/view_model/reference.rb
392
+ - lib/view_model/references.rb
393
+ - lib/view_model/registry.rb
394
+ - lib/view_model/schemas.rb
395
+ - lib/view_model/serialization_error.rb
396
+ - lib/view_model/serialize_context.rb
397
+ - lib/view_model/test_helpers.rb
398
+ - lib/view_model/test_helpers/arvm_builder.rb
399
+ - lib/view_model/traversal_context.rb
400
+ - lib/view_model/utils.rb
401
+ - lib/view_model/utils/collections.rb
402
+ - test/config/database.yml
403
+ - test/helpers/arvm_test_models.rb
404
+ - test/helpers/arvm_test_utilities.rb
405
+ - test/helpers/callback_tracer.rb
406
+ - test/helpers/controller_test_helpers.rb
407
+ - test/helpers/match_enumerator.rb
408
+ - test/helpers/query_logging.rb
409
+ - test/helpers/test_access_control.rb
410
+ - test/helpers/viewmodel_spec_helpers.rb
411
+ - test/unit/view_model/access_control_test.rb
412
+ - test/unit/view_model/active_record/alias_test.rb
413
+ - test/unit/view_model/active_record/belongs_to_test.rb
414
+ - test/unit/view_model/active_record/cache_test.rb
415
+ - test/unit/view_model/active_record/cloner_test.rb
416
+ - test/unit/view_model/active_record/controller_test.rb
417
+ - test/unit/view_model/active_record/counter_test.rb
418
+ - test/unit/view_model/active_record/customization_test.rb
419
+ - test/unit/view_model/active_record/has_many_test.rb
420
+ - test/unit/view_model/active_record/has_many_through_poly_test.rb
421
+ - test/unit/view_model/active_record/has_many_through_test.rb
422
+ - test/unit/view_model/active_record/has_one_test.rb
423
+ - test/unit/view_model/active_record/namespacing_test.rb
424
+ - test/unit/view_model/active_record/optional_attribute_view_test.rb
425
+ - test/unit/view_model/active_record/poly_test.rb
426
+ - test/unit/view_model/active_record/shared_test.rb
427
+ - test/unit/view_model/active_record/version_test.rb
428
+ - test/unit/view_model/active_record_test.rb
429
+ - test/unit/view_model/callbacks_test.rb
430
+ - test/unit/view_model/deserialization_error/unique_violation_test.rb
431
+ - test/unit/view_model/record_test.rb
432
+ - test/unit/view_model/traversal_context_test.rb
433
+ - test/unit/view_model_test.rb
434
+ homepage: https://github.com/iknow/cerego_view_models
435
+ licenses:
436
+ - MIT
437
+ metadata: {}
438
+ post_install_message:
439
+ rdoc_options: []
440
+ require_paths:
441
+ - lib
442
+ required_ruby_version: !ruby/object:Gem::Requirement
443
+ requirements:
444
+ - - ">="
445
+ - !ruby/object:Gem::Version
446
+ version: '0'
447
+ required_rubygems_version: !ruby/object:Gem::Requirement
448
+ requirements:
449
+ - - ">="
450
+ - !ruby/object:Gem::Version
451
+ version: '0'
452
+ requirements: []
453
+ rubygems_version: 3.0.3
454
+ signing_key:
455
+ specification_version: 4
456
+ summary: ViewModels provide a means of encapsulating a collection of related data
457
+ and specifying its JSON serialization.
458
+ test_files:
459
+ - test/config/database.yml
460
+ - test/helpers/arvm_test_models.rb
461
+ - test/helpers/arvm_test_utilities.rb
462
+ - test/helpers/callback_tracer.rb
463
+ - test/helpers/controller_test_helpers.rb
464
+ - test/helpers/match_enumerator.rb
465
+ - test/helpers/query_logging.rb
466
+ - test/helpers/test_access_control.rb
467
+ - test/helpers/viewmodel_spec_helpers.rb
468
+ - test/unit/view_model/access_control_test.rb
469
+ - test/unit/view_model/active_record/alias_test.rb
470
+ - test/unit/view_model/active_record/belongs_to_test.rb
471
+ - test/unit/view_model/active_record/cache_test.rb
472
+ - test/unit/view_model/active_record/cloner_test.rb
473
+ - test/unit/view_model/active_record/controller_test.rb
474
+ - test/unit/view_model/active_record/counter_test.rb
475
+ - test/unit/view_model/active_record/customization_test.rb
476
+ - test/unit/view_model/active_record/has_many_test.rb
477
+ - test/unit/view_model/active_record/has_many_through_poly_test.rb
478
+ - test/unit/view_model/active_record/has_many_through_test.rb
479
+ - test/unit/view_model/active_record/has_one_test.rb
480
+ - test/unit/view_model/active_record/namespacing_test.rb
481
+ - test/unit/view_model/active_record/optional_attribute_view_test.rb
482
+ - test/unit/view_model/active_record/poly_test.rb
483
+ - test/unit/view_model/active_record/shared_test.rb
484
+ - test/unit/view_model/active_record/version_test.rb
485
+ - test/unit/view_model/active_record_test.rb
486
+ - test/unit/view_model/callbacks_test.rb
487
+ - test/unit/view_model/deserialization_error/unique_violation_test.rb
488
+ - test/unit/view_model/record_test.rb
489
+ - test/unit/view_model/traversal_context_test.rb
490
+ - test/unit/view_model_test.rb