@@ -58,6 +58,6 @@ test("PWA theme, offline reload, and manifest", async ({
|
||||
const m = await request.get("/deep/nested/flow/toolbox-app.json");
|
||||
await expect(m.json()).resolves.toMatchObject({
|
||||
id: "de.add-ideas.flow-tools",
|
||||
version: "0.1.0",
|
||||
version: "0.2.0",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("keeps the primary workspace inside a narrow viewport", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/deep/nested/flow/");
|
||||
await expect(page.locator("main").first()).toBeVisible();
|
||||
await expect(
|
||||
page.locator("main .loading, main .workbench-loading"),
|
||||
).toHaveCount(0);
|
||||
|
||||
const widths = await page.evaluate(() => ({
|
||||
content: document.documentElement.scrollWidth,
|
||||
viewport: document.documentElement.clientWidth,
|
||||
}));
|
||||
expect(widths.viewport).toBeLessThanOrEqual(430);
|
||||
expect(widths.content).toBeLessThanOrEqual(widths.viewport + 1);
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
importRecipe,
|
||||
records,
|
||||
renderPipelineSvg,
|
||||
runPipeline,
|
||||
type Stage,
|
||||
} from "../../src/core/pipeline";
|
||||
@@ -55,5 +56,55 @@ describe("pipeline", () => {
|
||||
'{"schema":"de.add-ideas.flow-tools.recipe.v1","stages":[{"type":"javascript","config":{}}]}',
|
||||
),
|
||||
).toThrow(/Invalid recipe/iu);
|
||||
expect(() =>
|
||||
importRecipe(
|
||||
'{"schema":"de.add-ideas.flow-tools.recipe.v1","stages":[{"id":"same","type":"sort","enabled":true,"config":{}},{"id":"same","type":"sort","enabled":true,"config":{}}]}',
|
||||
),
|
||||
).toThrow(/safe unique id/iu);
|
||||
});
|
||||
it("deduplicates, explodes arrays and slices deterministically", () => {
|
||||
const result = runPipeline(
|
||||
records([
|
||||
{ id: 1, tags: ["a", "b"] },
|
||||
{ id: 1, tags: ["a", "b"] },
|
||||
{ id: 2, tags: ["c"] },
|
||||
]),
|
||||
[
|
||||
{
|
||||
id: "d",
|
||||
type: "deduplicate",
|
||||
enabled: true,
|
||||
config: { fields: "id" },
|
||||
},
|
||||
{
|
||||
id: "e",
|
||||
type: "explode",
|
||||
enabled: true,
|
||||
config: { field: "tags", target: "tag" },
|
||||
},
|
||||
{
|
||||
id: "s",
|
||||
type: "slice",
|
||||
enabled: true,
|
||||
config: { offset: "1", count: "2" },
|
||||
},
|
||||
],
|
||||
);
|
||||
expect(result.rows.map((row) => row.tag)).toEqual(["b", "c"]);
|
||||
expect(result.analysis).toMatchObject({
|
||||
inputRows: 3,
|
||||
outputRows: 2,
|
||||
duplicateRows: 1,
|
||||
});
|
||||
expect(result.snapshots.at(-1)?.losses).toContain(
|
||||
"1 rows fall outside the selected slice.",
|
||||
);
|
||||
});
|
||||
it("exports an inert pipeline SVG", () => {
|
||||
const svg = renderPipelineSvg([
|
||||
{ id: "x", type: "map", enabled: true, config: {} },
|
||||
]);
|
||||
expect(svg).toContain("Flow pipeline");
|
||||
expect(svg).not.toContain("<script");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user