iknow_view_models 2.10.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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))
|