Skip to main content
Glama
by mckinsey
test_vizro.py8 kB
import operator import dash import pytest from packaging.version import parse import vizro import vizro.models as vm from vizro import Vizro from vizro._constants import VIZRO_ASSETS_PATH _git_branch = vizro.__version__ if not parse(vizro.__version__).is_devrelease else "main" def test_vizro_bootstrap(): assert ( vizro.bootstrap == f"https://cdn.jsdelivr.net/gh/mckinsey/vizro@{_git_branch}/vizro-core/src/vizro/static/css/vizro-bootstrap.min.css" ) # Using Vizro as a framework should include both the library and framework resources i.e. all files in # VIZRO_ASSETS_PATH. class TestVizroResources: # Only external_url or relative_package_path will exist in the resource specification depending on # whether serve_locally=True (the Dash and Vizro default) or False. @pytest.mark.parametrize( "serve_locally, resource_key, resource_value", [ (True, "relative_package_path", "static/css/vizro-bootstrap.min.css"), ( False, "external_url", f"https://cdn.jsdelivr.net/gh/mckinsey/vizro@{_git_branch}/vizro-core/src/vizro/static/css/vizro-bootstrap.min.css", ), ], ) def test_css(self, serve_locally, resource_key, resource_value): app = vizro.Vizro(serve_locally=serve_locally) framework_css = app.dash.css.get_library_css("vizro") # Check same number of files assert len(framework_css) == len(set(VIZRO_ASSETS_PATH.rglob("*.css"))) # Check vizro-bootstrap comes first and looks right assert framework_css[0] == {"namespace": "vizro", resource_key: resource_value} # Check rest is in alphabetical order assert framework_css[1:] == sorted(framework_css[1:], key=operator.itemgetter(resource_key)) # Only external_url or relative_package_path will exist in the resource specification depending on # whether serve_locally=True (the Dash and Vizro default) or False. @pytest.mark.parametrize( "serve_locally, resource_key, resource_value", [ (True, "relative_package_path", "static/js/models/slider.js"), ( False, "external_url", f"https://cdn.jsdelivr.net/gh/mckinsey/vizro@{_git_branch}/vizro-core/src/vizro/static/js/models/slider.min.js", ), ], ) def test_scripts(self, serve_locally, resource_key, resource_value): app = vizro.Vizro(serve_locally=serve_locally) framework_scripts = app.dash.scripts.get_library_scripts("vizro") # Check same number of files assert len(framework_scripts) == len( set(VIZRO_ASSETS_PATH.rglob("*.*")) - set(VIZRO_ASSETS_PATH.rglob("*.css")) ) # Check a random file. It doesn't matter what this one is so long as it doesn't have dynamic=True, which would # make it impossible to check external_url. assert framework_scripts[-1] == {"namespace": "vizro", resource_key: resource_value} # Checking the order here is trickier because when dynamic=True some resources don't have external_url. The # order is less important than for CSS anyway, so we don't test it. def test_double_instantiation(self): # This wouldn't pass without the suppress(ValueError) around ComponentRegistry.registry.discard("vizro"). vizro.Vizro() vizro.Vizro() # Using Vizro as a library in a pure Dash app should include only resources stipulated in vizro._css_dist and # vizro._js_dist and no other files from VIZRO_ASSETS_PATH. class TestDashResources: @pytest.mark.parametrize("serve_locally, resource_key", [(True, "relative_package_path"), (False, "external_url")]) def test_css(self, serve_locally, resource_key): app = dash.Dash(serve_locally=serve_locally) library_css = [{"namespace": "vizro", resource_key: resource[resource_key]} for resource in vizro._css_dist] assert app.css.get_library_css("vizro") == library_css # Only external_url or relative_package_path will exist in the resource specification depending on # whether serve_locally=True (the Dash and Vizro default) or False. @pytest.mark.parametrize("serve_locally, resource_key", [(True, "relative_package_path"), (False, "external_url")]) def test_scripts(self, serve_locally, resource_key): app = dash.Dash(serve_locally=serve_locally) # The below would mirror test_vizro_css but we need to handle dynamic resources differently. These never have # external_url associated with them. # library_scripts =[{"namespace": "vizro", resource_key: resource[resource_key]} for resource in vizro._js_dist] library_scripts = [] for resource in vizro._js_dist: if resource.get("dynamic", False): library_scripts.append( {"namespace": "vizro", "dynamic": True, "relative_package_path": resource["relative_package_path"]} ) else: library_scripts.append({"namespace": "vizro", resource_key: resource[resource_key]}) assert app.scripts.get_library_scripts("vizro") == library_scripts class TestBootstrapDetection: """Test automatic Bootstrap CSS detection.""" @pytest.mark.parametrize( "external_stylesheets, vizro_bootstrap_included", [ # Bootstrap detected - vizro bootstrap should NOT be included # String URL (["https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css"], False), # Dict with href key ( [{"href": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css"}], False, ), # Multiple stylesheets (["https://fonts.googleapis.com/css", "https://example.com/bootstrap.css"], False), # Mixed ( [ "https://codepen.io/bWffds.css", {"href": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css"}, ], False, ), # Case insensitive (["https://example.com/BOOTSTRAP-theme.css"], False), # Bootstrap NOT detected - vizro bootstrap should be included ([], True), (["https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"], True), ([{"href": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"}], True), ([{"src": "https://bootstrap.css"}], True), # Wrong key in dict ], ) def test_include_vizro_bootstrap(self, external_stylesheets, vizro_bootstrap_included): app = Vizro(external_stylesheets=external_stylesheets) framework_css = app.dash.css.get_library_css("vizro") has_vizro_bootstrap = any( "vizro-bootstrap.min.css" in resource.get("relative_package_path", "") for resource in framework_css ) assert has_vizro_bootstrap is vizro_bootstrap_included class TestRun: def test_run_block_with_undefined_captured_callables(self): dashboard_config = { "title": "Test dashboard", "pages": [ { "title": "Page 1", "components": [ { "type": "ag_grid", "figure": {"_target_": "llm_generated_grid", "data_frame": "iris"}, }, ], } ], } dashboard = vm.Dashboard.model_validate( dashboard_config, context={"allow_undefined_captured_callable": ["llm_generated_grid"]}, ) app = Vizro().build(dashboard) with pytest.raises(ValueError, match="Dashboard contains models with undefined CapturedCallable's"): app.run()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mckinsey/vizro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server