/* 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");
});
});