@@ -528,3 +528,367 @@ test_that("VitessceConfig add_meta_coordination", {
528528 expect_true(" metaCoordinationScopes" %in% names(vc_list $ coordinationSpace ))
529529 expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ coordinationSpace ))
530530})
531+
532+ test_that(" VitessceConfig add_coordination_by_dict with hierarchical structure" , {
533+ vc <- VitessceConfig $ new(schema_version = " 1.0.16" , name = " Test config" )
534+
535+ # Test complex hierarchical coordination using available coordination types
536+ # Simulate the Python test structure with R-compatible types
537+ scopes <- vc $ add_coordination_by_dict(list (
538+ spatialLayers = CL(list (
539+ list (
540+ geneFilter = list (" BRCA1" , " TP53" ),
541+ spatialZoom = 2.5 ,
542+ cellFilter = CL(list (
543+ list (
544+ spatialTargetX = 100 ,
545+ cellSetColor = list (255 , 0 , 0 )
546+ ),
547+ list (
548+ spatialTargetX = 200 ,
549+ cellSetColor = list (0 , 255 , 0 )
550+ )
551+ ))
552+ )
553+ ))
554+ ))
555+
556+ vc_list <- vc $ to_list()
557+
558+ # Check that the hierarchical structure was created
559+ expect_true(" spatialLayers" %in% names(vc_list $ coordinationSpace ))
560+ expect_true(" geneFilter" %in% names(vc_list $ coordinationSpace ))
561+ expect_true(" spatialZoom" %in% names(vc_list $ coordinationSpace ))
562+ expect_true(" cellFilter" %in% names(vc_list $ coordinationSpace ))
563+ expect_true(" spatialTargetX" %in% names(vc_list $ coordinationSpace ))
564+ expect_true(" cellSetColor" %in% names(vc_list $ coordinationSpace ))
565+
566+ # Check that dummy values were set for list types
567+ spatial_layers_scope <- names(vc_list $ coordinationSpace $ spatialLayers )[1 ]
568+ expect_equal(vc_list $ coordinationSpace $ spatialLayers [[spatial_layers_scope ]], jsonlite :: unbox(" __dummy__" ))
569+
570+ # Check that regular values were set correctly
571+ zoom_scope <- names(vc_list $ coordinationSpace $ spatialZoom )[1 ]
572+ expect_equal(vc_list $ coordinationSpace $ spatialZoom [[zoom_scope ]], jsonlite :: unbox(2.5 ))
573+
574+ # Check gene filter list
575+ gene_scope <- names(vc_list $ coordinationSpace $ geneFilter )[1 ]
576+ expect_equal(vc_list $ coordinationSpace $ geneFilter [[gene_scope ]], list (" BRCA1" , " TP53" ))
577+
578+ # Check spatial target values
579+ x_scopes <- names(vc_list $ coordinationSpace $ spatialTargetX )
580+ expect_length(x_scopes , 2 )
581+ expect_equal(vc_list $ coordinationSpace $ spatialTargetX [[x_scopes [1 ]]], jsonlite :: unbox(100 ))
582+ expect_equal(vc_list $ coordinationSpace $ spatialTargetX [[x_scopes [2 ]]], jsonlite :: unbox(200 ))
583+
584+ # Check color values
585+ color_scopes <- names(vc_list $ coordinationSpace $ cellSetColor )
586+ expect_length(color_scopes , 2 )
587+ expect_equal(vc_list $ coordinationSpace $ cellSetColor [[color_scopes [1 ]]], list (255 , 0 , 0 ))
588+ expect_equal(vc_list $ coordinationSpace $ cellSetColor [[color_scopes [2 ]]], list (0 , 255 , 0 ))
589+ })
590+
591+ test_that(" VitessceConfig add_and_use_coordination_by_dict" , {
592+ vc <- VitessceConfig $ new(schema_version = " 1.0.16" , name = " My config" )
593+ dataset <- vc $ add_dataset(name = " My dataset" )
594+
595+ # Add coordination first
596+ color_scope_list <- vc $ add_coordination(" cellSetColor" )
597+ color_scope <- color_scope_list [[1 ]]
598+ color_scope $ set_value(list (255 , 0 , 0 ))
599+
600+ # Add hierarchical coordination using available R types
601+ scopes <- vc $ add_coordination_by_dict(list (
602+ spatialLayers = CL(list (
603+ list (
604+ geneFilter = list (" GENE1" , " GENE2" ),
605+ spatialZoom = 1.5 ,
606+ cellFilter = CL(list (
607+ list (
608+ spatialTargetX = 0 ,
609+ cellSetColor = list (0 , 255 , 0 )
610+ ),
611+ list (
612+ spatialTargetX = 1 ,
613+ cellSetColor = list (0 , 0 , 255 )
614+ )
615+ ))
616+ )
617+ )),
618+ cellHighlight = CL(list (
619+ list (
620+ geneSelection = list (" GENE3" ),
621+ spatialTargetY = 10 ,
622+ cellSetColor = color_scope
623+ )
624+ ))
625+ ))
626+
627+ spatial_view <- vc $ add_view(" spatial" , dataset = dataset )
628+ spatial_view $ use_coordination_by_dict(scopes )
629+
630+ vc_list <- vc $ to_list()
631+
632+ # Check dataset
633+ expect_equal(vc_list $ datasets [[1 ]]$ uid , " A" )
634+ expect_equal(vc_list $ datasets [[1 ]]$ name , " My dataset" )
635+
636+ # Check coordination space structure
637+ expect_true(" dataset" %in% names(vc_list $ coordinationSpace ))
638+ expect_true(" spatialLayers" %in% names(vc_list $ coordinationSpace ))
639+ expect_true(" geneFilter" %in% names(vc_list $ coordinationSpace ))
640+ expect_true(" spatialZoom" %in% names(vc_list $ coordinationSpace ))
641+ expect_true(" cellFilter" %in% names(vc_list $ coordinationSpace ))
642+ expect_true(" spatialTargetX" %in% names(vc_list $ coordinationSpace ))
643+ expect_true(" spatialTargetY" %in% names(vc_list $ coordinationSpace ))
644+ expect_true(" cellSetColor" %in% names(vc_list $ coordinationSpace ))
645+ expect_true(" cellHighlight" %in% names(vc_list $ coordinationSpace ))
646+ expect_true(" geneSelection" %in% names(vc_list $ coordinationSpace ))
647+
648+ # Check specific values
649+ expect_equal(vc_list $ coordinationSpace $ dataset [[" A" ]], jsonlite :: unbox(" A" ))
650+
651+ # Check that spatial layers has dummy value
652+ spatial_layers_scope <- names(vc_list $ coordinationSpace $ spatialLayers )[1 ]
653+ expect_equal(vc_list $ coordinationSpace $ spatialLayers [[spatial_layers_scope ]], jsonlite :: unbox(" __dummy__" ))
654+
655+ # Check zoom value
656+ zoom_scope <- names(vc_list $ coordinationSpace $ spatialZoom )[1 ]
657+ expect_equal(vc_list $ coordinationSpace $ spatialZoom [[zoom_scope ]], jsonlite :: unbox(1.5 ))
658+
659+ # Check that color scope value is shared
660+ color_scopes <- names(vc_list $ coordinationSpace $ cellSetColor )
661+ expect_true(any(sapply(color_scopes , function (scope ) {
662+ identical(vc_list $ coordinationSpace $ cellSetColor [[scope ]], list (255 , 0 , 0 ))
663+ })))
664+
665+ # Check layout - view should use the scopes
666+ expect_equal(vc_list $ layout [[1 ]]$ component , " spatial" )
667+ expect_true(" dataset" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
668+ expect_equal(vc_list $ layout [[1 ]]$ coordinationScopes $ dataset , " A" )
669+ })
670+
671+ test_that(" VitessceConfig use_meta_complex_coordination" , {
672+ vc <- VitessceConfig $ new(schema_version = " 1.0.16" , name = " My config" )
673+ dataset <- vc $ add_dataset(name = " My dataset" )
674+
675+ # Create complex hierarchical coordination structure
676+ scopes <- vc $ add_coordination_by_dict(list (
677+ spatialLayers = CL(list (
678+ list (
679+ geneFilter = list (" GENE_A" , " GENE_B" ),
680+ spatialZoom = 2.0 ,
681+ cellFilter = CL(list (
682+ list (
683+ spatialTargetX = 0 ,
684+ cellSetColor = list (255 , 0 , 0 )
685+ ),
686+ list (
687+ spatialTargetX = 1 ,
688+ cellSetColor = list (0 , 255 , 0 )
689+ )
690+ ))
691+ )
692+ )),
693+ cellHighlight = CL(list (
694+ list (
695+ geneSelection = list (" GENE_C" ),
696+ spatialTargetY = 5 ,
697+ cellSetColor = list (255 , 0 , 0 )
698+ )
699+ ))
700+ ))
701+
702+ meta_coordination_scope <- vc $ add_meta_coordination()
703+ meta_coordination_scope $ use_coordination_by_dict(scopes )
704+
705+ spatial_view <- vc $ add_view(" spatial" , dataset = dataset )
706+ lc_view <- vc $ add_view(" layerController" , dataset = dataset )
707+
708+ spatial_view $ use_meta_coordination(meta_coordination_scope )
709+ lc_view $ use_meta_coordination(meta_coordination_scope )
710+
711+ vc_list <- vc $ to_list()
712+
713+ # Check basic structure
714+ expect_equal(vc_list $ version , " 1.0.16" )
715+ expect_equal(vc_list $ name , " My config" )
716+ expect_equal(vc_list $ datasets [[1 ]]$ uid , " A" )
717+ expect_equal(vc_list $ datasets [[1 ]]$ name , " My dataset" )
718+
719+ # Check coordination space
720+ expect_true(" dataset" %in% names(vc_list $ coordinationSpace ))
721+ expect_true(" spatialLayers" %in% names(vc_list $ coordinationSpace ))
722+ expect_true(" geneFilter" %in% names(vc_list $ coordinationSpace ))
723+ expect_true(" spatialZoom" %in% names(vc_list $ coordinationSpace ))
724+ expect_true(" cellFilter" %in% names(vc_list $ coordinationSpace ))
725+ expect_true(" spatialTargetX" %in% names(vc_list $ coordinationSpace ))
726+ expect_true(" spatialTargetY" %in% names(vc_list $ coordinationSpace ))
727+ expect_true(" cellSetColor" %in% names(vc_list $ coordinationSpace ))
728+ expect_true(" cellHighlight" %in% names(vc_list $ coordinationSpace ))
729+ expect_true(" geneSelection" %in% names(vc_list $ coordinationSpace ))
730+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ coordinationSpace ))
731+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ coordinationSpace ))
732+
733+ # Check meta coordination structure
734+ meta_scope_names <- names(vc_list $ coordinationSpace $ metaCoordinationScopes )
735+ expect_length(meta_scope_names , 1 )
736+ meta_scope_content <- vc_list $ coordinationSpace $ metaCoordinationScopes [[meta_scope_names [1 ]]]
737+ expect_true(" spatialLayers" %in% names(meta_scope_content ))
738+ expect_true(" cellHighlight" %in% names(meta_scope_content ))
739+
740+ # Check that views use meta coordination
741+ expect_equal(vc_list $ layout [[1 ]]$ component , " spatial" )
742+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
743+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
744+
745+ expect_equal(vc_list $ layout [[2 ]]$ component , " layerController" )
746+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[2 ]]$ coordinationScopes ))
747+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ layout [[2 ]]$ coordinationScopes ))
748+ })
749+
750+ test_that(" VitessceConfig link_views_by_dict complex hierarchical" , {
751+ vc <- VitessceConfig $ new(schema_version = " 1.0.16" , name = " My config" )
752+ dataset <- vc $ add_dataset(name = " My dataset" )
753+
754+ spatial_view <- vc $ add_view(" spatial" , dataset = dataset )
755+ lc_view <- vc $ add_view(" layerController" , dataset = dataset )
756+
757+ # Use complex hierarchical coordination linking
758+ vc $ link_views_by_dict(list (spatial_view , lc_view ), list (
759+ spatialLayers = CL(list (
760+ list (
761+ geneFilter = list (" GENE_1" , " GENE_2" ),
762+ spatialZoom = 3.0 ,
763+ cellFilter = CL(list (
764+ list (
765+ spatialTargetX = 0 ,
766+ cellSetColor = list (255 , 0 , 0 )
767+ ),
768+ list (
769+ spatialTargetX = 1 ,
770+ cellSetColor = list (0 , 255 , 0 )
771+ )
772+ ))
773+ )
774+ )),
775+ cellHighlight = CL(list (
776+ list (
777+ geneSelection = list (" GENE_3" ),
778+ spatialTargetY = 0 ,
779+ cellSetColor = list (255 , 0 , 0 )
780+ )
781+ ))
782+ ))
783+
784+ vc_list <- vc $ to_list()
785+
786+ # Check structure matches expected format
787+ expect_equal(vc_list $ version , " 1.0.16" )
788+ expect_equal(vc_list $ name , " My config" )
789+ expect_equal(vc_list $ datasets [[1 ]]$ uid , " A" )
790+ expect_equal(vc_list $ datasets [[1 ]]$ name , " My dataset" )
791+
792+ # Check coordination space contains all expected types
793+ expect_true(" dataset" %in% names(vc_list $ coordinationSpace ))
794+ expect_true(" spatialLayers" %in% names(vc_list $ coordinationSpace ))
795+ expect_true(" geneFilter" %in% names(vc_list $ coordinationSpace ))
796+ expect_true(" spatialZoom" %in% names(vc_list $ coordinationSpace ))
797+ expect_true(" cellFilter" %in% names(vc_list $ coordinationSpace ))
798+ expect_true(" spatialTargetX" %in% names(vc_list $ coordinationSpace ))
799+ expect_true(" spatialTargetY" %in% names(vc_list $ coordinationSpace ))
800+ expect_true(" cellSetColor" %in% names(vc_list $ coordinationSpace ))
801+ expect_true(" cellHighlight" %in% names(vc_list $ coordinationSpace ))
802+ expect_true(" geneSelection" %in% names(vc_list $ coordinationSpace ))
803+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ coordinationSpace ))
804+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ coordinationSpace ))
805+
806+ # Check specific values
807+ zoom_scope <- names(vc_list $ coordinationSpace $ spatialZoom )[1 ]
808+ expect_equal(vc_list $ coordinationSpace $ spatialZoom [[zoom_scope ]], jsonlite :: unbox(3.0 ))
809+
810+ gene_filter_scope <- names(vc_list $ coordinationSpace $ geneFilter )[1 ]
811+ expect_equal(vc_list $ coordinationSpace $ geneFilter [[gene_filter_scope ]], list (" GENE_1" , " GENE_2" ))
812+
813+ # Check that both views use meta coordination
814+ expect_equal(vc_list $ layout [[1 ]]$ component , " spatial" )
815+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
816+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
817+
818+ expect_equal(vc_list $ layout [[2 ]]$ component , " layerController" )
819+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[2 ]]$ coordinationScopes ))
820+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ layout [[2 ]]$ coordinationScopes ))
821+ })
822+
823+ test_that(" VitessceConfig link_views_by_dict with scope_prefix" , {
824+ vc <- VitessceConfig $ new(schema_version = " 1.0.16" , name = " My config" )
825+ dataset <- vc $ add_dataset(name = " My dataset" )
826+
827+ spatial_view <- vc $ add_view(" spatial" , dataset = dataset )
828+ lc_view <- vc $ add_view(" layerController" , dataset = dataset )
829+
830+ # Test with scope prefix like Python test
831+ vc $ link_views_by_dict(list (spatial_view , lc_view ), list (
832+ spatialLayers = CL(list (
833+ list (
834+ spatialZoom = 1.0 ,
835+ cellFilter = CL(list (
836+ list (
837+ spatialTargetX = 0 ,
838+ cellSetColor = list (255 , 0 , 0 )
839+ ),
840+ list (
841+ spatialTargetX = 1 ,
842+ cellSetColor = list (0 , 255 , 0 )
843+ )
844+ ))
845+ )
846+ ))
847+ ), scope_prefix = " SOME_PREFIX_" )
848+
849+ vc_list <- vc $ to_list()
850+
851+ # Check structure
852+ expect_equal(vc_list $ version , " 1.0.16" )
853+ expect_equal(vc_list $ name , " My config" )
854+ expect_equal(vc_list $ datasets [[1 ]]$ uid , " A" )
855+ expect_equal(vc_list $ datasets [[1 ]]$ name , " My dataset" )
856+
857+ # Check coordination space with prefixes
858+ expect_true(" dataset" %in% names(vc_list $ coordinationSpace ))
859+ expect_true(" spatialLayers" %in% names(vc_list $ coordinationSpace ))
860+ expect_true(" spatialZoom" %in% names(vc_list $ coordinationSpace ))
861+ expect_true(" cellFilter" %in% names(vc_list $ coordinationSpace ))
862+ expect_true(" spatialTargetX" %in% names(vc_list $ coordinationSpace ))
863+ expect_true(" cellSetColor" %in% names(vc_list $ coordinationSpace ))
864+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ coordinationSpace ))
865+ expect_true(" metaCoordinationScopesBy" %in% names(vc_list $ coordinationSpace ))
866+
867+ # Check that scope names use the prefix
868+ spatial_layers_scopes <- names(vc_list $ coordinationSpace $ spatialLayers )
869+ expect_true(any(grepl(" ^SOME_PREFIX_" , spatial_layers_scopes )))
870+
871+ zoom_scopes <- names(vc_list $ coordinationSpace $ spatialZoom )
872+ expect_true(any(grepl(" ^SOME_PREFIX_" , zoom_scopes )))
873+
874+ x_target_scopes <- names(vc_list $ coordinationSpace $ spatialTargetX )
875+ expect_true(any(grepl(" ^SOME_PREFIX_" , x_target_scopes )))
876+
877+ color_scopes <- names(vc_list $ coordinationSpace $ cellSetColor )
878+ expect_true(any(grepl(" ^SOME_PREFIX_" , color_scopes )))
879+
880+ # Check meta coordination scope names use prefix
881+ meta_scopes <- names(vc_list $ coordinationSpace $ metaCoordinationScopes )
882+ expect_true(any(grepl(" ^SOME_PREFIX_" , meta_scopes )))
883+
884+ # Check that views use the prefixed meta coordination
885+ expect_equal(vc_list $ layout [[1 ]]$ component , " spatial" )
886+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[1 ]]$ coordinationScopes ))
887+ meta_scope_used <- vc_list $ layout [[1 ]]$ coordinationScopes $ metaCoordinationScopes [1 ]
888+ expect_true(grepl(" ^SOME_PREFIX_" , meta_scope_used ))
889+
890+ expect_equal(vc_list $ layout [[2 ]]$ component , " layerController" )
891+ expect_true(" metaCoordinationScopes" %in% names(vc_list $ layout [[2 ]]$ coordinationScopes ))
892+ meta_scope_used_2 <- vc_list $ layout [[2 ]]$ coordinationScopes $ metaCoordinationScopes [1 ]
893+ expect_true(grepl(" ^SOME_PREFIX_" , meta_scope_used_2 ))
894+ })
0 commit comments