/* Copyright 2026 Marimo. All rights reserved. */ import { readFileSync } from "node:fs"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { ISLAND_DATA_ATTRIBUTES, ISLAND_TAG_NAMES, ISLANDS_JSON_SCRIPT_TYPE, } from "@/core/islands/constants"; import { Logger } from "@/utils/Logger"; import { createMarimoFile, extractIslandCodeFromEmbed, parseIslandCode, parseIslandEditor, parseIslandElement, parseIslandElementsIntoApps, parseMarimoIslandApps, retainIslandSource, } from "../parse"; import { createMockIslandElement, createMockIslands } from "./test-utils.tsx"; function islandSnapshotPath(filename: string): string { return new URL( `../../../../../tests/_islands/snapshots/${filename}`, import.meta.url, ).pathname.replace(/^\/@fs/, ""); } function createPayloadCell( overrides: Partial<{ cellId: string; code: string; outputHtml: string; outputMimetype: string; reactive: boolean; displayCode: boolean; displayOutput: boolean; }> = {}, ) { return { cellId: "cell-1", code: 'print("payload")', outputHtml: "
payload
", outputMimetype: "text/html", reactive: true, displayCode: false, displayOutput: true, ...overrides, }; } function appendPayload( root: HTMLElement, payload: { schemaVersion: number; appId: string; dependencies?: unknown; cells: ReturnType[]; }, ) { const script = document.createElement("script"); script.type = ISLANDS_JSON_SCRIPT_TYPE; script.textContent = JSON.stringify(payload); root.appendChild(script); return script; } describe("createMarimoFile", () => { it("should serialize dependencies as top-level script metadata", () => { const file = createMarimoFile({ dependencies: ['cowsay==6.1; sys_platform == "emscripten"'], cells: [{ code: "import cowsay" }], }); expect(file).toBe( [ "# /// script", '# dependencies = ["cowsay==6.1; sys_platform == \\"emscripten\\""]', "# ///", "import marimo", "app = marimo.App()", "@app.cell", "def __():", " import cowsay", " return", ].join("\n"), ); }); it("should omit metadata for empty dependencies", () => { const cells = [{ code: "import cowsay" }]; expect(createMarimoFile({ cells, dependencies: [] })).toBe( createMarimoFile({ cells }), ); }); it("should return a string", () => { const app = { cells: [ { code: 'print("Hello, World!")', }, ], }; const result = createMarimoFile(app); expect(typeof result).toBe("string"); }); it("should correctly format a single cell", () => { const app = { cells: [ { code: 'print("Hello, World!")', }, ], }; const result = createMarimoFile(app); expect(result).toMatchInlineSnapshot(` "import marimo app = marimo.App() @app.cell def __(): print("Hello, World!") return" `); }); it("should correctly format multiple cells", () => { const app = { cells: [ { code: 'print("Hello, World!")', }, { code: 'print("Goodbye, World!")', }, ], }; const result = createMarimoFile(app); expect(result).toMatchInlineSnapshot(` "import marimo app = marimo.App() @app.cell def __(): print("Hello, World!") return @app.cell def __(): print("Goodbye, World!") return" `); }); it("should create an async marimo file from cells", () => { const app = { cells: [{ code: "await asyncio.sleep(1)" }], }; const result = createMarimoFile(app); expect(result).toMatchInlineSnapshot(` "import marimo app = marimo.App() @app.cell async def __(): await asyncio.sleep(1) return" `); }); it("should create disabled marimo cells", () => { const app = { cells: [{ code: "x = 0", disabled: true }, { code: "x = 1" }], }; const result = createMarimoFile(app); expect(result).toMatchInlineSnapshot(` "import marimo app = marimo.App() @app.cell(disabled=True) def __(): pass return @app.cell def __(): x = 1 return" `); }); it("should properly indent multi-line code", () => { const app = { cells: [{ code: "if True:\n print('hello')\n print('world')" }], }; const result = createMarimoFile(app); expect(result).toMatchInlineSnapshot(` "import marimo app = marimo.App() @app.cell def __(): if True: print('hello') print('world') return" `); }); }); describe("parseIslandCode", () => { let codes = [ ` def __(): print("Hello, World!") return `, `def __():\n print("Hello, World!")\n return`, `def __(): print("Hello, World!") return`, ]; codes = [...codes, ...codes.map(encodeURIComponent)]; it.each(codes)( "should return the code without leading or trailing whitespace", (code) => { const result = parseIslandCode(code); const expected = 'def __():\n print("Hello, World!")\n return'; expect(result).toBe(expected); }, ); it("should parse URI-encoded code with special characters", () => { const code = "print(%22Hello%2C%20world!%22)"; const result = parseIslandCode(code); expect(result).toBe('print("Hello, world!")'); }); it("should handle null and undefined", () => { expect(parseIslandCode(null)).toBe(""); expect(parseIslandCode(undefined)).toBe(""); }); }); describe("parseIslandEditor", () => { it("should parse JSON-encoded code", () => { const code = '"print(\\"Hello\\")"'; const result = parseIslandEditor(code); expect(result).toBe('print("Hello")'); }); it("should return raw code if JSON parsing fails", () => { const code = 'print("Hello")'; const result = parseIslandEditor(code); expect(result).toBe('print("Hello")'); }); it("should handle null and undefined", () => { expect(parseIslandEditor(null)).toBe(""); expect(parseIslandEditor(undefined)).toBe(""); }); }); describe("extractIslandCodeFromEmbed", () => { it("should extract code from marimo-cell-code element", () => { const element = createMockIslandElement({ code: 'print("test")', }); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const result = extractIslandCodeFromEmbed(element); expect(result).toBe('print("test")'); }); it("should return empty string for non-reactive cells", () => { const element = createMockIslandElement({ code: 'print("test")', }); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "false"); const result = extractIslandCodeFromEmbed(element); expect(result).toBe(""); }); it("should extract code from editor element if code element not found", () => { const element = document.createElement(ISLAND_TAG_NAMES.ISLAND); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const editor = document.createElement(ISLAND_TAG_NAMES.CODE_EDITOR); editor.setAttribute("data-initial-value", '"print(\\"hello\\")"'); element.appendChild(editor); const result = extractIslandCodeFromEmbed(element); expect(result).toBe('print("hello")'); }); it("should return empty string if no code elements found", () => { const element = document.createElement(ISLAND_TAG_NAMES.ISLAND); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const result = extractIslandCodeFromEmbed(element); expect(result).toBe(""); }); }); describe("parseIslandElement", () => { it("should parse a valid island element", () => { const element = createMockIslandElement({ code: 'print("test")', innerHTML: "
output
", }); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const result = parseIslandElement(element); expect(result).toMatchInlineSnapshot(` { "code": "print("test")", "output": "
output
", } `); }); it("should return null if output is missing", () => { const element = document.createElement(ISLAND_TAG_NAMES.ISLAND); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const codeElement = document.createElement(ISLAND_TAG_NAMES.CELL_CODE); codeElement.textContent = encodeURIComponent('print("test")'); element.appendChild(codeElement); const result = parseIslandElement(element); expect(result).toBeNull(); }); it("should return null if code is missing", () => { const element = document.createElement(ISLAND_TAG_NAMES.ISLAND); const outputElement = document.createElement(ISLAND_TAG_NAMES.CELL_OUTPUT); outputElement.innerHTML = "
output
"; element.appendChild(outputElement); const result = parseIslandElement(element); expect(result).toBeNull(); }); it("uses retained source after the custom element renders", () => { const element = document.createElement(ISLAND_TAG_NAMES.ISLAND); retainIslandSource(element, { code: 'print("retained")', output: "
retained output
", }); expect(parseIslandElement(element)).toEqual({ code: 'print("retained")', output: "
retained output
", }); retainIslandSource(element, { code: "", output: "
static
" }); expect(parseIslandElement(element)).toBeNull(); }); it("prefers new live source when an island element is reused", () => { const element = createMockIslandElement({ code: 'print("new")', innerHTML: "
new output
", }); element.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); retainIslandSource(element, { code: 'print("retained")', output: "
retained output
", }); expect(parseIslandElement(element)).toEqual({ code: 'print("new")', output: "
new output
", }); }); }); describe("parseIslandElementsIntoApps", () => { it("should parse single app with single cell", () => { const elements = [ createMockIslandElement({ appId: "app1", cellIdx: "0", code: 'print("hello")', innerHTML: "
output1
", }), ]; elements[0].setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const result = parseIslandElementsIntoApps(elements); expect(result).toHaveLength(1); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "print("hello")", "idx": 0, "output": "
output1
", }, ], "id": "app1", }, ] `); }); it("should parse single app with multiple cells", () => { const elements = createMockIslands(3, "app1").map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); const result = parseIslandElementsIntoApps(elements); expect(result).toHaveLength(1); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, { "code": "cell_1 = 1", "idx": 1, "output": "
output 1
", }, { "code": "cell_2 = 2", "idx": 2, "output": "
output 2
", }, ], "id": "app1", }, ] `); }); it("should parse multiple apps", () => { const elements = [ ...createMockIslands(2, "app1"), ...createMockIslands(2, "app2"), ].map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); const result = parseIslandElementsIntoApps(elements); expect(result).toHaveLength(2); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, { "code": "cell_1 = 1", "idx": 1, "output": "
output 1
", }, ], "id": "app1", }, { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, { "code": "cell_1 = 1", "idx": 1, "output": "
output 1
", }, ], "id": "app2", }, ] `); }); it("should skip elements without app-id", () => { const validElement = createMockIslandElement({ appId: "app1", code: 'print("test")', innerHTML: "
output
", }); validElement.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const invalidElement = document.createElement(ISLAND_TAG_NAMES.ISLAND); invalidElement.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); const result = parseIslandElementsIntoApps([validElement, invalidElement]); expect(result).toHaveLength(1); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "print("test")", "idx": 0, "output": "
output
", }, ], "id": "app1", }, ] `); }); it("should assign correct cell indices", () => { const elements = createMockIslands(3, "app1").map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); const result = parseIslandElementsIntoApps(elements); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, { "code": "cell_1 = 1", "idx": 1, "output": "
output 1
", }, { "code": "cell_2 = 2", "idx": 2, "output": "
output 2
", }, ], "id": "app1", }, ] `); }); it("should set data-cell-idx attribute on elements", () => { const elements = createMockIslands(2, "app1").map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); parseIslandElementsIntoApps(elements); expect(elements[0].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(elements[1].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); }); }); describe("parseMarimoIslandApps", () => { let container: HTMLDivElement; beforeEach(() => { container = document.createElement("div"); document.body.appendChild(container); }); afterEach(() => { document.body.removeChild(container); vi.restoreAllMocks(); }); it("should parse islands from document", () => { const elements = createMockIslands(2, "app1").map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); for (const el of elements) { container.appendChild(el); } const result = parseMarimoIslandApps(container); expect(result).toHaveLength(1); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, { "code": "cell_1 = 1", "idx": 1, "output": "
output 1
", }, ], "id": "app1", }, ] `); }); it("should return empty array if no islands found", () => { const result = parseMarimoIslandApps(container); expect(result).toEqual([]); }); it("should accept custom root element", () => { const customRoot = document.createElement("div"); const elements = createMockIslands(1, "app1").map((el) => { el.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); return el; }); for (const el of elements) { customRoot.appendChild(el); } const result = parseMarimoIslandApps(customRoot); expect(result).toHaveLength(1); expect(result).toMatchInlineSnapshot(` [ { "cells": [ { "code": "cell_0 = 0", "idx": 0, "output": "
output 0
", }, ], "id": "app1", }, ] `); }); it("should use supported JSON payload data for matched islands", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: 'print("dom")', innerHTML: "
dom
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell()], }); const result = parseMarimoIslandApps(container); expect(result).toEqual([ { id: "app1", payloadBacked: true, cells: [ { cellId: "cell-1", code: 'print("payload")', idx: 0, output: "
payload
", }, ], }, ]); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull(); expect(extractIslandCodeFromEmbed(island)).toBe('print("payload")'); expect(island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)?.innerHTML).toBe( "
payload
", ); }); it("preserves payload-backed cells after a non-materializing capability probe", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-2", code: "dom_code = True", innerHTML: "
dom output
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell({ cellId: "cell-2" })], }); const originalIsland = island.outerHTML; const probed = parseMarimoIslandApps(container, { materialize: false }); expect(probed).toHaveLength(1); expect(island.outerHTML).toBe(originalIsland); expect(parseMarimoIslandApps(container)).toEqual(probed); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull(); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); }); it("refreshes a reused payload anchor when its content changes", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: 'print("dom")', innerHTML: "
dom output
", }); island.insertAdjacentHTML( "beforeend", '
', ); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); const script = appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell()], }); parseMarimoIslandApps(container); script.textContent = JSON.stringify({ schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ code: 'print("updated")', outputHtml: "
updated output
", }), ], }); parseMarimoIslandApps(container); expect(extractIslandCodeFromEmbed(island)).toBe('print("updated")'); expect(island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)?.innerHTML).toBe( "
updated output
", ); expect( island .querySelector(ISLAND_TAG_NAMES.CODE_EDITOR) ?.getAttribute("data-initial-value"), ).toBe(JSON.stringify('print("updated")')); }); it("should parse Python-generated island payload snapshots", () => { const html = readFileSync(islandSnapshotPath("html-payload.txt"), "utf8"); container.innerHTML = html; const result = parseMarimoIslandApps(container); const islands = container.querySelectorAll( ISLAND_TAG_NAMES.ISLAND, ); expect(result).toEqual([ { id: "main", payloadBacked: true, cells: [ { cellId: "Hbol", code: "import marimo as mo", idx: 0, output: "", }, { cellId: "MJUe", code: "mo.md('Hello, HTML!')", idx: 1, output: "", }, ], }, ]); expect(islands[0].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBeNull(); expect(islands[1].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(islands[2].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); }); it("should restore metadata from a Python-generated dependency payload", () => { container.innerHTML = readFileSync( islandSnapshotPath("body-dependencies.txt"), "utf8", ); const probed = parseMarimoIslandApps(container, { materialize: false }); const apps = parseMarimoIslandApps(container); expect(probed).toEqual(apps); expect(apps).toEqual([ { id: "main", payloadBacked: true, dependencies: [ 'cowsay==6.1; sys_platform == "emscripten"', "rich[jupyter]>=13", "desktop; sys_platform != 'emscripten'", "older-python; python_version < '3.13'", "newer-python; python_version >= '3.13'", ], cells: [{ cellId: "Hbol", code: "import cowsay", output: "", idx: 0 }], }, ]); // The Python Pyodide test reads this file with the real metadata parser. expect(createMarimoFile(apps[0])).toBe( readFileSync(islandSnapshotPath("notebook-dependencies.txt"), "utf8"), ); }); it("should carry dependencies from payloads into each generated notebook", () => { for (const [appId, dependencies] of [ ["app1", ["cowsay==6.1"]], ["app2", ["rich[jupyter]>=13"]], ] as const) { container.appendChild( createMockIslandElement({ appId, cellId: "cell-1" }), ); appendPayload(container, { schemaVersion: 1, appId, dependencies, cells: [createPayloadCell()], }); } const apps = parseMarimoIslandApps(container); expect(apps.map((app) => [app.id, app.dependencies])).toEqual([ ["app1", ["cowsay==6.1"]], ["app2", ["rich[jupyter]>=13"]], ]); expect(createMarimoFile(apps[0])).toContain( '# /// script\n# dependencies = ["cowsay==6.1"]\n# ///\n', ); }); it.each([null, "cowsay", [123], ["cowsay", null]])( "should ignore payloads with malformed dependencies: %j", (dependencies) => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "import cowsay", innerHTML: "
dom
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", dependencies, cells: [createPayloadCell()], }); expect(parseMarimoIslandApps(container)).toEqual([ { id: "app1", cells: [{ code: "import cowsay", output: "
dom
", idx: 0 }], }, ]); }, ); it("should merge dependencies from payloads belonging to the same app", () => { for (const [cellId, dependencies] of [ ["cell-1", ["cowsay"]], ["cell-2", ["cowsay", "rich"]], ] as const) { container.appendChild(createMockIslandElement({ appId: "app1", cellId })); appendPayload(container, { schemaVersion: 1, appId: "app1", dependencies, cells: [createPayloadCell({ cellId })], }); } expect( parseMarimoIslandApps(container).map((app) => app.dependencies), ).toEqual([["cowsay", "rich"]]); }); it("should fall back to DOM islands for unsupported payload versions", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: 'print("dom")', innerHTML: "
dom
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 2, appId: "app1", cells: [createPayloadCell()], }); const result = parseMarimoIslandApps(container); expect(result).toEqual([ { id: "app1", cells: [ { code: 'print("dom")', idx: 0, output: "
dom
", }, ], }, ]); }); it("should ignore payload scripts rendered inside island output", () => { const nestedPayload = { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ code: "payload_code_should_not_run = True", outputHtml: "
payload
", }), ], }; const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: 'print("dom")', innerHTML: `
dom
`, }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); const result = parseMarimoIslandApps(container); expect(result).toEqual([ { id: "app1", cells: [ { code: 'print("dom")', idx: 0, output: island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT) ?.innerHTML, }, ], }, ]); }); it("should use payload order for runtime cell indices", () => { const second = createMockIslandElement({ appId: "app1", cellId: "cell-2", code: "second_dom = True", innerHTML: "
second dom
", }); const first = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "first_dom = True", innerHTML: "
first dom
", }); for (const island of [second, first]) { island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); } appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ cellId: "cell-1", code: "first_payload = True", outputHtml: "
first payload
", }), createPayloadCell({ cellId: "cell-2", code: "second_payload = True", outputHtml: "
second payload
", }), ], }); const result = parseMarimoIslandApps(container); expect(result[0].cells.map((cell) => cell.code)).toEqual([ "first_payload = True", "second_payload = True", ]); expect(first.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(second.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); }); it("should include payload-only runtime cells", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-2", code: "value", innerHTML: "
value
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ cellId: "cell-1", code: "import marimo as mo", outputHtml: "", }), createPayloadCell({ cellId: "cell-2", code: "mo.md('visible')", outputHtml: "
visible
", }), ], }); const result = parseMarimoIslandApps(container); expect(result[0].cells.map((cell) => cell.code)).toEqual([ "import marimo as mo", "mo.md('visible')", ]); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); }); it("should bind payload-backed islands by runtime index after static cells", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-2", code: "visible_dom = True", innerHTML: "
visible dom
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ cellId: "cell-1", code: "", outputHtml: "
static
", reactive: false, }), createPayloadCell({ cellId: "cell-2", code: "visible_payload = True", outputHtml: "
visible payload
", }), ], }); const result = parseMarimoIslandApps(container); expect(result[0].cells).toEqual([ { cellId: "cell-1", code: "", disabled: true, idx: 0, output: "
static
", }, { cellId: "cell-2", code: "visible_payload = True", idx: 1, output: "
visible payload
", }, ]); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull(); }); it("should fall back to DOM when no payload cell matches an island", () => { const island = createMockIslandElement({ appId: "app1", cellId: "dom-only", code: "dom_only = True", innerHTML: "
dom only
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); island.removeAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ cellId: "payload-only", code: "payload_only = True", outputHtml: "
payload only
", }), ], dependencies: ["cowsay"], }); const result = parseMarimoIslandApps(container); expect(result).toEqual([ { id: "app1", cells: [ { code: "dom_only = True", idx: 0, output: "
dom only
", }, ], }, ]); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBe( "dom-only", ); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE)).toBe("true"); }); it("should ignore payloads without matching islands", () => { const warn = vi.spyOn(Logger, "warn").mockImplementation(() => undefined); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell()], }); const result = parseMarimoIslandApps(container); expect(result).toEqual([]); expect(warn).toHaveBeenCalledWith("No embedded marimo apps found."); }); it("should still parse DOM-only apps when another app has payload", () => { const payloadIsland = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "payload_dom = True", innerHTML: "
payload dom
", }); const domIsland = createMockIslandElement({ appId: "app2", code: "dom_app = True", innerHTML: "
dom app
", }); for (const island of [payloadIsland, domIsland]) { island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); } appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell()], }); const result = parseMarimoIslandApps(container); expect(result.map((app) => app.id)).toEqual(["app1", "app2"]); expect(result[0].cells[0].code).toBe('print("payload")'); expect(result[1].cells[0].code).toBe("dom_app = True"); }); it("should materialize non-reactive payload islands without runtime cells", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "static_dom = True", innerHTML: "
static dom
", }); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "false"); island.removeAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ code: "", outputHtml: "
static payload
", reactive: false, }), ], dependencies: ["cowsay"], }); const result = parseMarimoIslandApps(container); expect(result).toEqual([]); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBeNull(); expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull(); expect(island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)?.innerHTML).toBe( "
static payload
", ); }); it("should keep non-reactive display code out of runtime cells", () => { const staticIsland = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "x = 0", innerHTML: "
static
", }); const reactiveIsland = createMockIslandElement({ appId: "app1", cellId: "cell-2", code: "y = 1", innerHTML: "
reactive
", }); staticIsland.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "false"); reactiveIsland.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.append(staticIsland, reactiveIsland); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ cellId: "cell-1", code: "x = 0", outputHtml: "
static payload
", reactive: false, displayCode: true, }), createPayloadCell({ cellId: "cell-2", code: "y = 1", outputHtml: "
reactive payload
", }), ], }); const result = parseMarimoIslandApps(container); const file = createMarimoFile(result[0]); expect(result[0].cells).toEqual([ { cellId: "cell-1", code: "", disabled: true, idx: 0, output: "
static payload
", }, { cellId: "cell-2", code: "y = 1", idx: 1, output: "
reactive payload
", }, ]); expect(file).not.toContain("x = 0"); expect(file).toContain("@app.cell(disabled=True)\ndef __():\n pass"); expect(reactiveIsland.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe( "1", ); }); it("should update editor initial values from payload code", () => { const island = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: 'print("dom")', innerHTML: "
dom
", }); island.insertAdjacentHTML( "beforeend", '
', ); island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [createPayloadCell()], }); parseMarimoIslandApps(container); expect( island .querySelector(ISLAND_TAG_NAMES.CODE_EDITOR) ?.getAttribute("data-initial-value"), ).toBe(JSON.stringify('print("payload")')); }); it("should match duplicate cell ids by occurrence", () => { const first = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "dom_first = True", innerHTML: "
dom first
", }); const second = createMockIslandElement({ appId: "app1", cellId: "cell-1", code: "dom_second = True", innerHTML: "
dom second
", }); for (const island of [first, second]) { island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true"); container.appendChild(island); } appendPayload(container, { schemaVersion: 1, appId: "app1", cells: [ createPayloadCell({ code: "payload_first = True", outputHtml: "
payload first
", }), createPayloadCell({ code: "payload_second = True", outputHtml: "
payload second
", }), ], }); const result = parseMarimoIslandApps(container); expect(result[0].cells.map((cell) => cell.code)).toEqual([ "payload_first = True", "payload_second = True", ]); expect(first.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0"); expect(second.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1"); }); });