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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +6 -6
- data/.rubocop.yml +18 -0
- data/Appraisals +6 -6
- data/Gemfile +6 -2
- data/Rakefile +5 -5
- data/gemfiles/rails_5_2.gemfile +5 -5
- data/gemfiles/rails_6_0.gemfile +9 -0
- data/iknow_view_models.gemspec +40 -38
- data/lib/iknow_view_models.rb +9 -7
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model.rb +31 -17
- data/lib/view_model/access_control.rb +5 -2
- data/lib/view_model/access_control/composed.rb +10 -9
- data/lib/view_model/access_control/open.rb +2 -0
- data/lib/view_model/access_control/read_only.rb +2 -0
- data/lib/view_model/access_control/tree.rb +11 -6
- data/lib/view_model/access_control_error.rb +4 -1
- data/lib/view_model/active_record.rb +17 -15
- data/lib/view_model/active_record/association_data.rb +2 -1
- data/lib/view_model/active_record/association_manipulation.rb +6 -4
- data/lib/view_model/active_record/cache.rb +114 -34
- data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
- data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
- data/lib/view_model/active_record/controller.rb +68 -1
- data/lib/view_model/active_record/controller_base.rb +4 -1
- data/lib/view_model/active_record/nested_controller_base.rb +1 -0
- data/lib/view_model/active_record/update_context.rb +8 -6
- data/lib/view_model/active_record/update_data.rb +32 -30
- data/lib/view_model/active_record/update_operation.rb +17 -13
- data/lib/view_model/active_record/visitor.rb +0 -1
- data/lib/view_model/after_transaction_runner.rb +0 -1
- data/lib/view_model/callbacks.rb +3 -1
- data/lib/view_model/controller.rb +13 -3
- data/lib/view_model/deserialization_error.rb +15 -12
- data/lib/view_model/error.rb +12 -10
- data/lib/view_model/error_view.rb +3 -1
- data/lib/view_model/migratable_view.rb +78 -0
- data/lib/view_model/migration.rb +48 -0
- data/lib/view_model/migration/no_path_error.rb +26 -0
- data/lib/view_model/migration/one_way_error.rb +24 -0
- data/lib/view_model/migration/unspecified_version_error.rb +24 -0
- data/lib/view_model/migrator.rb +108 -0
- data/lib/view_model/record.rb +15 -14
- data/lib/view_model/reference.rb +3 -1
- data/lib/view_model/references.rb +8 -5
- data/lib/view_model/registry.rb +14 -2
- data/lib/view_model/schemas.rb +9 -4
- data/lib/view_model/serialization_error.rb +4 -1
- data/lib/view_model/serialize_context.rb +4 -4
- data/lib/view_model/test_helpers.rb +8 -3
- data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
- data/lib/view_model/traversal_context.rb +2 -1
- data/nix/dependencies.nix +5 -0
- data/nix/gem/generate.rb +2 -1
- data/shell.nix +8 -3
- data/test/.rubocop.yml +14 -0
- data/test/helpers/arvm_test_models.rb +12 -9
- data/test/helpers/arvm_test_utilities.rb +5 -3
- data/test/helpers/controller_test_helpers.rb +55 -32
- data/test/helpers/match_enumerator.rb +1 -0
- data/test/helpers/query_logging.rb +2 -1
- data/test/helpers/test_access_control.rb +5 -3
- data/test/helpers/viewmodel_spec_helpers.rb +88 -22
- data/test/unit/view_model/access_control_test.rb +144 -144
- data/test/unit/view_model/active_record/alias_test.rb +15 -13
- data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
- data/test/unit/view_model/active_record/cache_test.rb +68 -31
- data/test/unit/view_model/active_record/cloner_test.rb +67 -63
- data/test/unit/view_model/active_record/controller_test.rb +113 -65
- data/test/unit/view_model/active_record/counter_test.rb +10 -9
- data/test/unit/view_model/active_record/customization_test.rb +59 -58
- data/test/unit/view_model/active_record/has_many_test.rb +112 -111
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
- data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
- data/test/unit/view_model/active_record/has_one_test.rb +37 -36
- data/test/unit/view_model/active_record/migration_test.rb +161 -0
- data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
- data/test/unit/view_model/active_record/poly_test.rb +44 -45
- data/test/unit/view_model/active_record/shared_test.rb +30 -28
- data/test/unit/view_model/active_record/version_test.rb +9 -7
- data/test/unit/view_model/active_record_test.rb +72 -72
- data/test/unit/view_model/callbacks_test.rb +19 -15
- data/test/unit/view_model/controller_test.rb +4 -2
- data/test/unit/view_model/record_test.rb +158 -145
- data/test/unit/view_model/registry_test.rb +38 -0
- data/test/unit/view_model/traversal_context_test.rb +4 -5
- data/test/unit/view_model_test.rb +18 -16
- metadata +38 -12
- data/.travis.yml +0 -31
- data/appveyor.yml +0 -22
- data/gemfiles/rails_6_0_beta.gemfile +0 -9
| @@ -1,9 +1,11 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require_relative "../../../helpers/arvm_test_models.rb"
         | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 3 2 |  | 
| 4 | 
            -
             | 
| 3 | 
            +
            require_relative '../../../helpers/arvm_test_utilities'
         | 
| 4 | 
            +
            require_relative '../../../helpers/arvm_test_models'
         | 
| 5 5 |  | 
| 6 | 
            -
            require  | 
| 6 | 
            +
            require 'minitest/autorun'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'view_model/active_record'
         | 
| 7 9 |  | 
| 8 10 | 
             
            class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase
         | 
| 9 11 | 
             
              include ARVMTestUtilities
         | 
| @@ -99,7 +101,7 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 99 101 | 
             
                                         parents_tags: [ParentsTag.new(tag: @tag_a1, position: 1.0),
         | 
| 100 102 | 
             
                                                        ParentsTag.new(tag: @tag_a2, position: 2.0),
         | 
| 101 103 | 
             
                                                        ParentsTag.new(tag: @tag_b1, position: 3.0),
         | 
| 102 | 
            -
                                                        ParentsTag.new(tag: @tag_b2, position: 4.0)])
         | 
| 104 | 
            +
                                                        ParentsTag.new(tag: @tag_b2, position: 4.0),])
         | 
| 103 105 |  | 
| 104 106 | 
             
                enable_logging!
         | 
| 105 107 | 
             
              end
         | 
| @@ -135,7 +137,7 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 135 137 | 
             
              end
         | 
| 136 138 |  | 
| 137 139 | 
             
              def test_preload_dependencies
         | 
| 138 | 
            -
                # TODO not part of ARVM; but depends on the particular context from #before_all
         | 
| 140 | 
            +
                # TODO: not part of ARVM; but depends on the particular context from #before_all
         | 
| 139 141 | 
             
                # If we refactor out the contexts from their tests, this should go in another test file.
         | 
| 140 142 |  | 
| 141 143 | 
             
                root_updates, _ref_updates = ViewModel::ActiveRecord::UpdateData.parse_hashes([{ '_type' => 'Parent' }])
         | 
| @@ -145,7 +147,7 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 145 147 |  | 
| 146 148 | 
             
                root_updates, _ref_updates = ViewModel::ActiveRecord::UpdateData.parse_hashes([{ '_type' => 'Parent',
         | 
| 147 149 | 
             
                                                                                              'tags' => [{ '_ref' => 'r1' }] }],
         | 
| 148 | 
            -
             | 
| 150 | 
            +
                                                                                              { 'r1' => { '_type' => 'TagB' } })
         | 
| 149 151 |  | 
| 150 152 | 
             
                assert_equal(DeepPreloader::Spec.new(
         | 
| 151 153 | 
             
                              'parents_tags' => DeepPreloader::Spec.new(
         | 
| @@ -154,7 +156,6 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 154 156 | 
             
                             'mentioning tags causes through association loading, excluding shared')
         | 
| 155 157 | 
             
              end
         | 
| 156 158 |  | 
| 157 | 
            -
             | 
| 158 159 | 
             
              def test_serialize
         | 
| 159 160 | 
             
                view, refs = serialize_with_references(ParentView.new(@parent1))
         | 
| 160 161 |  | 
| @@ -162,7 +163,7 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 162 163 | 
             
                assert_equal([{ 'id' => @tag_a1.id, '_type' => 'TagA', '_version' => 1, 'name' => 'tag A1' },
         | 
| 163 164 | 
             
                              { 'id' => @tag_a2.id, '_type' => 'TagA', '_version' => 1, 'name' => 'tag A2' },
         | 
| 164 165 | 
             
                              { 'id' => @tag_b1.id, '_type' => 'TagB', '_version' => 1, 'name' => 'tag B1' },
         | 
| 165 | 
            -
                              { 'id' => @tag_b2.id, '_type' => 'TagB', '_version' => 1, 'name' => 'tag B2' }],
         | 
| 166 | 
            +
                              { 'id' => @tag_b2.id, '_type' => 'TagB', '_version' => 1, 'name' => 'tag B2' },],
         | 
| 166 167 | 
             
                             tag_data)
         | 
| 167 168 | 
             
              end
         | 
| 168 169 |  | 
| @@ -186,7 +187,7 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 186 187 | 
             
              end
         | 
| 187 188 |  | 
| 188 189 | 
             
              def test_reordering_swap_type
         | 
| 189 | 
            -
                alter_by_view!(ParentView, @parent1) do |view,  | 
| 190 | 
            +
                alter_by_view!(ParentView, @parent1) do |view, _refs|
         | 
| 190 191 | 
             
                  t1, t2, t3, t4 = view['tags']
         | 
| 191 192 | 
             
                  view['tags'] = [t3, t2, t1, t4]
         | 
| 192 193 | 
             
                end
         | 
| @@ -248,16 +249,16 @@ class ViewModel::ActiveRecord::HasManyThroughPolyTest < ActiveSupport::TestCase | |
| 248 249 | 
             
                def test_renamed_roundtrip
         | 
| 249 250 | 
             
                  context = ParentView.new_serialize_context
         | 
| 250 251 | 
             
                  alter_by_view!(ParentView, @parent, serialize_context: context) do |view, refs|
         | 
| 251 | 
            -
                    assert_equal({refs.keys.first => { 'id' | 
| 252 | 
            +
                    assert_equal({ refs.keys.first => { 'id' => @parent.parents_tags.first.tag.id,
         | 
| 252 253 | 
             
                                                       '_type'    => 'TagA',
         | 
| 253 254 | 
             
                                                       '_version' => 1,
         | 
| 254 | 
            -
                                                       'name'     => 'tag A name' }}, refs)
         | 
| 255 | 
            +
                                                       'name'     => 'tag A name' } }, refs)
         | 
| 255 256 | 
             
                    assert_equal([{ '_ref' => refs.keys.first }],
         | 
| 256 257 | 
             
                                 view['something_else'])
         | 
| 257 258 |  | 
| 258 259 | 
             
                    refs.clear
         | 
| 259 | 
            -
                    refs['new'] = {'_type' => 'TagB', 'name' => 'tag B name'}
         | 
| 260 | 
            -
                    view['something_else'] = [{'_ref' => 'new'}]
         | 
| 260 | 
            +
                    refs['new'] = { '_type' => 'TagB', 'name' => 'tag B name' }
         | 
| 261 | 
            +
                    view['something_else'] = [{ '_ref' => 'new' }]
         | 
| 261 262 | 
             
                  end
         | 
| 262 263 |  | 
| 263 264 | 
             
                  assert_equal('tag B name', @parent.parents_tags.first.tag.name)
         | 
| @@ -1,9 +1,11 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require_relative "../../../helpers/arvm_test_models.rb"
         | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 3 2 |  | 
| 4 | 
            -
             | 
| 3 | 
            +
            require_relative '../../../helpers/arvm_test_utilities'
         | 
| 4 | 
            +
            require_relative '../../../helpers/arvm_test_models'
         | 
| 5 5 |  | 
| 6 | 
            -
            require  | 
| 6 | 
            +
            require 'minitest/autorun'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'view_model/active_record'
         | 
| 7 9 |  | 
| 8 10 | 
             
            class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase
         | 
| 9 11 | 
             
              include ARVMTestUtilities
         | 
| @@ -78,7 +80,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 78 80 | 
             
                  define_model do
         | 
| 79 81 | 
             
                    belongs_to :parent
         | 
| 80 82 | 
             
                    belongs_to :tag
         | 
| 81 | 
            -
                    # TODO list membership?
         | 
| 83 | 
            +
                    # TODO: list membership?
         | 
| 82 84 | 
             
                  end
         | 
| 83 85 |  | 
| 84 86 | 
             
                  no_viewmodel
         | 
| @@ -100,7 +102,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 100 102 |  | 
| 101 103 | 
             
                @parent1 = Parent.create(name: 'p1',
         | 
| 102 104 | 
             
                                         parents_tags: [ParentsTag.new(tag: @tag1, position: 1.0),
         | 
| 103 | 
            -
                                                        ParentsTag.new(tag: @tag2, position: 2.0)])
         | 
| 105 | 
            +
                                                        ParentsTag.new(tag: @tag2, position: 2.0),])
         | 
| 104 106 |  | 
| 105 107 | 
             
                enable_logging!
         | 
| 106 108 | 
             
              end
         | 
| @@ -130,7 +132,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 130 132 | 
             
              end
         | 
| 131 133 |  | 
| 132 134 | 
             
              def test_preload_dependencies
         | 
| 133 | 
            -
                # TODO not part of ARVM; but depends on the particular context from #before_all
         | 
| 135 | 
            +
                # TODO: not part of ARVM; but depends on the particular context from #before_all
         | 
| 134 136 | 
             
                # If we refactor out the contexts from their tests, this should go in another test file.
         | 
| 135 137 |  | 
| 136 138 | 
             
                root_updates, _ref_updates = ViewModel::ActiveRecord::UpdateData.parse_hashes([{ '_type' => 'Parent' }])
         | 
| @@ -153,7 +155,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 153 155 |  | 
| 154 156 | 
             
                tag_data = view['tags'].map { |hash| refs[hash['_ref']] }
         | 
| 155 157 | 
             
                assert_equal([{ 'id' => @tag1.id, '_type' => 'Tag', '_version' => 1, 'name' => 'tag1' },
         | 
| 156 | 
            -
                              { 'id' => @tag2.id, '_type' => 'Tag', '_version' => 1, 'name' => 'tag2' }],
         | 
| 158 | 
            +
                              { 'id' => @tag2.id, '_type' => 'Tag', '_version' => 1, 'name' => 'tag2' },],
         | 
| 157 159 | 
             
                             tag_data)
         | 
| 158 160 | 
             
              end
         | 
| 159 161 |  | 
| @@ -197,7 +199,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 197 199 | 
             
              def test_child_edit_doesnt_editcheck_parent
         | 
| 198 200 | 
             
                # editing child doesn't edit check parent
         | 
| 199 201 | 
             
                pv, d_context = alter_by_view!(ParentView, @parent1) do |view, refs|
         | 
| 200 | 
            -
                  refs[view['tags'][0][ | 
| 202 | 
            +
                  refs[view['tags'][0]['_ref']]['name'] = 'changed'
         | 
| 201 203 | 
             
                end
         | 
| 202 204 |  | 
| 203 205 | 
             
                nc = pv.tags.detect { |t| t.name == 'changed' }
         | 
| @@ -259,7 +261,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 259 261 | 
             
                fupdate_tags(@parent1) do |tags|
         | 
| 260 262 | 
             
                  c1, c2 = tags
         | 
| 261 263 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }]) },
         | 
| 262 | 
            -
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } }
         | 
| 264 | 
            +
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } },
         | 
| 263 265 | 
             
                  }
         | 
| 264 266 | 
             
                end
         | 
| 265 267 | 
             
                assert_equal([c1.name, c2.name, 'new tag'],
         | 
| @@ -272,7 +274,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 272 274 | 
             
                  c1, c2 = tags
         | 
| 273 275 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }],
         | 
| 274 276 | 
             
                                                       before: { '_type' => 'Tag', 'id' => c2.id }) },
         | 
| 275 | 
            -
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } }
         | 
| 277 | 
            +
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } },
         | 
| 276 278 | 
             
                  }
         | 
| 277 279 | 
             
                end
         | 
| 278 280 | 
             
                assert_equal([c1.name, 'new tag', c2.name],
         | 
| @@ -285,7 +287,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 285 287 | 
             
                  c1, c2 = tags
         | 
| 286 288 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }],
         | 
| 287 289 | 
             
                                                       before: { '_type' => 'Tag', 'id' => c1.id }) },
         | 
| 288 | 
            -
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } }
         | 
| 290 | 
            +
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } },
         | 
| 289 291 | 
             
                  }
         | 
| 290 292 | 
             
                end
         | 
| 291 293 | 
             
                assert_equal(['new tag', c1.name, c2.name],
         | 
| @@ -298,21 +300,20 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 298 300 | 
             
                  c1, c2 = tags
         | 
| 299 301 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'c2' }],
         | 
| 300 302 | 
             
                                                       before: { '_type' => 'Tag', 'id' => c1.id }) },
         | 
| 301 | 
            -
                    :refs    => { 'c2' => { '_type' => 'Tag', 'id' => c2.id } }
         | 
| 303 | 
            +
                    :refs    => { 'c2' => { '_type' => 'Tag', 'id' => c2.id } },
         | 
| 302 304 | 
             
                  }
         | 
| 303 305 | 
             
                end
         | 
| 304 306 | 
             
                assert_equal([c2.name, c1.name],
         | 
| 305 307 | 
             
                             tags(@parent1).map(&:name))
         | 
| 306 308 | 
             
              end
         | 
| 307 309 |  | 
| 308 | 
            -
             | 
| 309 310 | 
             
              def test_functional_update_append_after_mid
         | 
| 310 311 | 
             
                c1 = c2 = nil
         | 
| 311 312 | 
             
                fupdate_tags(@parent1) do |tags|
         | 
| 312 313 | 
             
                  c1, c2 = tags
         | 
| 313 314 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }],
         | 
| 314 315 | 
             
                                                       after: { '_type' => 'Tag', 'id' => c1.id }) },
         | 
| 315 | 
            -
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } }
         | 
| 316 | 
            +
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } },
         | 
| 316 317 | 
             
                  }
         | 
| 317 318 | 
             
                end
         | 
| 318 319 | 
             
                assert_equal([c1.name, 'new tag', c2.name],
         | 
| @@ -325,7 +326,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 325 326 | 
             
                  c1, c2 = tags
         | 
| 326 327 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }],
         | 
| 327 328 | 
             
                                                       after: { '_type' => 'Tag', 'id' => c2.id }) },
         | 
| 328 | 
            -
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } }
         | 
| 329 | 
            +
                    :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag' } },
         | 
| 329 330 | 
             
                  }
         | 
| 330 331 | 
             
                end
         | 
| 331 332 | 
             
                assert_equal([c1.name, c2.name, 'new tag'],
         | 
| @@ -338,7 +339,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 338 339 | 
             
                  c1, c2 = tags
         | 
| 339 340 | 
             
                  { :fupdate => build_fupdate { append([{ '_ref' => 'c1' }],
         | 
| 340 341 | 
             
                                                       after: { '_type' => 'Tag', 'id' => c2.id }) },
         | 
| 341 | 
            -
                    :refs    => { 'c1' => { '_type' => 'Tag', 'id' => c1.id } }
         | 
| 342 | 
            +
                    :refs    => { 'c1' => { '_type' => 'Tag', 'id' => c1.id } },
         | 
| 342 343 | 
             
                  }
         | 
| 343 344 | 
             
                end
         | 
| 344 345 | 
             
                assert_equal([c2.name, c1.name],
         | 
| @@ -375,7 +376,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 375 376 | 
             
                    @parent1.parents_tags.where(tag_id: c2.id).destroy_all
         | 
| 376 377 | 
             
                    { :fupdate => build_fupdate { append([{ '_ref' => 'new_tag' }],
         | 
| 377 378 | 
             
                                                         after: { '_type' => 'Tag', 'id' => c2.id }) },
         | 
| 378 | 
            -
                      :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag name' } }
         | 
| 379 | 
            +
                      :refs    => { 'new_tag' => { '_type' => 'Tag', 'name' => 'new tag name' } },
         | 
| 379 380 | 
             
                    }
         | 
| 380 381 | 
             
                  end
         | 
| 381 382 | 
             
                end
         | 
| @@ -387,13 +388,12 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 387 388 | 
             
                c1 = c2 = nil
         | 
| 388 389 | 
             
                fupdate_tags(@parent1) do |tags|
         | 
| 389 390 | 
             
                  c1, c2 = tags
         | 
| 390 | 
            -
                  { :fupdate => build_fupdate { update([{ '_ref' => 'c1' }])},
         | 
| 391 | 
            -
                    :refs    => { 'c1' => { '_type' => 'Tag', 'id' => c1.id, 'name' => 'c1 new name' } }
         | 
| 391 | 
            +
                  { :fupdate => build_fupdate { update([{ '_ref' => 'c1' }]) },
         | 
| 392 | 
            +
                    :refs    => { 'c1' => { '_type' => 'Tag', 'id' => c1.id, 'name' => 'c1 new name' } },
         | 
| 392 393 | 
             
                  }
         | 
| 393 394 | 
             
                end
         | 
| 394 395 | 
             
                assert_equal(['c1 new name', c2.name],
         | 
| 395 396 | 
             
                             tags(@parent1).map(&:name))
         | 
| 396 | 
            -
             | 
| 397 397 | 
             
              end
         | 
| 398 398 |  | 
| 399 399 | 
             
              def test_functional_update_update_stale
         | 
| @@ -403,14 +403,13 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 403 403 | 
             
                c2.parents_tags.destroy_all
         | 
| 404 404 |  | 
| 405 405 | 
             
                ex = assert_raises(ViewModel::DeserializationError::AssociatedNotFound) do
         | 
| 406 | 
            -
                  fupdate_tags(@parent1) do | | 
| 407 | 
            -
            #        @parent1.parents_tags.where(tag_id: c2.id).destroy_all
         | 
| 406 | 
            +
                  fupdate_tags(@parent1) do |_tags|
         | 
| 408 407 | 
             
                    { :fupdate => build_fupdate { update([{ '_ref' => 'c2' }]) },
         | 
| 409 | 
            -
                      :refs    => { 'c2' => { '_type' => 'Tag', 'id' => c2.id, 'name' => 'c2 new name' } }
         | 
| 408 | 
            +
                      :refs    => { 'c2' => { '_type' => 'Tag', 'id' => c2.id, 'name' => 'c2 new name' } },
         | 
| 410 409 | 
             
                    }
         | 
| 411 410 | 
             
                  end
         | 
| 412 411 | 
             
                end
         | 
| 413 | 
            -
                assert_equal( | 
| 412 | 
            +
                assert_equal('tags', ex.association)
         | 
| 414 413 | 
             
                assert_equal([ViewModel::Reference.new(TagView, c2.id)], ex.missing_nodes)
         | 
| 415 414 | 
             
              end
         | 
| 416 415 |  | 
| @@ -442,7 +441,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 442 441 | 
             
                                           deserialize_context: context)
         | 
| 443 442 |  | 
| 444 443 | 
             
                expected_edit_checks = [pv.to_reference,
         | 
| 445 | 
            -
                                        *nc.map(&:to_reference)]
         | 
| 444 | 
            +
                                        *nc.map(&:to_reference),]
         | 
| 446 445 |  | 
| 447 446 | 
             
                assert_contains_exactly(expected_edit_checks,
         | 
| 448 447 | 
             
                                        context.valid_edit_refs)
         | 
| @@ -476,7 +475,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 476 475 |  | 
| 477 476 | 
             
                expected_edit_checks = [ViewModel::Reference.new(ParentView, @parent1.id),
         | 
| 478 477 | 
             
                                        ViewModel::Reference.new(TagView, @tag1.id),
         | 
| 479 | 
            -
                                        ViewModel::Reference.new(TagView, new_tag.id)]
         | 
| 478 | 
            +
                                        ViewModel::Reference.new(TagView, new_tag.id),]
         | 
| 480 479 |  | 
| 481 480 | 
             
                assert_contains_exactly(expected_edit_checks,
         | 
| 482 481 | 
             
                                        context.valid_edit_refs)
         | 
| @@ -518,7 +517,6 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 518 517 |  | 
| 519 518 | 
             
                assert_equal(expected_edit_checks, context.valid_edit_refs.to_set)
         | 
| 520 519 |  | 
| 521 | 
            -
             | 
| 522 520 | 
             
                assert_equal([@tag2, @tag1],
         | 
| 523 521 | 
             
                             tags(@parent1))
         | 
| 524 522 |  | 
| @@ -536,8 +534,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 536 534 | 
             
                # append
         | 
| 537 535 | 
             
                pv.append_associated(:tags,
         | 
| 538 536 | 
             
                                     { '_type' => 'Tag', 'id' => @tag1.id },
         | 
| 539 | 
            -
                                     deserialize_context:  | 
| 540 | 
            -
             | 
| 537 | 
            +
                                     deserialize_context: ParentView.new_deserialize_context)
         | 
| 541 538 |  | 
| 542 539 | 
             
                assert_equal([@tag2, @tag1],
         | 
| 543 540 | 
             
                             tags(@parent1))
         | 
| @@ -563,7 +560,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 563 560 |  | 
| 564 561 | 
             
                # insert after
         | 
| 565 562 | 
             
                pv.append_associated(:tags,
         | 
| 566 | 
            -
                                     { '_type' => 'Tag', 'id' => | 
| 563 | 
            +
                                     { '_type' => 'Tag', 'id' => @tag3.id },
         | 
| 567 564 | 
             
                                     after: ViewModel::Reference.new(TagView, @tag1.id),
         | 
| 568 565 | 
             
                                     deserialize_context: (context = ParentView.new_deserialize_context))
         | 
| 569 566 |  | 
| @@ -577,8 +574,7 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 577 574 | 
             
                # append
         | 
| 578 575 | 
             
                pv.append_associated(:tags,
         | 
| 579 576 | 
             
                                     { '_type' => 'Tag', 'id' => @tag3.id },
         | 
| 580 | 
            -
                                     deserialize_context:  | 
| 581 | 
            -
             | 
| 577 | 
            +
                                     deserialize_context: ParentView.new_deserialize_context)
         | 
| 582 578 |  | 
| 583 579 | 
             
                assert_equal([@tag1, @tag2, @tag3],
         | 
| 584 580 | 
             
                             tags(@parent1))
         | 
| @@ -611,7 +607,6 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 611 607 | 
             
                  ViewModel::ActiveRecord::HasManyThroughTest.build_join_table_model(self)
         | 
| 612 608 | 
             
                end
         | 
| 613 609 |  | 
| 614 | 
            -
             | 
| 615 610 | 
             
                def setup
         | 
| 616 611 | 
             
                  super
         | 
| 617 612 |  | 
| @@ -629,16 +624,16 @@ class ViewModel::ActiveRecord::HasManyThroughTest < ActiveSupport::TestCase | |
| 629 624 | 
             
                def test_renamed_roundtrip
         | 
| 630 625 | 
             
                  context = ParentView.new_serialize_context
         | 
| 631 626 | 
             
                  alter_by_view!(ParentView, @parent, serialize_context: context) do |view, refs|
         | 
| 632 | 
            -
                    assert_equal({refs.keys.first => { 'id' | 
| 627 | 
            +
                    assert_equal({ refs.keys.first => { 'id' => @parent.parents_tags.first.tag.id,
         | 
| 633 628 | 
             
                                                       '_type'    => 'Tag',
         | 
| 634 629 | 
             
                                                       '_version' => 1,
         | 
| 635 | 
            -
                                                       'name'     => 'tag name' }}, refs)
         | 
| 630 | 
            +
                                                       'name'     => 'tag name' } }, refs)
         | 
| 636 631 | 
             
                    assert_equal([{ '_ref' => refs.keys.first }],
         | 
| 637 632 | 
             
                                 view['something_else'])
         | 
| 638 633 |  | 
| 639 634 | 
             
                    refs.clear
         | 
| 640 | 
            -
                    refs['new'] = {'_type' => 'Tag', 'name' => 'tag new name'}
         | 
| 641 | 
            -
                    view['something_else'] = [{'_ref' => 'new'}]
         | 
| 635 | 
            +
                    refs['new'] = { '_type' => 'Tag', 'name' => 'tag new name' }
         | 
| 636 | 
            +
                    view['something_else'] = [{ '_ref' => 'new' }]
         | 
| 642 637 | 
             
                  end
         | 
| 643 638 |  | 
| 644 639 | 
             
                  assert_equal('tag new name', @parent.parents_tags.first.tag.name)
         | 
| @@ -1,10 +1,12 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require_relative "../../../helpers/arvm_test_models.rb"
         | 
| 3 | 
            -
            require_relative '../../../helpers/viewmodel_spec_helpers.rb'
         | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 4 2 |  | 
| 5 | 
            -
             | 
| 3 | 
            +
            require_relative '../../../helpers/arvm_test_utilities'
         | 
| 4 | 
            +
            require_relative '../../../helpers/arvm_test_models'
         | 
| 5 | 
            +
            require_relative '../../../helpers/viewmodel_spec_helpers'
         | 
| 6 6 |  | 
| 7 | 
            -
            require  | 
| 7 | 
            +
            require 'minitest/autorun'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            require 'view_model/active_record'
         | 
| 8 10 |  | 
| 9 11 | 
             
            class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase
         | 
| 10 12 | 
             
              include ARVMTestUtilities
         | 
| @@ -15,13 +17,13 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 15 17 | 
             
              def setup
         | 
| 16 18 | 
             
                super
         | 
| 17 19 |  | 
| 18 | 
            -
                # TODO make a `has_list?` that allows a model to set all children as an array
         | 
| 19 | 
            -
                @model1 = model_class.new(name:  | 
| 20 | 
            -
                                      child: child_model_class.new(name:  | 
| 20 | 
            +
                # TODO: make a `has_list?` that allows a model to set all children as an array
         | 
| 21 | 
            +
                @model1 = model_class.new(name: 'p1',
         | 
| 22 | 
            +
                                      child: child_model_class.new(name: 'p1t'))
         | 
| 21 23 | 
             
                @model1.save!
         | 
| 22 24 |  | 
| 23 | 
            -
                @model2 = model_class.new(name:  | 
| 24 | 
            -
                                      child: child_model_class.new(name:  | 
| 25 | 
            +
                @model2 = model_class.new(name: 'p2',
         | 
| 26 | 
            +
                                      child: child_model_class.new(name: 'p2t'))
         | 
| 25 27 |  | 
| 26 28 | 
             
                @model2.save!
         | 
| 27 29 |  | 
| @@ -38,9 +40,9 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 38 40 |  | 
| 39 41 | 
             
              def test_create_from_view
         | 
| 40 42 | 
             
                view = {
         | 
| 41 | 
            -
                   | 
| 42 | 
            -
                   | 
| 43 | 
            -
                   | 
| 43 | 
            +
                  '_type'    => 'Model',
         | 
| 44 | 
            +
                  'name'     => 'p',
         | 
| 45 | 
            +
                  'child' => { '_type' => 'Child', 'name' => 't' },
         | 
| 44 46 | 
             
                }
         | 
| 45 47 |  | 
| 46 48 | 
             
                pv = ModelView.deserialize_from_view(view)
         | 
| @@ -49,23 +51,22 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 49 51 | 
             
                assert(!p.changed?)
         | 
| 50 52 | 
             
                assert(!p.new_record?)
         | 
| 51 53 |  | 
| 52 | 
            -
                assert_equal( | 
| 53 | 
            -
             | 
| 54 | 
            +
                assert_equal('p', p.name)
         | 
| 54 55 |  | 
| 55 56 | 
             
                assert(p.child.present?)
         | 
| 56 | 
            -
                assert_equal( | 
| 57 | 
            +
                assert_equal('t', p.child.name)
         | 
| 57 58 | 
             
              end
         | 
| 58 59 |  | 
| 59 60 | 
             
              def test_serialize_view
         | 
| 60 61 | 
             
                view, _refs = serialize_with_references(ModelView.new(@model1))
         | 
| 61 | 
            -
                assert_equal({  | 
| 62 | 
            -
                                | 
| 63 | 
            -
                                | 
| 64 | 
            -
                                | 
| 65 | 
            -
                                | 
| 66 | 
            -
                                                | 
| 67 | 
            -
                                                | 
| 68 | 
            -
                                                | 
| 62 | 
            +
                assert_equal({ '_type'    => 'Model',
         | 
| 63 | 
            +
                               '_version' => 1,
         | 
| 64 | 
            +
                               'id'       => @model1.id,
         | 
| 65 | 
            +
                               'name'     => @model1.name,
         | 
| 66 | 
            +
                               'child' => { '_type' => 'Child',
         | 
| 67 | 
            +
                                               '_version' => 1,
         | 
| 68 | 
            +
                                               'id'       => @model1.child.id,
         | 
| 69 | 
            +
                                               'name'     => @model1.child.name } },
         | 
| 69 70 | 
             
                             view)
         | 
| 70 71 | 
             
              end
         | 
| 71 72 |  | 
| @@ -77,11 +78,11 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 77 78 |  | 
| 78 79 | 
             
                ModelView.deserialize_from_view(
         | 
| 79 80 | 
             
                  [update_hash_for(ModelView, @model1) { |p| p['child'] = update_hash_for(ChildView, t2) },
         | 
| 80 | 
            -
                   update_hash_for(ModelView, @model2) { |p| p['child'] = update_hash_for(ChildView, t1) }],
         | 
| 81 | 
            +
                   update_hash_for(ModelView, @model2) { |p| p['child'] = update_hash_for(ChildView, t1) },],
         | 
| 81 82 | 
             
                  deserialize_context: deserialize_context)
         | 
| 82 83 |  | 
| 83 84 | 
             
                assert_equal(Set.new([ViewModel::Reference.new(ModelView, @model1.id),
         | 
| 84 | 
            -
                                      ViewModel::Reference.new(ModelView, @model2.id)]),
         | 
| 85 | 
            +
                                      ViewModel::Reference.new(ModelView, @model2.id),]),
         | 
| 85 86 | 
             
                             deserialize_context.valid_edit_refs.to_set)
         | 
| 86 87 |  | 
| 87 88 | 
             
                @model1.reload
         | 
| @@ -100,7 +101,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 100 101 | 
             
              def test_has_one_create
         | 
| 101 102 | 
             
                @model1.update(child: nil)
         | 
| 102 103 |  | 
| 103 | 
            -
                alter_by_view!(ModelView, @model1) do |view,  | 
| 104 | 
            +
                alter_by_view!(ModelView, @model1) do |view, _refs|
         | 
| 104 105 | 
             
                  view['child'] = { '_type' => 'Child', 'name' => 't' }
         | 
| 105 106 | 
             
                end
         | 
| 106 107 |  | 
| @@ -108,8 +109,8 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 108 109 | 
             
              end
         | 
| 109 110 |  | 
| 110 111 | 
             
              def test_has_one_update
         | 
| 111 | 
            -
                alter_by_view!(ModelView, @model1) do |view,  | 
| 112 | 
            -
                  view['child']['name'] =  | 
| 112 | 
            +
                alter_by_view!(ModelView, @model1) do |view, _refs|
         | 
| 113 | 
            +
                  view['child']['name'] = 'hello'
         | 
| 113 114 | 
             
                end
         | 
| 114 115 |  | 
| 115 116 | 
             
                assert_equal('hello', @model1.child.name)
         | 
| @@ -117,7 +118,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 117 118 |  | 
| 118 119 | 
             
              def test_has_one_destroy
         | 
| 119 120 | 
             
                old_child = @model1.child
         | 
| 120 | 
            -
                alter_by_view!(ModelView, @model1) do |view,  | 
| 121 | 
            +
                alter_by_view!(ModelView, @model1) do |view, _refs|
         | 
| 121 122 | 
             
                  view['child'] = nil
         | 
| 122 123 | 
             
                end
         | 
| 123 124 | 
             
                assert(Child.where(id: old_child.id).blank?)
         | 
| @@ -127,7 +128,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 127 128 | 
             
                old_model1_child = @model1.child
         | 
| 128 129 | 
             
                old_model2_child = @model2.child
         | 
| 129 130 |  | 
| 130 | 
            -
                alter_by_view!(ModelView, [@model1, @model2]) do |(p1, p2),  | 
| 131 | 
            +
                alter_by_view!(ModelView, [@model1, @model2]) do |(p1, p2), _refs|
         | 
| 131 132 | 
             
                  p2['child'] = p1['child']
         | 
| 132 133 | 
             
                  p1['child'] = nil
         | 
| 133 134 | 
             
                end
         | 
| @@ -179,8 +180,8 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 179 180 |  | 
| 180 181 | 
             
              def test_bad_single_association
         | 
| 181 182 | 
             
                view = {
         | 
| 182 | 
            -
                   | 
| 183 | 
            -
                   | 
| 183 | 
            +
                  '_type' => 'Model',
         | 
| 184 | 
            +
                  'child' => [],
         | 
| 184 185 | 
             
                }
         | 
| 185 186 | 
             
                ex = assert_raises(ViewModel::DeserializationError::InvalidSyntax) do
         | 
| 186 187 | 
             
                  ModelView.deserialize_from_view(view)
         | 
| @@ -190,7 +191,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 190 191 |  | 
| 191 192 | 
             
              describe 'owned reference child' do
         | 
| 192 193 | 
             
                def child_attributes
         | 
| 193 | 
            -
                  super.merge(viewmodel: ->( | 
| 194 | 
            +
                  super.merge(viewmodel: ->(_v) { root! })
         | 
| 194 195 | 
             
                end
         | 
| 195 196 |  | 
| 196 197 | 
             
                def new_model
         | 
| @@ -419,7 +420,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 419 420 | 
             
                end
         | 
| 420 421 |  | 
| 421 422 | 
             
                def test_renamed_roundtrip
         | 
| 422 | 
            -
                  alter_by_view!(ModelView, @model) do |view,  | 
| 423 | 
            +
                  alter_by_view!(ModelView, @model) do |view, _refs|
         | 
| 423 424 | 
             
                    assert_equal({ 'id'       => @model.child.id,
         | 
| 424 425 | 
             
                                   '_type'    => 'Child',
         | 
| 425 426 | 
             
                                   '_version' => 1,
         | 
| @@ -428,7 +429,7 @@ class ViewModel::ActiveRecord::HasOneTest < ActiveSupport::TestCase | |
| 428 429 | 
             
                    view['something_else']['name'] = 'child new name'
         | 
| 429 430 | 
             
                  end
         | 
| 430 431 |  | 
| 431 | 
            -
                  assert_equal('child new name', | 
| 432 | 
            +
                  assert_equal('child new name', @model.child.name)
         | 
| 432 433 | 
             
                end
         | 
| 433 434 | 
             
              end
         | 
| 434 435 |  |