def test_config_add_dataset(self):
        vc = VitessceConfig()
        my_dataset = vc.add_dataset(name='My Dataset')

        vc_dict = vc.to_dict()
        vc_json = json.dumps(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version": "1.0.4",
                "name": "",
                "description": "",
                "datasets": [{
                    'uid': 'A',
                    'name': 'My Dataset',
                    'files': []
                }],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                },
                "layout": [],
                "initStrategy": "auto"
            })
    def test_config_add_dataset_add_files(self):
        vc = VitessceConfig()
        my_dataset = (vc.add_dataset(name='My Chained Dataset').add_file(
            url="http://example.com/cells.json",
            data_type=dt.CELLS,
            file_type=ft.CELLS_JSON,
        ).add_file(
            url="http://example.com/cell_sets.json",
            data_type=dt.CELL_SETS,
            file_type=ft.CELL_SETS_JSON,
        ))

        vc_dict = vc.to_dict()
        vc_json = json.dumps(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version":
                "1.0.4",
                "name":
                "",
                "description":
                "",
                "datasets": [
                    {
                        'uid':
                        'A',
                        'name':
                        'My Chained Dataset',
                        'files': [{
                            'url': 'http://example.com/cells.json',
                            'type': 'cells',
                            'fileType': 'cells.json'
                        }, {
                            'url': 'http://example.com/cell_sets.json',
                            'type': 'cell-sets',
                            'fileType': 'cell-sets.json'
                        }]
                    },
                ],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                },
                "layout": [],
                "initStrategy":
                "auto"
            })
def buildVitessceConfig(adata, area_name):
    vc = VitessceConfig("Developing human neocortex: gestational week 20")
    dataset = vc.add_dataset(area_name).add_object(
        # The`add_object()` function converts the AnnData data structure into a [Zarr]
        # (https://zarr.readthedocs.io/en/stable/) store that is compatible with Vitessce.
        AnnDataWrapper(adata,
                       mappings_obsm=["X_tsne"],
                       mappings_obsm_names=["t-SNE"],
                       expression_matrix="X",
                       spatial_centroid_obsm="X_spatial"))
    spatial_plot = vc.add_view(dataset, cm.SPATIAL)
    tsne_plot = vc.add_view(dataset, cm.SCATTERPLOT, mapping="t-SNE")
    heatmap = vc.add_view(dataset, cm.HEATMAP)
    genes_list = vc.add_view(dataset, cm.GENES)
    vc.layout((spatial_plot | tsne_plot) / (heatmap | genes_list))
    return vc
    def test_config_add_scatterplot_view_with_mapping(self):
        vc = VitessceConfig()
        my_dataset = vc.add_dataset(name='My Dataset')

        my_view = vc.add_view(cm.SCATTERPLOT,
                              dataset=my_dataset,
                              mapping="X_umap")

        vc_dict = vc.to_dict()
        vc_json = json.dumps(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version":
                "1.0.4",
                "name":
                "",
                "description":
                "",
                "datasets": [{
                    'uid': 'A',
                    'name': 'My Dataset',
                    'files': []
                }],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                    'embeddingType': {
                        'A': 'X_umap'
                    }
                },
                "layout": [{
                    'component': 'scatterplot',
                    'coordinationScopes': {
                        'dataset': 'A',
                        'embeddingType': 'A'
                    },
                    'h': 1,
                    'w': 1,
                    'x': 0,
                    'y': 0
                }],
                "initStrategy":
                "auto"
            })
    def test_config_set_layout_single_view(self):
        vc = VitessceConfig()
        my_dataset = vc.add_dataset(name='My Dataset')
        my_view = vc.add_view(cm.SPATIAL, dataset=my_dataset)
        vc.layout(my_view)

        vc_dict = vc.to_dict()
        vc_json = json.dumps(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version":
                "1.0.4",
                "name":
                "",
                "description":
                "",
                "datasets": [{
                    'uid': 'A',
                    'name': 'My Dataset',
                    'files': []
                }],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                },
                "layout": [{
                    'component': 'spatial',
                    'coordinationScopes': {
                        'dataset': 'A',
                    },
                    'x': 0,
                    'y': 0,
                    'h': 12,
                    'w': 12,
                }],
                "initStrategy":
                "auto"
            })
    def test_config_to_python_with_data_objects(self):
        vc = VitessceConfig()

        class MockWrapperA(AbstractWrapper):
            def __init__(self, name, **kwargs):
                super().__init__(**kwargs)
                self._repr = make_repr(locals())
                self.name = name

            def convert_and_save(self, dataset_uid, obj_i):
                def get_molecules(base_url):
                    return {
                        "url": f"{base_url}/molecules",
                        "type": "molecules",
                        "fileType": "molecules.json"
                    }

                def get_cells(base_url):
                    return {
                        "url": f"{base_url}/cells",
                        "type": "cells",
                        "fileType": "cells.json"
                    }

                self.file_def_creators += [get_molecules, get_cells]

        class MockWrapperB(AbstractWrapper):
            def __init__(self, name, **kwargs):
                super().__init__(**kwargs)
                self._repr = make_repr(locals())
                self.name = name

            def convert_and_save(self, dataset_uid, obj_i):
                def get_cell_sets(base_url):
                    return {
                        "url": f"{base_url}/cell-sets",
                        "type": "cell-sets",
                        "fileType": "cell-sets.json"
                    }

                self.file_def_creators += [get_cell_sets]

        dataset_a = vc.add_dataset(name='My First Dataset').add_object(
            obj=MockWrapperA("Experiment A")).add_file(
                url="http://example.com/my_cells.json",
                file_type=ft.CELLS_JSON,
                data_type=dt.CELLS)
        dataset_b = vc.add_dataset(name='My Second Dataset').add_object(
            obj=MockWrapperB("Experiment B"))
        vc.add_view(cm.SPATIAL, dataset=dataset_a, x=0, y=0, w=3,
                    h=3).set_props(title="My spatial plot")
        vc.add_view(cm.SCATTERPLOT,
                    dataset=dataset_b,
                    x=3,
                    y=0,
                    w=3,
                    h=3,
                    mapping="PCA").set_props(title="My scatterplot")
        base_url = "http://localhost:8000"

        classes_to_import, code_block = vc.to_python()
        self.assertEqual(
            classes_to_import,
            ['VitessceChainableConfig', 'VitessceConfigDatasetFile'])

        # Evaluate the code string directly
        reconstructed_vc = eval(code_block)
        self.assertEqual(vc.to_dict(base_url=base_url),
                         reconstructed_vc.to_dict(base_url=base_url))

        # Convert code string to an AST and back before evaluation
        if hasattr(ast, 'unparse'):
            # Unparse added in Python 3.9
            ast_reconstructed_vc = eval(ast.unparse(ast.parse(code_block)))
            self.assertEqual(vc.to_dict(base_url=base_url),
                             ast_reconstructed_vc.to_dict(base_url=base_url))
        else:
            ast.parse(code_block)
    def test_config_add_dataset_add_objects(self):
        vc = VitessceConfig()

        class MockWrapperA(AbstractWrapper):
            def __init__(self, name, **kwargs):
                super().__init__(**kwargs)
                self.name = name

            def convert_and_save(self, dataset_uid, obj_i):
                def get_molecules(base_url):
                    return {
                        "url": f"{base_url}/molecules",
                        "type": "molecules",
                        "fileType": "molecules.json"
                    }

                def get_cells(base_url):
                    return {
                        "url": f"{base_url}/cells",
                        "type": "cells",
                        "fileType": "cells.json"
                    }

                self.file_def_creators += [get_molecules, get_cells]

        class MockWrapperB(AbstractWrapper):
            def __init__(self, name, **kwargs):
                super().__init__(**kwargs)
                self.name = name

            def convert_and_save(self, dataset_uid, obj_i):
                def get_cell_sets(base_url):
                    return {
                        "url": f"{base_url}/cell-sets",
                        "type": "cell-sets",
                        "fileType": "cell-sets.json"
                    }

                self.file_def_creators += [get_cell_sets]

        vc.add_dataset(name='My Object Dataset').add_object(
            obj=MockWrapperA("Experiment A")).add_object(
                obj=MockWrapperB("Experiment B"))

        vc_dict = vc.to_dict(base_url="http://localhost:8000")
        print(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version":
                "1.0.4",
                "name":
                "",
                "description":
                "",
                "datasets": [
                    {
                        'uid':
                        'A',
                        'name':
                        'My Object Dataset',
                        'files': [{
                            "url": "http://localhost:8000/molecules",
                            "type": "molecules",
                            "fileType": "molecules.json"
                        }, {
                            "url": "http://localhost:8000/cells",
                            "type": "cells",
                            "fileType": "cells.json"
                        }, {
                            "url": "http://localhost:8000/cell-sets",
                            "type": "cell-sets",
                            "fileType": "cell-sets.json"
                        }]
                    },
                ],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                },
                "layout": [],
                "initStrategy":
                "auto"
            })
    def test_config_add_scatterplot_view_with_embedding_coordinations(self):
        vc = VitessceConfig()
        my_dataset = vc.add_dataset(name='My Dataset')

        my_view = vc.add_view(cm.SCATTERPLOT, dataset=my_dataset)

        et_scope, ez_scope, ex_scope, ey_scope = vc.add_coordination(
            ct.EMBEDDING_TYPE, ct.EMBEDDING_ZOOM, ct.EMBEDDING_TARGET_X,
            ct.EMBEDDING_TARGET_Y)
        my_view.use_coordination(et_scope, ez_scope, ex_scope, ey_scope)

        et_scope.set_value("X_pca")
        ez_scope.set_value(2)
        ex_scope.set_value(10)
        ey_scope.set_value(11)

        vc_dict = vc.to_dict()
        vc_json = json.dumps(vc_dict)

        self.assertEqual(
            vc_dict, {
                "version":
                "1.0.4",
                "name":
                "",
                "description":
                "",
                "datasets": [{
                    'uid': 'A',
                    'name': 'My Dataset',
                    'files': []
                }],
                'coordinationSpace': {
                    'dataset': {
                        'A': 'A'
                    },
                    'embeddingType': {
                        'A': 'X_pca'
                    },
                    'embeddingZoom': {
                        'A': 2
                    },
                    'embeddingTargetX': {
                        'A': 10
                    },
                    'embeddingTargetY': {
                        'A': 11
                    },
                },
                "layout": [{
                    'component': 'scatterplot',
                    'coordinationScopes': {
                        'dataset': 'A',
                        'embeddingType': 'A',
                        'embeddingZoom': 'A',
                        'embeddingTargetX': 'A',
                        'embeddingTargetY': 'A',
                    },
                    'h': 1,
                    'w': 1,
                    'x': 0,
                    'y': 0
                }],
                "initStrategy":
                "auto"
            })