@@ -185,6 +185,11 @@ public override TestTreeNode SelectedNode
185185 }
186186 }
187187
188+ public new void ToggleNodeChecked ( int idx , TestTreeNode node )
189+ {
190+ base . ToggleNodeChecked ( idx , node ) ;
191+ }
192+
188193 protected override List < TestTreeNode > Nodes
189194 {
190195 get
@@ -606,6 +611,211 @@ public void ShouldPopulateTreeWithSingleEntryWithMetaInPath()
606611 }
607612 } ) ;
608613 }
614+
615+ [ Test ]
616+ public void ShouldCheckParentOfMetaFile ( )
617+ {
618+ var testTree = new TestTree ( true ) ;
619+ var testTreeListener = testTree . TestTreeListener ;
620+
621+ testTreeListener . GetCollapsedFolders ( ) . Returns ( new string [ 0 ] ) ;
622+ testTreeListener . SelectedNode . Returns ( ( TestTreeNode ) null ) ;
623+ testTreeListener . GetCheckedFiles ( ) . Returns ( new string [ 0 ] ) ;
624+ testTreeListener . Nodes . Returns ( new List < TestTreeNode > ( ) ) ;
625+ testTreeListener . PathSeparator . Returns ( @"\" ) ;
626+ testTreeListener . DisplayRootNode . Returns ( true ) ;
627+ testTreeListener . IsSelectable . Returns ( false ) ;
628+ testTreeListener . Title . Returns ( "Test Tree" ) ;
629+ testTreeListener . PromoteMetaFiles . Returns ( true ) ;
630+
631+ var testTreeData = new [ ] {
632+ new TestTreeData {
633+ Path = "Folder\\ Default Scene.unity"
634+ } ,
635+ new TestTreeData {
636+ Path = "Folder\\ Default Scene.unity.meta"
637+ }
638+ } ;
639+ testTree . Load ( testTreeData ) ;
640+
641+ testTree . CreatedTreeNodes . ShouldAllBeEquivalentTo ( new [ ] {
642+ new TestTreeNode {
643+ Path = "Test Tree" ,
644+ Label = "Test Tree" ,
645+ IsFolder = true
646+ } ,
647+ new TestTreeNode {
648+ Path = "Folder" ,
649+ Label = "Folder" ,
650+ Level = 1 ,
651+ IsFolder = true
652+ } ,
653+ new TestTreeNode {
654+ Path = "Folder\\ Default Scene.unity" ,
655+ Label = "Default Scene.unity" ,
656+ Level = 2 ,
657+ TreeData = testTreeData [ 0 ] ,
658+ IsContainer = true
659+ } ,
660+ new TestTreeNode {
661+ Path = "Folder\\ Default Scene.unity.meta" ,
662+ Label = "Default Scene.unity.meta" ,
663+ Level = 3 ,
664+ TreeData = testTreeData [ 1 ]
665+ }
666+ } ) ;
667+
668+ var sceneNode = testTree . CreatedTreeNodes [ 2 ] ;
669+ var sceneMetaNode = testTree . CreatedTreeNodes [ 3 ] ;
670+
671+ Assert . AreEqual ( CheckState . Empty , sceneNode . CheckState ) ;
672+ Assert . AreEqual ( CheckState . Empty , sceneMetaNode . CheckState ) ;
673+
674+ testTree . ToggleNodeChecked ( 3 , sceneMetaNode ) ;
675+
676+ Assert . AreEqual ( CheckState . Checked , sceneNode . CheckState ) ;
677+ Assert . AreEqual ( CheckState . Checked , sceneMetaNode . CheckState ) ;
678+
679+ testTreeListener . Received ( 2 ) . AddCheckedNode ( Arg . Any < TestTreeNode > ( ) ) ;
680+ }
681+
682+ [ Test ]
683+ public void ShouldRippleChecksCorrectly ( )
684+ {
685+ var testTree = new TestTree ( true ) ;
686+ var testTreeListener = testTree . TestTreeListener ;
687+
688+ testTreeListener . GetCollapsedFolders ( ) . Returns ( new string [ 0 ] ) ;
689+ testTreeListener . SelectedNode . Returns ( ( TestTreeNode ) null ) ;
690+ testTreeListener . GetCheckedFiles ( ) . Returns ( new string [ 0 ] ) ;
691+ testTreeListener . Nodes . Returns ( new List < TestTreeNode > ( ) ) ;
692+ testTreeListener . PathSeparator . Returns ( @"\" ) ;
693+ testTreeListener . DisplayRootNode . Returns ( true ) ;
694+ testTreeListener . IsSelectable . Returns ( false ) ;
695+ testTreeListener . Title . Returns ( "Test Tree" ) ;
696+ testTreeListener . PromoteMetaFiles . Returns ( true ) ;
697+
698+ var testTreeData = new [ ] {
699+ new TestTreeData {
700+ Path = "Root\\ Parent\\ A.txt"
701+ } ,
702+ new TestTreeData {
703+ Path = "Root\\ Parent\\ B.txt"
704+ } ,
705+ new TestTreeData {
706+ Path = "Root\\ Parent\\ C.txt"
707+ }
708+ } ;
709+
710+ testTree . Load ( testTreeData ) ;
711+
712+ testTree . CreatedTreeNodes . ShouldAllBeEquivalentTo ( new [ ] {
713+ new TestTreeNode {
714+ Path = "Test Tree" ,
715+ Label = "Test Tree" ,
716+ IsFolder = true
717+ } ,
718+ new TestTreeNode {
719+ Path = "Root" ,
720+ Label = "Root" ,
721+ Level = 1 ,
722+ IsFolder = true
723+ } ,
724+ new TestTreeNode {
725+ Path = "Root\\ Parent" ,
726+ Label = "Parent" ,
727+ Level = 2 ,
728+ IsFolder = true
729+ } ,
730+ new TestTreeNode {
731+ Path = "Root\\ Parent\\ A.txt" ,
732+ Label = "A.txt" ,
733+ Level = 3 ,
734+ TreeData = testTreeData [ 0 ] ,
735+ } ,
736+ new TestTreeNode {
737+ Path = "Root\\ Parent\\ B.txt" ,
738+ Label = "B.txt" ,
739+ Level = 3 ,
740+ TreeData = testTreeData [ 1 ] ,
741+ } ,
742+ new TestTreeNode {
743+ Path = "Root\\ Parent\\ C.txt" ,
744+ Label = "C.txt" ,
745+ Level = 3 ,
746+ TreeData = testTreeData [ 2 ] ,
747+ }
748+ } ) ;
749+
750+ var rootNode = testTree . CreatedTreeNodes [ 1 ] ;
751+ var parentNode = testTree . CreatedTreeNodes [ 2 ] ;
752+ var aNode = testTree . CreatedTreeNodes [ 3 ] ;
753+ var bNode = testTree . CreatedTreeNodes [ 4 ] ;
754+ var cNode = testTree . CreatedTreeNodes [ 5 ] ;
755+
756+ // Initial state, everything unchecked
757+
758+ Assert . AreEqual ( CheckState . Empty , rootNode . CheckState ) ;
759+ Assert . AreEqual ( CheckState . Empty , parentNode . CheckState ) ;
760+ Assert . AreEqual ( CheckState . Empty , aNode . CheckState ) ;
761+ Assert . AreEqual ( CheckState . Empty , bNode . CheckState ) ;
762+ Assert . AreEqual ( CheckState . Empty , cNode . CheckState ) ;
763+
764+ testTree . ToggleNodeChecked ( 1 , rootNode ) ;
765+
766+ // Checked the root node, everything checked
767+
768+ Assert . AreEqual ( CheckState . Checked , rootNode . CheckState ) ;
769+ Assert . AreEqual ( CheckState . Checked , parentNode . CheckState ) ;
770+ Assert . AreEqual ( CheckState . Checked , aNode . CheckState ) ;
771+ Assert . AreEqual ( CheckState . Checked , bNode . CheckState ) ;
772+ Assert . AreEqual ( CheckState . Checked , cNode . CheckState ) ;
773+
774+ testTreeListener . Received ( 3 ) . AddCheckedNode ( Arg . Any < TestTreeNode > ( ) ) ;
775+ testTreeListener . ClearReceivedCalls ( ) ;
776+
777+ // Unchecked c.txt, c.txt unchecked, parents mixed
778+
779+ testTree . ToggleNodeChecked ( 5 , cNode ) ;
780+
781+ Assert . AreEqual ( CheckState . Mixed , rootNode . CheckState ) ;
782+ Assert . AreEqual ( CheckState . Mixed , parentNode . CheckState ) ;
783+ Assert . AreEqual ( CheckState . Checked , aNode . CheckState ) ;
784+ Assert . AreEqual ( CheckState . Checked , bNode . CheckState ) ;
785+ Assert . AreEqual ( CheckState . Empty , cNode . CheckState ) ;
786+
787+ testTreeListener . Received ( 1 ) . RemoveCheckedNode ( Arg . Any < TestTreeNode > ( ) ) ;
788+ testTreeListener . ClearReceivedCalls ( ) ;
789+
790+ testTree . ToggleNodeChecked ( 5 , cNode ) ;
791+
792+ // Checked c.txt, everything checked
793+
794+ Assert . AreEqual ( CheckState . Checked , rootNode . CheckState ) ;
795+ Assert . AreEqual ( CheckState . Checked , parentNode . CheckState ) ;
796+ Assert . AreEqual ( CheckState . Checked , aNode . CheckState ) ;
797+ Assert . AreEqual ( CheckState . Checked , bNode . CheckState ) ;
798+ Assert . AreEqual ( CheckState . Checked , cNode . CheckState ) ;
799+
800+ testTreeListener . Received ( 1 ) . AddCheckedNode ( Arg . Any < TestTreeNode > ( ) ) ;
801+ testTreeListener . ClearReceivedCalls ( ) ;
802+
803+ // Unchecked a.txt b.txt and c.txt, everything checked
804+
805+ testTree . ToggleNodeChecked ( 3 , aNode ) ;
806+ testTree . ToggleNodeChecked ( 4 , bNode ) ;
807+ testTree . ToggleNodeChecked ( 5 , cNode ) ;
808+
809+ Assert . AreEqual ( CheckState . Empty , rootNode . CheckState ) ;
810+ Assert . AreEqual ( CheckState . Empty , parentNode . CheckState ) ;
811+ Assert . AreEqual ( CheckState . Empty , aNode . CheckState ) ;
812+ Assert . AreEqual ( CheckState . Empty , bNode . CheckState ) ;
813+ Assert . AreEqual ( CheckState . Empty , cNode . CheckState ) ;
814+
815+ testTreeListener . Received ( 3 ) . RemoveCheckedNode ( Arg . Any < TestTreeNode > ( ) ) ;
816+ testTreeListener . ClearReceivedCalls ( ) ;
817+ }
818+
609819 [ Test ]
610820 public void ShouldPopulateTreeWithSingleEntryWithNonPromotedMetaInPath ( )
611821 {
0 commit comments