@marimo-team/islands 0.21.2-dev39 → 0.21.2-dev40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +5 -2
- package/package.json +1 -1
- package/src/__mocks__/notebook.ts +9 -9
- package/src/__tests__/branded.ts +20 -0
- package/src/components/data-table/charts/__tests__/storage.test.ts +7 -7
- package/src/components/editor/__tests__/data-attributes.test.tsx +8 -8
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +15 -15
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -2
- package/src/components/editor/navigation/__tests__/selection.test.ts +7 -6
- package/src/components/editor/navigation/__tests__/state.test.ts +8 -7
- package/src/components/editor/output/MarimoErrorOutput.tsx +7 -7
- package/src/components/editor/output/__tests__/traceback.test.tsx +4 -4
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +4 -4
- package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +8 -1
- package/src/components/storage/storage-inspector.tsx +1 -2
- package/src/components/tracing/tracing.tsx +3 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +9 -8
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +31 -31
- package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -3
- package/src/core/ai/context/providers/__tests__/tables.test.ts +3 -2
- package/src/core/ai/context/providers/__tests__/variable.test.ts +84 -63
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +10 -9
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +6 -6
- package/src/core/ai/tools/edit-notebook-tool.ts +3 -3
- package/src/core/cells/__tests__/add-missing-import.test.ts +3 -3
- package/src/core/cells/__tests__/cells.test.ts +192 -135
- package/src/core/cells/__tests__/focus.test.ts +5 -4
- package/src/core/cells/__tests__/logs.test.ts +13 -12
- package/src/core/cells/__tests__/pending-delete-service.test.tsx +3 -3
- package/src/core/cells/__tests__/runs.test.ts +22 -21
- package/src/core/cells/__tests__/scrollCellIntoView.test.ts +8 -7
- package/src/core/cells/__tests__/session.test.ts +23 -22
- package/src/core/cells/cells.ts +1 -1
- package/src/core/cells/ids.ts +5 -5
- package/src/core/cells/logs.ts +2 -2
- package/src/core/cells/runs.ts +6 -8
- package/src/core/codemirror/__tests__/format.test.ts +34 -36
- package/src/core/codemirror/__tests__/setup.test.ts +2 -2
- package/src/core/codemirror/cells/__tests__/traceback-decorations.test.ts +33 -32
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +12 -13
- package/src/core/codemirror/language/__tests__/utils.test.ts +3 -3
- package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +7 -8
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +4 -3
- package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +7 -6
- package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
- package/src/core/datasets/__tests__/data-source.test.ts +5 -6
- package/src/core/datasets/state.ts +1 -1
- package/src/core/errors/__tests__/errors.test.ts +2 -1
- package/src/core/export/__tests__/hooks.test.ts +37 -36
- package/src/core/islands/main.ts +2 -7
- package/src/core/kernel/__tests__/handlers.test.ts +5 -4
- package/src/core/kernel/handlers.ts +7 -4
- package/src/core/network/DeferredRequestRegistry.ts +2 -2
- package/src/core/network/__tests__/CachingRequestRegistry.test.ts +9 -10
- package/src/core/network/__tests__/DeferredRequestRegistry.test.ts +4 -6
- package/src/core/static/__tests__/virtual-file-tracker.test.ts +8 -8
- package/src/core/static/virtual-file-tracker.ts +1 -1
- package/src/core/storage/__tests__/state.test.ts +31 -21
- package/src/core/storage/state.ts +1 -1
- package/src/core/variables/__tests__/state.test.ts +6 -6
- package/src/core/variables/types.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +8 -8
- package/src/core/websocket/useMarimoKernelConnection.tsx +12 -15
- package/src/plugins/impl/anywidget/model.ts +1 -2
- package/src/stories/cell.stories.tsx +8 -8
- package/src/stories/layout/vertical/one-column.stories.tsx +9 -8
- package/src/stories/log-viewer.stories.tsx +8 -8
- package/src/stories/variables.stories.tsx +2 -2
- package/src/utils/__tests__/download.test.tsx +19 -18
- package/src/utils/json/base64.ts +3 -3
- package/src/utils/traceback.ts +5 -3
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
4
|
import { Mocks } from "@/__mocks__/common";
|
|
5
|
+
import { cellId } from "@/__tests__/branded";
|
|
5
6
|
|
|
6
7
|
// Mock the external dependencies
|
|
7
8
|
vi.mock("html-to-image", () => ({
|
|
@@ -13,7 +14,6 @@ vi.mock("@/utils/Logger", () => ({
|
|
|
13
14
|
}));
|
|
14
15
|
|
|
15
16
|
import type { NotebookState } from "@/core/cells/cells";
|
|
16
|
-
import type { CellId } from "@/core/cells/ids";
|
|
17
17
|
import type { OutputMessage } from "@/core/kernel/messages";
|
|
18
18
|
import type { JotaiStore } from "@/core/state/jotai";
|
|
19
19
|
import { CellOutputContextProvider, getCellContextData } from "../cell-output";
|
|
@@ -35,21 +35,21 @@ describe("CellOutputContextProvider", () => {
|
|
|
35
35
|
// Create a basic mock notebook state
|
|
36
36
|
mockNotebook = {
|
|
37
37
|
cellIds: {
|
|
38
|
-
inOrderIds: ["cell1"
|
|
38
|
+
inOrderIds: ["cell1", "cell2", "cell3"],
|
|
39
39
|
},
|
|
40
40
|
cellData: {
|
|
41
41
|
cell1: {
|
|
42
|
-
id: "cell1"
|
|
42
|
+
id: "cell1",
|
|
43
43
|
name: "My Cell",
|
|
44
44
|
code: "print('hello world')",
|
|
45
45
|
},
|
|
46
46
|
cell2: {
|
|
47
|
-
id: "cell2"
|
|
47
|
+
id: "cell2",
|
|
48
48
|
name: "",
|
|
49
49
|
code: "import matplotlib.pyplot as plt\nplt.plot([1,2,3])",
|
|
50
50
|
},
|
|
51
51
|
cell3: {
|
|
52
|
-
id: "cell3"
|
|
52
|
+
id: "cell3",
|
|
53
53
|
name: "Empty Cell",
|
|
54
54
|
code: "# no output",
|
|
55
55
|
},
|
|
@@ -226,9 +226,9 @@ describe("Cell output utility functions", () => {
|
|
|
226
226
|
|
|
227
227
|
for (const testCase of testCases) {
|
|
228
228
|
mockStore = createMockStore({
|
|
229
|
-
cellIds: { inOrderIds: ["test"
|
|
229
|
+
cellIds: { inOrderIds: ["test"] },
|
|
230
230
|
cellData: {
|
|
231
|
-
test: { id: "test"
|
|
231
|
+
test: { id: "test", name: "", code: "" },
|
|
232
232
|
},
|
|
233
233
|
cellRuntime: {
|
|
234
234
|
test: {
|
|
@@ -261,9 +261,9 @@ describe("Cell output utility functions", () => {
|
|
|
261
261
|
|
|
262
262
|
for (const testCase of testCases) {
|
|
263
263
|
mockStore = createMockStore({
|
|
264
|
-
cellIds: { inOrderIds: ["test"
|
|
264
|
+
cellIds: { inOrderIds: ["test"] },
|
|
265
265
|
cellData: {
|
|
266
|
-
test: { id: "test"
|
|
266
|
+
test: { id: "test", name: "", code: "" },
|
|
267
267
|
},
|
|
268
268
|
cellRuntime: {
|
|
269
269
|
test: {
|
|
@@ -295,9 +295,9 @@ describe("Cell output utility functions", () => {
|
|
|
295
295
|
|
|
296
296
|
for (const testCase of testCases) {
|
|
297
297
|
mockStore = createMockStore({
|
|
298
|
-
cellIds: { inOrderIds: ["test"
|
|
298
|
+
cellIds: { inOrderIds: ["test"] },
|
|
299
299
|
cellData: {
|
|
300
|
-
test: { id: "test"
|
|
300
|
+
test: { id: "test", name: "", code: "" },
|
|
301
301
|
},
|
|
302
302
|
cellRuntime: {
|
|
303
303
|
test: {
|
|
@@ -369,9 +369,9 @@ describe("Cell output utility functions", () => {
|
|
|
369
369
|
).mockReturnValue(mockDiv);
|
|
370
370
|
|
|
371
371
|
mockStore = createMockStore({
|
|
372
|
-
cellIds: { inOrderIds: ["test"
|
|
372
|
+
cellIds: { inOrderIds: ["test"] },
|
|
373
373
|
cellData: {
|
|
374
|
-
test: { id: "test"
|
|
374
|
+
test: { id: "test", name: "", code: "" },
|
|
375
375
|
},
|
|
376
376
|
cellRuntime: {
|
|
377
377
|
test: {
|
|
@@ -396,16 +396,16 @@ describe("Cell output utility functions", () => {
|
|
|
396
396
|
beforeEach(() => {
|
|
397
397
|
mockNotebook = {
|
|
398
398
|
cellIds: {
|
|
399
|
-
inOrderIds: ["cell1"
|
|
399
|
+
inOrderIds: ["cell1", "cell2"],
|
|
400
400
|
},
|
|
401
401
|
cellData: {
|
|
402
402
|
cell1: {
|
|
403
|
-
id: "cell1"
|
|
403
|
+
id: "cell1",
|
|
404
404
|
name: "My Named Cell",
|
|
405
405
|
code: "x = 42",
|
|
406
406
|
},
|
|
407
407
|
cell2: {
|
|
408
|
-
id: "cell2"
|
|
408
|
+
id: "cell2",
|
|
409
409
|
name: "",
|
|
410
410
|
code: "y = x * 2",
|
|
411
411
|
},
|
|
@@ -432,7 +432,7 @@ describe("Cell output utility functions", () => {
|
|
|
432
432
|
});
|
|
433
433
|
|
|
434
434
|
it("should extract basic cell data", () => {
|
|
435
|
-
const result = getCellContextData("cell1"
|
|
435
|
+
const result = getCellContextData(cellId("cell1"), mockNotebook);
|
|
436
436
|
|
|
437
437
|
expect(result.cellId).toBe("cell1");
|
|
438
438
|
expect(result.cellName).toBe("My Named Cell");
|
|
@@ -440,13 +440,13 @@ describe("Cell output utility functions", () => {
|
|
|
440
440
|
});
|
|
441
441
|
|
|
442
442
|
it("should generate cell name for unnamed cells", () => {
|
|
443
|
-
const result = getCellContextData("cell2"
|
|
443
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook);
|
|
444
444
|
|
|
445
445
|
expect(result.cellName).toBe("cell-1"); // 0-indexed, so cell2 is at index 1
|
|
446
446
|
});
|
|
447
447
|
|
|
448
448
|
it("should include cell output when present", () => {
|
|
449
|
-
const result = getCellContextData("cell1"
|
|
449
|
+
const result = getCellContextData(cellId("cell1"), mockNotebook);
|
|
450
450
|
|
|
451
451
|
expect(result.cellOutput).toBeDefined();
|
|
452
452
|
expect(result.cellOutput?.outputType).toBe("text");
|
|
@@ -454,19 +454,19 @@ describe("Cell output utility functions", () => {
|
|
|
454
454
|
});
|
|
455
455
|
|
|
456
456
|
it("should not include cell output when not present", () => {
|
|
457
|
-
const result = getCellContextData("cell2"
|
|
457
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook);
|
|
458
458
|
|
|
459
459
|
expect(result.cellOutput).toBeUndefined();
|
|
460
460
|
});
|
|
461
461
|
|
|
462
462
|
it("should not include console outputs by default", () => {
|
|
463
|
-
const result = getCellContextData("cell2"
|
|
463
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook);
|
|
464
464
|
|
|
465
465
|
expect(result.consoleOutputs).toBeUndefined();
|
|
466
466
|
});
|
|
467
467
|
|
|
468
468
|
it("should include console outputs when opted in", () => {
|
|
469
|
-
const result = getCellContextData("cell2"
|
|
469
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook, {
|
|
470
470
|
includeConsoleOutput: true,
|
|
471
471
|
});
|
|
472
472
|
|
|
@@ -478,7 +478,7 @@ describe("Cell output utility functions", () => {
|
|
|
478
478
|
});
|
|
479
479
|
|
|
480
480
|
it("should filter out empty console outputs", () => {
|
|
481
|
-
const cell2Runtime = mockNotebook.cellRuntime["cell2"
|
|
481
|
+
const cell2Runtime = mockNotebook.cellRuntime[cellId("cell2")];
|
|
482
482
|
if (cell2Runtime) {
|
|
483
483
|
(cell2Runtime as { consoleOutputs: OutputMessage[] }).consoleOutputs = [
|
|
484
484
|
{
|
|
@@ -492,7 +492,7 @@ describe("Cell output utility functions", () => {
|
|
|
492
492
|
];
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
const result = getCellContextData("cell2"
|
|
495
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook, {
|
|
496
496
|
includeConsoleOutput: true,
|
|
497
497
|
});
|
|
498
498
|
|
|
@@ -501,7 +501,7 @@ describe("Cell output utility functions", () => {
|
|
|
501
501
|
});
|
|
502
502
|
|
|
503
503
|
it("should handle cells with both cell output and console outputs", () => {
|
|
504
|
-
const cell1Runtime = mockNotebook.cellRuntime["cell1"
|
|
504
|
+
const cell1Runtime = mockNotebook.cellRuntime[cellId("cell1")];
|
|
505
505
|
if (cell1Runtime) {
|
|
506
506
|
(cell1Runtime as { consoleOutputs: OutputMessage[] }).consoleOutputs = [
|
|
507
507
|
{
|
|
@@ -511,7 +511,7 @@ describe("Cell output utility functions", () => {
|
|
|
511
511
|
];
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
-
const result = getCellContextData("cell1"
|
|
514
|
+
const result = getCellContextData(cellId("cell1"), mockNotebook, {
|
|
515
515
|
includeConsoleOutput: true,
|
|
516
516
|
});
|
|
517
517
|
|
|
@@ -524,7 +524,7 @@ describe("Cell output utility functions", () => {
|
|
|
524
524
|
});
|
|
525
525
|
|
|
526
526
|
it("should handle empty console outputs array", () => {
|
|
527
|
-
const result = getCellContextData("cell1"
|
|
527
|
+
const result = getCellContextData(cellId("cell1"), mockNotebook, {
|
|
528
528
|
includeConsoleOutput: true,
|
|
529
529
|
});
|
|
530
530
|
|
|
@@ -532,7 +532,7 @@ describe("Cell output utility functions", () => {
|
|
|
532
532
|
});
|
|
533
533
|
|
|
534
534
|
it("should handle media outputs in cell output", () => {
|
|
535
|
-
const cell1Runtime = mockNotebook.cellRuntime["cell1"
|
|
535
|
+
const cell1Runtime = mockNotebook.cellRuntime[cellId("cell1")];
|
|
536
536
|
if (cell1Runtime) {
|
|
537
537
|
(cell1Runtime as { output: OutputMessage | null }).output = {
|
|
538
538
|
mimetype: "image/png",
|
|
@@ -540,7 +540,7 @@ describe("Cell output utility functions", () => {
|
|
|
540
540
|
} as OutputMessage;
|
|
541
541
|
}
|
|
542
542
|
|
|
543
|
-
const result = getCellContextData("cell1"
|
|
543
|
+
const result = getCellContextData(cellId("cell1"), mockNotebook);
|
|
544
544
|
|
|
545
545
|
expect(result.cellOutput).toBeDefined();
|
|
546
546
|
expect(result.cellOutput?.outputType).toBe("media");
|
|
@@ -548,7 +548,7 @@ describe("Cell output utility functions", () => {
|
|
|
548
548
|
});
|
|
549
549
|
|
|
550
550
|
it("should handle media outputs in console outputs", () => {
|
|
551
|
-
const cell2Runtime = mockNotebook.cellRuntime["cell2"
|
|
551
|
+
const cell2Runtime = mockNotebook.cellRuntime[cellId("cell2")];
|
|
552
552
|
if (cell2Runtime) {
|
|
553
553
|
(cell2Runtime as { consoleOutputs: OutputMessage[] }).consoleOutputs = [
|
|
554
554
|
{
|
|
@@ -558,7 +558,7 @@ describe("Cell output utility functions", () => {
|
|
|
558
558
|
];
|
|
559
559
|
}
|
|
560
560
|
|
|
561
|
-
const result = getCellContextData("cell2"
|
|
561
|
+
const result = getCellContextData(cellId("cell2"), mockNotebook, {
|
|
562
562
|
includeConsoleOutput: true,
|
|
563
563
|
});
|
|
564
564
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
|
|
4
4
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
5
|
-
import
|
|
5
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
6
6
|
import type {
|
|
7
7
|
ConnectionsMap,
|
|
8
8
|
DatasetTablesMap,
|
|
@@ -88,7 +88,7 @@ const createMockDataTable = (
|
|
|
88
88
|
source_type: "local",
|
|
89
89
|
num_rows: 100,
|
|
90
90
|
num_columns: 3,
|
|
91
|
-
variable_name: name, // This makes it a dataframe
|
|
91
|
+
variable_name: variableName(name), // This makes it a dataframe
|
|
92
92
|
columns: [
|
|
93
93
|
{
|
|
94
94
|
name: "id",
|
|
@@ -634,7 +634,7 @@ describe("DatasourceContextProvider", () => {
|
|
|
634
634
|
|
|
635
635
|
describe("getDatasourceContext", () => {
|
|
636
636
|
it("should return null if no cell ID is found", () => {
|
|
637
|
-
const context = getDatasourceContext("1"
|
|
637
|
+
const context = getDatasourceContext(cellId("1"));
|
|
638
638
|
expect(context).toBeNull();
|
|
639
639
|
});
|
|
640
640
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { variableName } from "@/__tests__/branded";
|
|
4
5
|
import type { DatasetTablesMap } from "@/core/datasets/data-source-connections";
|
|
5
6
|
import type { DataTable, DataTableColumn } from "@/core/kernel/messages";
|
|
6
7
|
import { type TableContextItem, TableContextProvider } from "../tables";
|
|
@@ -86,7 +87,7 @@ describe("TableContextProvider", () => {
|
|
|
86
87
|
|
|
87
88
|
it("should handle dataframe tables with variable names", () => {
|
|
88
89
|
const dfTable = createMockTable("df_analysis", {
|
|
89
|
-
variable_name: "df_analysis",
|
|
90
|
+
variable_name: variableName("df_analysis"),
|
|
90
91
|
source: "pandas",
|
|
91
92
|
source_type: "local",
|
|
92
93
|
columns: [
|
|
@@ -180,7 +181,7 @@ describe("TableContextProvider", () => {
|
|
|
180
181
|
const table = createMockTable("remote_table", {
|
|
181
182
|
source: "postgresql://localhost:5432/mydb",
|
|
182
183
|
source_type: "connection",
|
|
183
|
-
engine: "postgresql",
|
|
184
|
+
engine: variableName("postgresql"),
|
|
184
185
|
columns: [
|
|
185
186
|
createMockColumn("uuid", "string", "uuid"),
|
|
186
187
|
createMockColumn("created_at", "string", "timestamp with time zone"),
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
|
|
4
4
|
import { describe, expect, it, vi } from "vitest";
|
|
5
|
-
import
|
|
5
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
6
6
|
import type { DatasetTablesMap } from "@/core/datasets/data-source-connections";
|
|
7
|
-
import type { Variable,
|
|
7
|
+
import type { Variable, Variables } from "@/core/variables/types";
|
|
8
8
|
import { type VariableContextItem, VariableContextProvider } from "../variable";
|
|
9
9
|
|
|
10
10
|
// Mock the variable completions module
|
|
@@ -17,7 +17,7 @@ vi.mock("@/core/codemirror/completion/variable-completions", () => ({
|
|
|
17
17
|
prefix: string,
|
|
18
18
|
) => {
|
|
19
19
|
return Object.entries(variables).map(([name, variable]) => ({
|
|
20
|
-
name: `${prefix}${name}
|
|
20
|
+
name: variableName(`${prefix}${name}`),
|
|
21
21
|
displayname: name,
|
|
22
22
|
detail: variable.dataType || "unknown",
|
|
23
23
|
boost,
|
|
@@ -34,9 +34,9 @@ const createMockVariable = (
|
|
|
34
34
|
name: string,
|
|
35
35
|
options: Partial<Variable> = {},
|
|
36
36
|
): Variable => ({
|
|
37
|
-
name: name
|
|
38
|
-
declaredBy: ["cell1"
|
|
39
|
-
usedBy: ["cell2"
|
|
37
|
+
name: variableName(name),
|
|
38
|
+
declaredBy: [cellId("cell1")],
|
|
39
|
+
usedBy: [cellId("cell2")],
|
|
40
40
|
value: `value_of_${name}`,
|
|
41
41
|
dataType: "str",
|
|
42
42
|
...options,
|
|
@@ -55,10 +55,13 @@ describe("VariableContextProvider", () => {
|
|
|
55
55
|
|
|
56
56
|
it("should return variable items for single variable", () => {
|
|
57
57
|
const variables: Variables = {
|
|
58
|
-
["user_name"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
[variableName("user_name")]: createMockVariable(
|
|
59
|
+
variableName("user_name"),
|
|
60
|
+
{
|
|
61
|
+
value: '"John Doe"',
|
|
62
|
+
dataType: "str",
|
|
63
|
+
},
|
|
64
|
+
),
|
|
62
65
|
};
|
|
63
66
|
const tablesMap: DatasetTablesMap = new Map();
|
|
64
67
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
@@ -69,29 +72,32 @@ describe("VariableContextProvider", () => {
|
|
|
69
72
|
|
|
70
73
|
it("should return variable items for multiple variables with different types", () => {
|
|
71
74
|
const variables: Variables = {
|
|
72
|
-
["user_id"
|
|
75
|
+
[variableName("user_id")]: createMockVariable(variableName("user_id"), {
|
|
73
76
|
value: "123",
|
|
74
77
|
dataType: "int",
|
|
75
|
-
declaredBy: ["cell1"
|
|
76
|
-
usedBy: ["cell2"
|
|
77
|
-
}),
|
|
78
|
-
["is_active" as VariableName]: createMockVariable("is_active", {
|
|
79
|
-
value: "True",
|
|
80
|
-
dataType: "bool",
|
|
81
|
-
declaredBy: ["cell2" as CellId],
|
|
82
|
-
usedBy: [],
|
|
78
|
+
declaredBy: [cellId("cell1")],
|
|
79
|
+
usedBy: [cellId("cell2"), cellId("cell3")],
|
|
83
80
|
}),
|
|
84
|
-
["
|
|
81
|
+
[variableName("is_active")]: createMockVariable(
|
|
82
|
+
variableName("is_active"),
|
|
83
|
+
{
|
|
84
|
+
value: "True",
|
|
85
|
+
dataType: "bool",
|
|
86
|
+
declaredBy: [cellId("cell2")],
|
|
87
|
+
usedBy: [],
|
|
88
|
+
},
|
|
89
|
+
),
|
|
90
|
+
[variableName("scores")]: createMockVariable(variableName("scores"), {
|
|
85
91
|
value: "[1, 2, 3, 4, 5]",
|
|
86
92
|
dataType: "list",
|
|
87
|
-
declaredBy: ["cell3"
|
|
88
|
-
usedBy: ["cell4"
|
|
93
|
+
declaredBy: [cellId("cell3")],
|
|
94
|
+
usedBy: [cellId("cell4")],
|
|
89
95
|
}),
|
|
90
|
-
["config"
|
|
96
|
+
[variableName("config")]: createMockVariable(variableName("config"), {
|
|
91
97
|
value: '{"debug": true, "timeout": 30}',
|
|
92
98
|
dataType: "dict",
|
|
93
|
-
declaredBy: ["cell1"
|
|
94
|
-
usedBy: ["cell2"
|
|
99
|
+
declaredBy: [cellId("cell1")],
|
|
100
|
+
usedBy: [cellId("cell2"), cellId("cell4")],
|
|
95
101
|
}),
|
|
96
102
|
};
|
|
97
103
|
const tablesMap: DatasetTablesMap = new Map();
|
|
@@ -103,18 +109,27 @@ describe("VariableContextProvider", () => {
|
|
|
103
109
|
|
|
104
110
|
it("should handle variables with null/undefined values", () => {
|
|
105
111
|
const variables: Variables = {
|
|
106
|
-
["null_var"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
[variableName("null_var")]: createMockVariable(
|
|
113
|
+
variableName("null_var"),
|
|
114
|
+
{
|
|
115
|
+
value: null,
|
|
116
|
+
dataType: "NoneType",
|
|
117
|
+
},
|
|
118
|
+
),
|
|
119
|
+
[variableName("undefined_var")]: createMockVariable(
|
|
120
|
+
variableName("undefined_var"),
|
|
121
|
+
{
|
|
122
|
+
value: undefined,
|
|
123
|
+
dataType: null,
|
|
124
|
+
},
|
|
125
|
+
),
|
|
126
|
+
[variableName("empty_string")]: createMockVariable(
|
|
127
|
+
variableName("empty_string"),
|
|
128
|
+
{
|
|
129
|
+
value: '""',
|
|
130
|
+
dataType: "str",
|
|
131
|
+
},
|
|
132
|
+
),
|
|
118
133
|
};
|
|
119
134
|
const tablesMap: DatasetTablesMap = new Map();
|
|
120
135
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
@@ -125,23 +140,23 @@ describe("VariableContextProvider", () => {
|
|
|
125
140
|
|
|
126
141
|
it("should handle complex data types", () => {
|
|
127
142
|
const variables: Variables = {
|
|
128
|
-
["df"
|
|
143
|
+
[variableName("df")]: createMockVariable(variableName("df"), {
|
|
129
144
|
value: "<DataFrame shape: (100, 5)>",
|
|
130
145
|
dataType: "pandas.DataFrame",
|
|
131
|
-
declaredBy: ["cell1"
|
|
132
|
-
usedBy: ["cell2"
|
|
146
|
+
declaredBy: [cellId("cell1")],
|
|
147
|
+
usedBy: [cellId("cell2"), cellId("cell3")],
|
|
133
148
|
}),
|
|
134
|
-
["model"
|
|
149
|
+
[variableName("model")]: createMockVariable(variableName("model"), {
|
|
135
150
|
value: "<sklearn.linear_model.LinearRegression>",
|
|
136
151
|
dataType: "sklearn.linear_model._base.LinearRegression",
|
|
137
|
-
declaredBy: ["cell4"
|
|
138
|
-
usedBy: ["cell5"
|
|
152
|
+
declaredBy: [cellId("cell4")],
|
|
153
|
+
usedBy: [cellId("cell5")],
|
|
139
154
|
}),
|
|
140
|
-
["array"
|
|
155
|
+
[variableName("array")]: createMockVariable(variableName("array"), {
|
|
141
156
|
value: "array([1, 2, 3, 4, 5])",
|
|
142
157
|
dataType: "numpy.ndarray",
|
|
143
|
-
declaredBy: ["cell2"
|
|
144
|
-
usedBy: ["cell3"
|
|
158
|
+
declaredBy: [cellId("cell2")],
|
|
159
|
+
usedBy: [cellId("cell3")],
|
|
145
160
|
}),
|
|
146
161
|
};
|
|
147
162
|
const tablesMap: DatasetTablesMap = new Map();
|
|
@@ -153,21 +168,27 @@ describe("VariableContextProvider", () => {
|
|
|
153
168
|
|
|
154
169
|
it("should handle variables with special characters in names", () => {
|
|
155
170
|
const variables: Variables = {
|
|
156
|
-
["_private_var"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
171
|
+
[variableName("_private_var")]: createMockVariable(
|
|
172
|
+
variableName("_private_var"),
|
|
173
|
+
{
|
|
174
|
+
value: "42",
|
|
175
|
+
dataType: "int",
|
|
176
|
+
},
|
|
177
|
+
),
|
|
178
|
+
[variableName("var_with_numbers123")]: createMockVariable(
|
|
179
|
+
variableName("var_with_numbers123"),
|
|
162
180
|
{
|
|
163
181
|
value: '"test"',
|
|
164
182
|
dataType: "str",
|
|
165
183
|
},
|
|
166
184
|
),
|
|
167
|
-
["CONSTANT_VAR"
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
[variableName("CONSTANT_VAR")]: createMockVariable(
|
|
186
|
+
variableName("CONSTANT_VAR"),
|
|
187
|
+
{
|
|
188
|
+
value: "3.14159",
|
|
189
|
+
dataType: "float",
|
|
190
|
+
},
|
|
191
|
+
),
|
|
171
192
|
};
|
|
172
193
|
const tablesMap: DatasetTablesMap = new Map();
|
|
173
194
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
@@ -191,7 +212,7 @@ describe("VariableContextProvider", () => {
|
|
|
191
212
|
data: { variable },
|
|
192
213
|
};
|
|
193
214
|
|
|
194
|
-
const variables: Variables = { ["username"
|
|
215
|
+
const variables: Variables = { [variableName("username")]: variable };
|
|
195
216
|
const tablesMap: DatasetTablesMap = new Map();
|
|
196
217
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
197
218
|
|
|
@@ -213,7 +234,7 @@ describe("VariableContextProvider", () => {
|
|
|
213
234
|
};
|
|
214
235
|
|
|
215
236
|
const variables: Variables = {
|
|
216
|
-
["mystery_var"
|
|
237
|
+
[variableName("mystery_var")]: variable,
|
|
217
238
|
};
|
|
218
239
|
const tablesMap: DatasetTablesMap = new Map();
|
|
219
240
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
@@ -237,7 +258,7 @@ describe("VariableContextProvider", () => {
|
|
|
237
258
|
};
|
|
238
259
|
|
|
239
260
|
const variables: Variables = {
|
|
240
|
-
["complex_data"
|
|
261
|
+
[variableName("complex_data")]: variable,
|
|
241
262
|
};
|
|
242
263
|
const tablesMap: DatasetTablesMap = new Map();
|
|
243
264
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
@@ -260,7 +281,7 @@ describe("VariableContextProvider", () => {
|
|
|
260
281
|
data: { variable },
|
|
261
282
|
};
|
|
262
283
|
|
|
263
|
-
const variables: Variables = { ["sales_df"
|
|
284
|
+
const variables: Variables = { [variableName("sales_df")]: variable };
|
|
264
285
|
const tablesMap: DatasetTablesMap = new Map();
|
|
265
286
|
const provider = new VariableContextProvider(variables, tablesMap);
|
|
266
287
|
|
|
@@ -284,12 +305,12 @@ describe("VariableContextProvider", () => {
|
|
|
284
305
|
describe("integration with tables", () => {
|
|
285
306
|
it("should work with both variables and tables", () => {
|
|
286
307
|
const variables: Variables = {
|
|
287
|
-
["df"
|
|
308
|
+
[variableName("df")]: createMockVariable(variableName("df"), {
|
|
288
309
|
dataType: "pandas.DataFrame",
|
|
289
310
|
value: "<DataFrame shape: (50, 3)>",
|
|
290
311
|
}),
|
|
291
|
-
["connection_string"
|
|
292
|
-
"connection_string",
|
|
312
|
+
[variableName("connection_string")]: createMockVariable(
|
|
313
|
+
variableName("connection_string"),
|
|
293
314
|
{
|
|
294
315
|
dataType: "str",
|
|
295
316
|
value: '"postgresql://localhost:5432/mydb"',
|
|
@@ -5,6 +5,7 @@ import { EditorView } from "@codemirror/view";
|
|
|
5
5
|
import { getDefaultStore } from "jotai";
|
|
6
6
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
7
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
8
|
+
import { cellId } from "@/__tests__/branded";
|
|
8
9
|
import { notebookAtom } from "@/core/cells/cells";
|
|
9
10
|
import type { CellId } from "@/core/cells/ids";
|
|
10
11
|
import { updateEditorCodeFromPython } from "@/core/codemirror/language/utils";
|
|
@@ -32,7 +33,7 @@ function createMockEditorView(code: string): EditorView {
|
|
|
32
33
|
doc: code,
|
|
33
34
|
extensions: [
|
|
34
35
|
adaptiveLanguageConfiguration({
|
|
35
|
-
cellId: "cell1"
|
|
36
|
+
cellId: cellId("cell1"),
|
|
36
37
|
completionConfig: {
|
|
37
38
|
copilot: false,
|
|
38
39
|
activate_on_typing: true,
|
|
@@ -44,7 +45,7 @@ function createMockEditorView(code: string): EditorView {
|
|
|
44
45
|
lspConfig: {},
|
|
45
46
|
}),
|
|
46
47
|
cellConfigExtension({
|
|
47
|
-
cellId: "cell1"
|
|
48
|
+
cellId: cellId("cell1"),
|
|
48
49
|
completionConfig: {
|
|
49
50
|
copilot: false,
|
|
50
51
|
activate_on_typing: true,
|
|
@@ -93,9 +94,9 @@ describe("EditNotebookTool", () => {
|
|
|
93
94
|
};
|
|
94
95
|
tool = new EditNotebookTool();
|
|
95
96
|
|
|
96
|
-
cellId1 = "cell-1"
|
|
97
|
-
cellId2 = "cell-2"
|
|
98
|
-
cellId3 = "cell-3"
|
|
97
|
+
cellId1 = cellId("cell-1");
|
|
98
|
+
cellId2 = cellId("cell-2");
|
|
99
|
+
cellId3 = cellId("cell-3");
|
|
99
100
|
|
|
100
101
|
// Reset mocks
|
|
101
102
|
vi.clearAllMocks();
|
|
@@ -270,7 +271,7 @@ describe("EditNotebookTool", () => {
|
|
|
270
271
|
{
|
|
271
272
|
edit: {
|
|
272
273
|
type: "update_cell",
|
|
273
|
-
position: { cellId: "nonexistent"
|
|
274
|
+
position: { cellId: cellId("nonexistent") },
|
|
274
275
|
code: "x = 2",
|
|
275
276
|
},
|
|
276
277
|
},
|
|
@@ -283,7 +284,7 @@ describe("EditNotebookTool", () => {
|
|
|
283
284
|
{
|
|
284
285
|
edit: {
|
|
285
286
|
type: "update_cell",
|
|
286
|
-
position: { cellId: "nonexistent"
|
|
287
|
+
position: { cellId: cellId("nonexistent") },
|
|
287
288
|
code: "x = 2",
|
|
288
289
|
},
|
|
289
290
|
},
|
|
@@ -496,7 +497,7 @@ describe("EditNotebookTool", () => {
|
|
|
496
497
|
type: "add_cell",
|
|
497
498
|
position: {
|
|
498
499
|
type: "relative",
|
|
499
|
-
cellId: "nonexistent"
|
|
500
|
+
cellId: cellId("nonexistent"),
|
|
500
501
|
before: true,
|
|
501
502
|
},
|
|
502
503
|
code: "y = 2",
|
|
@@ -660,7 +661,7 @@ describe("EditNotebookTool", () => {
|
|
|
660
661
|
{
|
|
661
662
|
edit: {
|
|
662
663
|
type: "delete_cell",
|
|
663
|
-
position: { cellId: "nonexistent"
|
|
664
|
+
position: { cellId: cellId("nonexistent") },
|
|
664
665
|
},
|
|
665
666
|
},
|
|
666
667
|
toolContext as never,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { getDefaultStore } from "jotai";
|
|
4
4
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
5
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
6
|
+
import { cellId } from "@/__tests__/branded";
|
|
6
7
|
import { notebookAtom } from "@/core/cells/cells";
|
|
7
8
|
import type { CellId } from "@/core/cells/ids";
|
|
8
9
|
import { RunStaleCellsTool } from "../run-cells-tool";
|
|
@@ -46,9 +47,9 @@ describe("RunStaleCellsTool", () => {
|
|
|
46
47
|
|
|
47
48
|
tool = new RunStaleCellsTool({ postExecutionDelay: 0 });
|
|
48
49
|
|
|
49
|
-
cellId1 = "cell-1"
|
|
50
|
-
cellId2 = "cell-2"
|
|
51
|
-
cellId3 = "cell-3"
|
|
50
|
+
cellId1 = cellId("cell-1");
|
|
51
|
+
cellId2 = cellId("cell-2");
|
|
52
|
+
cellId3 = cellId("cell-3");
|
|
52
53
|
|
|
53
54
|
// Reset mocks
|
|
54
55
|
vi.clearAllMocks();
|
|
@@ -490,9 +491,8 @@ describe("RunStaleCellsTool", () => {
|
|
|
490
491
|
});
|
|
491
492
|
|
|
492
493
|
it("should omit output for cells that exceed total output budget", async () => {
|
|
493
|
-
const cellIds = Array.from(
|
|
494
|
-
{
|
|
495
|
-
(_, i) => `budget-cell-${i}` as CellId,
|
|
494
|
+
const cellIds = Array.from({ length: 25 }, (_, i) =>
|
|
495
|
+
cellId(`budget-cell-${i}`),
|
|
496
496
|
);
|
|
497
497
|
const cellData: Record<string, { code: string; edited: boolean }> = {};
|
|
498
498
|
for (const id of cellIds) {
|