/* Copyright 2026 Marimo. All rights reserved. */
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
ISLAND_DATA_ATTRIBUTES,
ISLAND_TAG_NAMES,
} from "@/core/islands/constants";
import {
createMarimoFile,
extractIslandCodeFromEmbed,
parseIslandCode,
parseIslandEditor,
parseIslandElement,
parseIslandElementsIntoApps,
parseMarimoIslandApps,
} from "../parse";
import { createMockIslandElement, createMockIslands } from "./test-utils.tsx";
describe("createMarimoFile", () => {
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 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();
});
});
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);
});
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",
},
]
`);
});
});