From b01db7f5b39768dbd9c1719e5bff58e9e4ee6445 Mon Sep 17 00:00:00 2001 From: seveibar Date: Mon, 26 Aug 2024 21:56:34 -0700 Subject: [PATCH] svg snapshot testing --- .../getAllDimensionsForSchematicBox.ts | 60 +++++++++++--- tests/fixtures/extend-expect-any-svg.ts | 79 +++++++++++++++++++ .../schematic_box_test.snapshot.svg | 1 - .../__snapshots__/schematicbox1.snap.svg | 1 + .../getAllDimensionsForSchematicBox.test.ts | 46 ++++------- tests/utils/schematic/getSchematicBoxSvg.ts | 23 ++++++ 6 files changed, 164 insertions(+), 46 deletions(-) create mode 100644 tests/fixtures/extend-expect-any-svg.ts delete mode 100644 tests/utils/schematic/__snapshots__/schematic_box_test.snapshot.svg create mode 100644 tests/utils/schematic/__snapshots__/schematicbox1.snap.svg create mode 100644 tests/utils/schematic/getSchematicBoxSvg.ts diff --git a/lib/utils/schematic/getAllDimensionsForSchematicBox.ts b/lib/utils/schematic/getAllDimensionsForSchematicBox.ts index 9c8464a..ab28a56 100644 --- a/lib/utils/schematic/getAllDimensionsForSchematicBox.ts +++ b/lib/utils/schematic/getAllDimensionsForSchematicBox.ts @@ -28,6 +28,7 @@ export type PortArrangement = SideSizes | ExplicitPinMappingArrangement interface Params { schWidth?: number schHeight?: number + portDistanceFromEdge?: number schPinSpacing: number schPinStyle?: Record< `pin${number}` | number | `${number}`, @@ -78,7 +79,7 @@ interface SchematicBoxDimensions { export const getAllDimensionsForSchematicBox = ( params: Params, ): SchematicBoxDimensions => { - const parsedParams: ParsedParams = { ...params } as any + const portDistanceFromEdge = params.portDistanceFromEdge ?? 0.2 let sideSizes = params.schPortArrangement ? getSizeOfSidesFromPortArrangement(params.schPortArrangement) @@ -247,13 +248,6 @@ export const getAllDimensionsForSchematicBox = ( truePinIndex++ } - console.log(orderedTruePorts, { - leftTotalLength, - rightTotalLength, - topTotalLength, - bottomTotalLength, - }) - // Use lengths to determine schWidth and schHeight let schWidth = params.schWidth if (!schWidth) { @@ -264,22 +258,62 @@ export const getAllDimensionsForSchematicBox = ( schHeight = Math.max(leftTotalLength + 0.2, rightTotalLength + 0.2, 1) } + const trueEdgePositions = { + // Top left corner + left: { + x: -schWidth / 2 - portDistanceFromEdge, + y: leftTotalLength / 2, + }, + // bottom left corner + bottom: { + x: -leftTotalLength / 2, + y: -schHeight / 2 - portDistanceFromEdge, + }, + // bottom right corner + right: { + x: schWidth / 2 + portDistanceFromEdge, + y: -leftTotalLength / 2, + }, + // top right corner + top: { + x: leftTotalLength / 2, + y: schHeight / 2 + portDistanceFromEdge, + }, + } + + const trueEdgeTraversalDirections = { + left: { x: 0, y: -1 }, + right: { x: 0, y: 1 }, + top: { x: -1, y: 0 }, + bottom: { x: 1, y: 0 }, + } + const truePortsWithPositions = orderedTruePorts.map((p) => { - const { distanceFromEdge, trueIndex, pinNumber, side } = p - let x: number - let y: number + const { distanceFromEdge, side } = p + const edgePos = trueEdgePositions[side] + const edgeDir = trueEdgeTraversalDirections[side] return { + x: edgePos.x + distanceFromEdge * edgeDir.x, + y: edgePos.y + distanceFromEdge * edgeDir.y, ...p, } }) return { getPortPositionByPinNumber(pinNumber: number): { x: number; y: number } { - return { x: 0, y: 0 } + const port = truePortsWithPositions.find( + (p) => p.pinNumber.toString() === pinNumber.toString(), + ) + if (!port) { + throw new Error( + `Could not find port for pin number ${pinNumber}, available pins: ${truePortsWithPositions.map((tp) => tp.pinNumber).join(", ")}`, + ) + } + return port }, getSize(): { width: number; height: number } { - return { width: 10, height: 10 } + return { width: schWidth, height: schHeight } }, } } diff --git a/tests/fixtures/extend-expect-any-svg.ts b/tests/fixtures/extend-expect-any-svg.ts new file mode 100644 index 0000000..0f33995 --- /dev/null +++ b/tests/fixtures/extend-expect-any-svg.ts @@ -0,0 +1,79 @@ +import { expect, type MatcherResult } from "bun:test" +import * as fs from "node:fs" +import * as path from "node:path" +import looksSame from "looks-same" + +async function toMatchSvgSnapshot( + this: any, + received: string, + testPathOriginal: string, + svgName?: string, +): Promise { + const testPath = testPathOriginal.replace(/\.test\.tsx?$/, "") + const snapshotDir = path.join(path.dirname(testPath), "__snapshots__") + const snapshotName = svgName + ? `${svgName}.snap.svg` + : `${path.basename(testPath)}.snap.svg` + const filePath = path.join(snapshotDir, snapshotName) + + if (!fs.existsSync(snapshotDir)) { + fs.mkdirSync(snapshotDir, { recursive: true }) + } + + const updateSnapshot = + process.argv.includes("--update-snapshots") || + process.argv.includes("-u") || + Boolean(process.env.BUN_UPDATE_SNAPSHOTS) + + if (!fs.existsSync(filePath) || updateSnapshot) { + fs.writeFileSync(filePath, received) + return { + message: () => `Snapshot created at ${filePath}`, + pass: true, + } + } + + const existingSnapshot = fs.readFileSync(filePath, "utf-8") + + const result = await looksSame( + Buffer.from(received), + Buffer.from(existingSnapshot), + { + strict: false, + tolerance: 2, + }, + ) + + if (result.equal) { + return { + message: () => "Snapshot matches", + pass: true, + } + } + + const diffPath = filePath.replace(".snap.svg", ".diff.png") + await looksSame.createDiff({ + reference: Buffer.from(existingSnapshot), + current: Buffer.from(received), + diff: diffPath, + highlightColor: "#ff00ff", + }) + + return { + message: () => `Snapshot does not match. Diff saved at ${diffPath}`, + pass: false, + } +} + +expect.extend({ + toMatchSvgSnapshot: toMatchSvgSnapshot as any, +}) + +declare module "bun:test" { + interface Matchers { + toMatchSvgSnapshot( + testPath: string, + svgName?: string, + ): Promise + } +} diff --git a/tests/utils/schematic/__snapshots__/schematic_box_test.snapshot.svg b/tests/utils/schematic/__snapshots__/schematic_box_test.snapshot.svg deleted file mode 100644 index bf05204..0000000 --- a/tests/utils/schematic/__snapshots__/schematic_box_test.snapshot.svg +++ /dev/null @@ -1 +0,0 @@ -12345678 \ No newline at end of file diff --git a/tests/utils/schematic/__snapshots__/schematicbox1.snap.svg b/tests/utils/schematic/__snapshots__/schematicbox1.snap.svg new file mode 100644 index 0000000..c2e6478 --- /dev/null +++ b/tests/utils/schematic/__snapshots__/schematicbox1.snap.svg @@ -0,0 +1 @@ +12345678 \ No newline at end of file diff --git a/tests/utils/schematic/getAllDimensionsForSchematicBox.test.ts b/tests/utils/schematic/getAllDimensionsForSchematicBox.test.ts index 5e103ae..9651d96 100644 --- a/tests/utils/schematic/getAllDimensionsForSchematicBox.test.ts +++ b/tests/utils/schematic/getAllDimensionsForSchematicBox.test.ts @@ -1,38 +1,20 @@ import { expect, test, describe } from "bun:test" import { getAllDimensionsForSchematicBox } from "lib/utils/schematic/getAllDimensionsForSchematicBox" -import fs from "node:fs" +import { getSchematicBoxSvg } from "./getSchematicBoxSvg" +import "tests/fixtures/extend-expect-any-svg" -describe("getAllDimensionsForSchematicBox", () => { - test("should correctly calculate dimensions and generate SVG", () => { - const params: Parameters[0] = { - schWidth: 1, - schPinSpacing: 0.2, - schPinStyle: {}, - pinCount: 8, - } +test("getAllDimensionsForSchematicBox 1", () => { + const params: Parameters[0] = { + schWidth: 1, + schPinSpacing: 0.2, + schPinStyle: {}, + pinCount: 8, + } - const dimensions = getAllDimensionsForSchematicBox(params) - const size = dimensions.getSize() + const dimensions = getAllDimensionsForSchematicBox(params) - // Generate SVG - let svg = `` - - // Draw the box - svg += `` - - // Draw the pins - for (let i = 1; i <= 8; i++) { - const pos = dimensions.getPortPositionByPinNumber(i) - svg += `` - svg += `${i}` - } - - svg += "" - - // Save SVG to file - fs.writeFileSync( - `${import.meta.dir}/__snapshots__/schematic_box_test.snapshot.svg`, - svg, - ) - }) + expect(getSchematicBoxSvg(dimensions)).toMatchSvgSnapshot( + import.meta.path, + "schematicbox1", + ) }) diff --git a/tests/utils/schematic/getSchematicBoxSvg.ts b/tests/utils/schematic/getSchematicBoxSvg.ts new file mode 100644 index 0000000..e547c17 --- /dev/null +++ b/tests/utils/schematic/getSchematicBoxSvg.ts @@ -0,0 +1,23 @@ +import type { getAllDimensionsForSchematicBox } from "lib/utils/schematic/getAllDimensionsForSchematicBox" + +const MARGIN = 1 + +export const getSchematicBoxSvg = ( + dimensions: ReturnType, +) => { + const size = dimensions.getSize() + let svg = `` + + // Draw the box + svg += `` + + // Draw the pins + for (let i = 1; i <= 8; i++) { + const pos = dimensions.getPortPositionByPinNumber(i) + svg += `` + svg += `${i}` + } + + svg += "" + return svg +}