/* Copyright 2026 Marimo. All rights reserved. */ // @vitest-environment jsdom import { beforeEach, describe, expect, it, vi } from "vitest"; import { type AppConfig, defaultUserConfig, parseAppConfig, } from "@/core/config/config-schema"; import { appConfigAtom, configOverridesAtom, userConfigAtom, } from "../core/config/config"; import { marimoVersionAtom, showCodeInRunModeAtom } from "../core/meta/state"; import { type AppMode, viewStateAtom } from "../core/mode"; import { codeAtom, filenameAtom } from "../core/saving/file-state"; import { store } from "../core/state/jotai"; import { mount, visibleForTesting } from "../mount"; vi.mock("../utils/vitals", () => ({ reportVitals: vi.fn(), })); vi.mock("react-dom/client", () => ({ createRoot: vi.fn().mockImplementation((_el) => { return { render: vi.fn(), }; }), })); describe("main", () => { beforeEach(() => { visibleForTesting.reset(); // Reset store before each test store.set(viewStateAtom, { mode: "not-set" as AppMode, cellAnchor: null }); store.set(codeAtom, undefined); store.set(filenameAtom, null); store.set(showCodeInRunModeAtom, false); store.set(marimoVersionAtom, "unknown"); store.set(appConfigAtom, parseAppConfig({})); store.set(userConfigAtom, defaultUserConfig()); store.set(configOverridesAtom, {}); }); it.each(["edit", "read", "home", "run"])( "should mount with mode %s", (_mode) => { const el = document.createElement("div"); mount({ mode: "edit" }, el); expect(store.get(viewStateAtom).mode).toBe("edit"); expect(store.get(filenameAtom)).toBeDefined(); expect(store.get(marimoVersionAtom)).toBe("unknown"); expect(store.get(showCodeInRunModeAtom)).toBe(true); }, ); it("should not mount with invalid mode", () => { const el = document.createElement("div"); const error = mount({ mode: "invalid" }, el); expect(error).toBeDefined(); expect(error?.message).toBe("Invalid marimo mount options"); }); it("should mount with null values", () => { const el = document.createElement("div"); const error = mount( { mode: "edit", filename: null, code: null, version: null }, el, ); expect(error).toBeUndefined(); mount({ mode: "edit", filename: null, code: null, version: null }, el); expect(store.get(filenameAtom)).toBeNull(); expect(store.get(codeAtom)).toBe(""); expect(store.get(marimoVersionAtom)).toBe("unknown"); expect(store.get(viewStateAtom).mode).toBe("edit"); }); it("should mount with undefined values", () => { const el = document.createElement("div"); const error = mount( { mode: "edit", filename: undefined, code: undefined, version: undefined, }, el, ); expect(error).toBeUndefined(); expect(store.get(filenameAtom)).toBeNull(); expect(store.get(codeAtom)).toBe(""); expect(store.get(marimoVersionAtom)).toBe("unknown"); expect(store.get(viewStateAtom).mode).toBe("edit"); }); it("should mount with empty config", () => { const el = document.createElement("div"); const error = mount( { mode: "edit", config: {}, configOverrides: {}, appConfig: {} }, el, ); expect(error).toBeUndefined(); expect(store.get(userConfigAtom)).toEqual(defaultUserConfig()); expect(store.get(configOverridesAtom)).toEqual({}); expect(store.get(appConfigAtom)).toEqual(parseAppConfig({})); expect(store.get(viewStateAtom).mode).toBe("edit"); expect(store.get(showCodeInRunModeAtom)).toBe(true); }); it("should mount with all options", () => { const el = document.createElement("div"); const options = { filename: "test.py", code: "print('hello')", version: "1.0.0", mode: "edit" as const, config: { display: { cell_output: "above", code_editor_font_size: 99, dataframes: "rich", default_table_page_size: 10, default_width: "medium", theme: "light", }, }, configOverrides: { display: { code_editor_font_size: 100 } }, appConfig: { app_title: "My App" } as AppConfig, view: { showAppCode: true }, }; mount(options, el); expect(store.get(filenameAtom)).toBe("test.py"); expect(store.get(codeAtom)).toBe("print('hello')"); expect(store.get(marimoVersionAtom)).toBe("1.0.0"); expect(store.get(viewStateAtom).mode).toBe("edit"); expect(store.get(showCodeInRunModeAtom)).toBe(true); expect(store.get(userConfigAtom).display).toEqual( expect.objectContaining({ code_editor_font_size: 99, }), ); expect(store.get(configOverridesAtom)).toEqual( expect.objectContaining({ display: { code_editor_font_size: 100 }, }), ); expect(store.get(appConfigAtom)).toEqual( expect.objectContaining({ app_title: "My App" }), ); }); it("should throw on invalid options", () => { const el = document.createElement("div"); const error = mount({ invalid: true } as unknown, el); expect(error).toBeDefined(); expect(error?.message).toBe("Invalid marimo mount options"); }); it("should not mount twice", () => { const el = document.createElement("div"); mount({ mode: "edit" }, el); const error = mount({ mode: "edit" }, el); expect(error).toBeDefined(); expect(error?.message).toBe("marimo app has already been mounted."); }); });