iknow_view_models 2.10.1 → 3.0.0
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 +119 -0
- data/.travis.yml +31 -0
- data/Appraisals +6 -16
- data/gemfiles/{rails_7_0.gemfile → rails_6_0_beta.gemfile} +2 -2
- data/iknow_view_models.gemspec +3 -5
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model/active_record/association_data.rb +206 -92
- data/lib/view_model/active_record/association_manipulation.rb +22 -12
- data/lib/view_model/active_record/cache/cacheable_view.rb +3 -13
- data/lib/view_model/active_record/cache.rb +2 -2
- data/lib/view_model/active_record/cloner.rb +11 -11
- data/lib/view_model/active_record/controller.rb +0 -2
- data/lib/view_model/active_record/update_context.rb +21 -3
- data/lib/view_model/active_record/update_data.rb +43 -45
- data/lib/view_model/active_record/update_operation.rb +265 -153
- data/lib/view_model/active_record/visitor.rb +9 -6
- data/lib/view_model/active_record.rb +94 -74
- data/lib/view_model/after_transaction_runner.rb +3 -18
- data/lib/view_model/callbacks.rb +2 -2
- data/lib/view_model/changes.rb +24 -16
- data/lib/view_model/config.rb +6 -2
- data/lib/view_model/deserialization_error.rb +31 -0
- data/lib/view_model/deserialize_context.rb +2 -6
- data/lib/view_model/error_view.rb +6 -5
- data/lib/view_model/record/attribute_data.rb +11 -6
- data/lib/view_model/record.rb +44 -24
- data/lib/view_model/serialize_context.rb +2 -63
- data/lib/view_model/test_helpers/arvm_builder.rb +2 -4
- data/lib/view_model/traversal_context.rb +2 -2
- data/lib/view_model.rb +21 -13
- data/shell.nix +1 -1
- data/test/helpers/arvm_test_models.rb +4 -12
- data/test/helpers/arvm_test_utilities.rb +6 -0
- data/test/helpers/controller_test_helpers.rb +6 -6
- data/test/helpers/viewmodel_spec_helpers.rb +63 -52
- data/test/unit/view_model/access_control_test.rb +88 -37
- data/test/unit/view_model/active_record/belongs_to_test.rb +110 -178
- data/test/unit/view_model/active_record/cache_test.rb +11 -5
- data/test/unit/view_model/active_record/cloner_test.rb +1 -1
- data/test/unit/view_model/active_record/controller_test.rb +12 -20
- data/test/unit/view_model/active_record/has_many_test.rb +540 -316
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +12 -15
- data/test/unit/view_model/active_record/has_many_through_test.rb +15 -58
- data/test/unit/view_model/active_record/has_one_test.rb +288 -135
- data/test/unit/view_model/active_record/poly_test.rb +0 -1
- data/test/unit/view_model/active_record/shared_test.rb +21 -39
- data/test/unit/view_model/active_record/version_test.rb +3 -2
- data/test/unit/view_model/active_record_test.rb +5 -63
- data/test/unit/view_model/callbacks_test.rb +1 -0
- data/test/unit/view_model/record_test.rb +0 -32
- data/test/unit/view_model/traversal_context_test.rb +13 -12
- metadata +15 -25
- data/.github/workflows/gem-push.yml +0 -31
- data/.github/workflows/test.yml +0 -65
- data/gemfiles/rails_6_0.gemfile +0 -9
- data/gemfiles/rails_6_1.gemfile +0 -9
- data/test/unit/view_model/active_record/optional_attribute_view_test.rb +0 -58
@@ -190,6 +190,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
190
190
|
end
|
191
191
|
|
192
192
|
define_viewmodel do
|
193
|
+
root!
|
193
194
|
attribute :val
|
194
195
|
association :tree2
|
195
196
|
|
@@ -215,7 +216,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
215
216
|
|
216
217
|
define_viewmodel do
|
217
218
|
attribute :val
|
218
|
-
association :tree1
|
219
|
+
association :tree1
|
219
220
|
end
|
220
221
|
end
|
221
222
|
end
|
@@ -447,15 +448,16 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
447
448
|
include ViewModelSpecHelpers::List
|
448
449
|
extend Minitest::Spec::DSL
|
449
450
|
|
450
|
-
def assert_changes_match(changes,
|
451
|
+
def assert_changes_match(changes, n: false, d: false, nstc: false, refc: false, att: [], ass: [])
|
451
452
|
assert_equal(
|
452
453
|
changes,
|
453
454
|
ViewModel::Changes.new(
|
454
|
-
new:
|
455
|
-
deleted:
|
456
|
-
|
457
|
-
|
458
|
-
|
455
|
+
new: n,
|
456
|
+
deleted: d,
|
457
|
+
changed_nested_children: nstc,
|
458
|
+
changed_referenced_children: refc,
|
459
|
+
changed_attributes: att,
|
460
|
+
changed_associations: ass))
|
459
461
|
end
|
460
462
|
|
461
463
|
describe 'with parent and points-to child test models' do
|
@@ -479,7 +481,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
479
481
|
vm = viewmodel_class.deserialize_from_view(view, deserialize_context: ctx)
|
480
482
|
|
481
483
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
482
|
-
assert_changes_match(vm_changes, true,
|
484
|
+
assert_changes_match(vm_changes, n: true, att: ['name'])
|
483
485
|
end
|
484
486
|
|
485
487
|
it 'records a destroyed model' do
|
@@ -489,7 +491,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
489
491
|
vm.destroy!(deserialize_context: ctx)
|
490
492
|
|
491
493
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
492
|
-
assert_changes_match(vm_changes,
|
494
|
+
assert_changes_match(vm_changes, d: true)
|
493
495
|
end
|
494
496
|
|
495
497
|
it 'records a change to an attribute' do
|
@@ -498,7 +500,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
498
500
|
end
|
499
501
|
|
500
502
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
501
|
-
assert_changes_match(vm_changes,
|
503
|
+
assert_changes_match(vm_changes, att: ['name'])
|
502
504
|
end
|
503
505
|
|
504
506
|
it 'records a new child' do
|
@@ -507,10 +509,10 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
507
509
|
end
|
508
510
|
|
509
511
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
510
|
-
assert_changes_match(vm_changes,
|
512
|
+
assert_changes_match(vm_changes, nstc: true, ass: ['child'])
|
511
513
|
|
512
514
|
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
513
|
-
assert_changes_match(c_changes, true,
|
515
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
514
516
|
end
|
515
517
|
|
516
518
|
it 'records a replaced child' do
|
@@ -522,14 +524,14 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
522
524
|
end
|
523
525
|
|
524
526
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
525
|
-
assert_changes_match(vm_changes,
|
527
|
+
assert_changes_match(vm_changes, nstc: true, ass: ['child'])
|
526
528
|
|
527
529
|
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
528
|
-
assert_changes_match(c_changes, true,
|
530
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
529
531
|
|
530
532
|
oc_changes = ctx.valid_edit_changes(
|
531
533
|
ViewModel::Reference.new(child_viewmodel_class, old_child.id))
|
532
|
-
assert_changes_match(oc_changes,
|
534
|
+
assert_changes_match(oc_changes, d: true)
|
533
535
|
end
|
534
536
|
|
535
537
|
it 'records an edited child' do
|
@@ -542,10 +544,10 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
542
544
|
# The parent node itself wasn't changed, so must not have been
|
543
545
|
# valid_edit checked
|
544
546
|
refute(ctx.was_edited?(vm.to_reference))
|
545
|
-
assert_changes_match(vm.previous_changes,
|
547
|
+
assert_changes_match(vm.previous_changes, nstc: true)
|
546
548
|
|
547
549
|
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
548
|
-
assert_changes_match(c_changes,
|
550
|
+
assert_changes_match(c_changes, att: ['name'])
|
549
551
|
end
|
550
552
|
|
551
553
|
it 'records a deleted child' do
|
@@ -557,11 +559,11 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
557
559
|
end
|
558
560
|
|
559
561
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
560
|
-
assert_changes_match(vm_changes,
|
562
|
+
assert_changes_match(vm_changes, nstc: true, ass: ['child'])
|
561
563
|
|
562
564
|
oc_changes = ctx.valid_edit_changes(
|
563
565
|
ViewModel::Reference.new(child_viewmodel_class, old_child.id))
|
564
|
-
assert_changes_match(oc_changes,
|
566
|
+
assert_changes_match(oc_changes, d: true)
|
565
567
|
end
|
566
568
|
end
|
567
569
|
|
@@ -585,7 +587,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
585
587
|
end
|
586
588
|
|
587
589
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
588
|
-
assert_changes_match(vm_changes,
|
590
|
+
assert_changes_match(vm_changes, nstc: true, ass: ['children'])
|
589
591
|
|
590
592
|
new_children, existing_children = vm.children.partition do |c|
|
591
593
|
c.name < 'm'
|
@@ -593,7 +595,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
593
595
|
|
594
596
|
new_children.each do |c|
|
595
597
|
c_changes = ctx.valid_edit_changes(c.to_reference)
|
596
|
-
assert_changes_match(c_changes, true,
|
598
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
597
599
|
end
|
598
600
|
|
599
601
|
existing_children.each do |c|
|
@@ -613,15 +615,15 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
613
615
|
refute(vm.children.include?(replaced_child))
|
614
616
|
|
615
617
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
616
|
-
assert_changes_match(vm_changes,
|
618
|
+
assert_changes_match(vm_changes, nstc: true, ass: ['children'])
|
617
619
|
|
618
620
|
new_child = vm.children.detect { |c| c.name == 'b' }
|
619
621
|
c_changes = ctx.valid_edit_changes(new_child.to_reference)
|
620
|
-
assert_changes_match(c_changes, true,
|
622
|
+
assert_changes_match(c_changes, n:true, att: ['name'])
|
621
623
|
|
622
624
|
oc_changes = ctx.valid_edit_changes(
|
623
625
|
ViewModel::Reference.new(child_viewmodel_class, replaced_child.id))
|
624
|
-
assert_changes_match(oc_changes,
|
626
|
+
assert_changes_match(oc_changes, d: true)
|
625
627
|
end
|
626
628
|
|
627
629
|
it 'records reordered children' do
|
@@ -630,7 +632,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
630
632
|
end
|
631
633
|
|
632
634
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
633
|
-
assert_changes_match(vm_changes,
|
635
|
+
assert_changes_match(vm_changes, ass: ['children'])
|
634
636
|
|
635
637
|
vm.children.each do |c|
|
636
638
|
refute(ctx.was_edited?(c.to_reference))
|
@@ -639,23 +641,23 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
639
641
|
end
|
640
642
|
|
641
643
|
describe 'with parent and shared child test models' do
|
642
|
-
include ViewModelSpecHelpers::
|
644
|
+
include ViewModelSpecHelpers::ParentAndSharedBelongsToChild
|
643
645
|
|
644
646
|
def new_model
|
645
647
|
model_class.new(name: 'a', child: child_model_class.new(name: 'z'))
|
646
648
|
end
|
647
649
|
|
648
|
-
it 'records
|
650
|
+
it 'records a change to child without a tree change' do
|
649
651
|
vm, ctx = alter_by_view!(viewmodel_class, create_model!) do |view, refs|
|
650
652
|
view['child'] = { '_ref' => 'cref' }
|
651
653
|
refs.clear['cref'] = { '_type' => child_view_name, 'name' => 'b' }
|
652
654
|
end
|
653
655
|
|
654
656
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
655
|
-
assert_changes_match(vm_changes,
|
657
|
+
assert_changes_match(vm_changes, ass: ['child'])
|
656
658
|
|
657
659
|
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
658
|
-
assert_changes_match(c_changes, true,
|
660
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
659
661
|
end
|
660
662
|
|
661
663
|
it 'records an edited child without a tree change' do
|
@@ -664,10 +666,10 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
664
666
|
end
|
665
667
|
|
666
668
|
refute(ctx.was_edited?(vm.to_reference))
|
667
|
-
assert_changes_match(vm.previous_changes
|
669
|
+
assert_changes_match(vm.previous_changes)
|
668
670
|
|
669
671
|
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
670
|
-
assert_changes_match(c_changes,
|
672
|
+
assert_changes_match(c_changes, att: ['name'])
|
671
673
|
end
|
672
674
|
|
673
675
|
it 'records a deleted child' do
|
@@ -680,12 +682,61 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
680
682
|
end
|
681
683
|
|
682
684
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
683
|
-
assert_changes_match(vm_changes,
|
685
|
+
assert_changes_match(vm_changes, ass: ['child'])
|
684
686
|
|
685
687
|
refute(ctx.was_edited?(old_child.to_reference))
|
686
688
|
end
|
687
689
|
end
|
688
690
|
|
691
|
+
describe 'with parent and owned referenced child test models' do
|
692
|
+
include ViewModelSpecHelpers::ParentAndReferencedHasOneChild
|
693
|
+
|
694
|
+
def new_model
|
695
|
+
model_class.new(name: 'a', child: child_model_class.new(name: 'z'))
|
696
|
+
end
|
697
|
+
|
698
|
+
it 'records a change to child with referenced tree change' do
|
699
|
+
vm, ctx = alter_by_view!(viewmodel_class, create_model!) do |view, refs|
|
700
|
+
view['child'] = { '_ref' => 'cref' }
|
701
|
+
refs.clear['cref'] = { '_type' => child_view_name, 'name' => 'b' }
|
702
|
+
end
|
703
|
+
|
704
|
+
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
705
|
+
assert_changes_match(vm_changes, refc: true, ass: ['child'])
|
706
|
+
|
707
|
+
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
708
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
709
|
+
end
|
710
|
+
|
711
|
+
it 'records an edited child with referenced tree change' do
|
712
|
+
vm, ctx = alter_by_view!(viewmodel_class, create_model!) do |_view, refs|
|
713
|
+
refs.values.first.merge!('name' => 'b')
|
714
|
+
end
|
715
|
+
|
716
|
+
refute(ctx.was_edited?(vm.to_reference))
|
717
|
+
assert_changes_match(vm.previous_changes, refc: true)
|
718
|
+
|
719
|
+
c_changes = ctx.valid_edit_changes(vm.child.to_reference)
|
720
|
+
assert_changes_match(c_changes, att: ['name'])
|
721
|
+
end
|
722
|
+
|
723
|
+
it 'records a deleted child' do
|
724
|
+
vm = create_viewmodel!
|
725
|
+
old_child = vm.child
|
726
|
+
|
727
|
+
vm, ctx = alter_by_view!(viewmodel_class, vm.model) do |view, refs|
|
728
|
+
view['child'] = nil
|
729
|
+
refs.clear
|
730
|
+
end
|
731
|
+
|
732
|
+
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
733
|
+
assert_changes_match(vm_changes, refc: true, ass: ['child'])
|
734
|
+
|
735
|
+
c_changes = ctx.valid_edit_changes(old_child.to_reference)
|
736
|
+
assert_changes_match(c_changes, d: true)
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
689
740
|
describe 'with has_many_through children test models' do
|
690
741
|
include ViewModelSpecHelpers::ParentAndHasManyThroughChildren
|
691
742
|
|
@@ -706,7 +757,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
706
757
|
end
|
707
758
|
|
708
759
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
709
|
-
assert_changes_match(vm_changes,
|
760
|
+
assert_changes_match(vm_changes, ass: ['children'])
|
710
761
|
|
711
762
|
new_children, existing_children = vm.children.partition do |c|
|
712
763
|
c.name < 'm'
|
@@ -714,7 +765,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
714
765
|
|
715
766
|
new_children.each do |c|
|
716
767
|
c_changes = ctx.valid_edit_changes(c.to_reference)
|
717
|
-
assert_changes_match(c_changes, true,
|
768
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
718
769
|
end
|
719
770
|
|
720
771
|
existing_children.each do |c|
|
@@ -734,7 +785,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
734
785
|
end
|
735
786
|
|
736
787
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
737
|
-
assert_changes_match(vm_changes,
|
788
|
+
assert_changes_match(vm_changes, ass: ['children'])
|
738
789
|
|
739
790
|
new_children, existing_children = vm.children.partition do |c|
|
740
791
|
c.name < 'm'
|
@@ -742,7 +793,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
742
793
|
|
743
794
|
new_children.each do |c|
|
744
795
|
c_changes = ctx.valid_edit_changes(c.to_reference)
|
745
|
-
assert_changes_match(c_changes, true,
|
796
|
+
assert_changes_match(c_changes, n: true, att: ['name'])
|
746
797
|
end
|
747
798
|
|
748
799
|
existing_children.each do |c|
|
@@ -758,7 +809,7 @@ class ViewModel::AccessControlTest < ActiveSupport::TestCase
|
|
758
809
|
end
|
759
810
|
|
760
811
|
vm_changes = ctx.valid_edit_changes(vm.to_reference)
|
761
|
-
assert_changes_match(vm_changes,
|
812
|
+
assert_changes_match(vm_changes, ass: ['children'])
|
762
813
|
|
763
814
|
vm.children.each do |c|
|
764
815
|
refute(ctx.was_edited?(c.to_reference))
|