Skip to content

Commit

Permalink
added toMatchMultipleSvgSnapshot (#2)
Browse files Browse the repository at this point in the history
* toMatchMultipleSvgSnapshots and test
  • Loading branch information
ShiboSoftwareDev authored Sep 3, 2024
1 parent bfbf180 commit 22e8380
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
91 changes: 91 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,96 @@ async function toMatchSvgSnapshot(
}
}

async function toMatchMultipleSvgSnapshots(
// biome-ignore lint/suspicious/noExplicitAny: bun doesn't expose
this: any,
receivedMaybePromise: string[] | Promise<string[]>,
testPathOriginal: string,
svgNames: string[],
): Promise<MatcherResult> {
const passed = []
const failed = []
for (let index = 0; index < svgNames.length; index++) {
const svgName = svgNames[index]
const received = await receivedMaybePromise
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) {
console.log("Writing snapshot to", filePath)
fs.writeFileSync(filePath, received[index])
passed.push({
message: `Snapshot ${svgName} created at ${filePath}`,
pass: true,
})
continue
}

const existingSnapshot = fs.readFileSync(filePath, "utf-8")

const result = await looksSame(
Buffer.from(received[index]),
Buffer.from(existingSnapshot),
{
strict: false,
tolerance: 2,
},
)

if (result.equal) {
passed.push({
message: `Snapshot ${svgName} matches`,
pass: true,
})
continue
}

const diffPath = filePath.replace(".snap.svg", ".diff.png")
await looksSame.createDiff({
reference: Buffer.from(existingSnapshot),
current: Buffer.from(received[index]),
diff: diffPath,
highlightColor: "#ff00ff",
})

failed.push({
message: `Snapshot ${svgName} does not match. Diff saved at ${diffPath}`,
pass: false,
})
}
let aggregatedMessage = ""
if (failed.length === 0) {
for (const result of passed) aggregatedMessage += `${result.message}\n`
return {
pass: true,
message: () => aggregatedMessage,
}
}
for (const result of failed) aggregatedMessage += `${result.message}\n`
return {
pass: false,
message: () => aggregatedMessage,
}
}

expect.extend({
// biome-ignore lint/suspicious/noExplicitAny:
toMatchSvgSnapshot: toMatchSvgSnapshot as any,
// biome-ignore lint/suspicious/noExplicitAny:
toMatchMultipleSvgSnapshots: toMatchMultipleSvgSnapshots as any,
})

declare module "bun:test" {
Expand All @@ -79,5 +166,9 @@ declare module "bun:test" {
testPath: string,
svgName?: string,
): Promise<MatcherResult>
toMatchMultipleSvgSnapshots(
testPath: string,
svgNames?: string[],
): Promise<MatcherResult>
}
}
59 changes: 59 additions & 0 deletions tests/toMatchMultipleSvgSnapshots.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { expect, test, beforeAll, afterAll } from "bun:test"
import * as fs from "node:fs"
import * as path from "node:path"
import "../index"

const testSvgs = [
`<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>`,
`<svg width="400" height="110" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="patt1" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" fill="red" />
</pattern>
</defs>
<rect width="200" height="100" x="0" y="0" stroke="black" fill="url(#patt1)" />
</svg>
`,
`<svg height="220" width="500" xmlns="http://www.w3.org/2000/svg">
<polygon points="100,10 150,190 50,190" style="fill:lime;stroke:purple;stroke-width:3" />
</svg>`,
]

const svgNames: string[] = []
for (let i = 0; i < testSvgs.length; i++) svgNames.push(`test${i + 1}`)

const snapshotDir = path.join(__dirname, "__snapshots__")
const snapshotPaths = svgNames.map((svgName) =>
path.join(snapshotDir, `${svgName}.snap.svg`),
)

beforeAll(() => {
if (!fs.existsSync(snapshotDir)) {
fs.mkdirSync(snapshotDir, { recursive: true })
}
})

afterAll(() => {
for (const snapshotPath of snapshotPaths)
if (fs.existsSync(snapshotPath)) {
fs.unlinkSync(snapshotPath)
}
if (fs.existsSync(snapshotDir)) {
fs.rmdirSync(snapshotDir, { recursive: true })
}
})

test("toMatchMultipleSvgSnapshots creates and matches snapshots", async () => {
// First run: create snapshot
await expect(testSvgs).toMatchMultipleSvgSnapshots(import.meta.path, svgNames)

// Verify snapshot was created
for (const snapshotPath of snapshotPaths)
expect(fs.existsSync(snapshotPath)).toBe(true)

// Second run: match existing snapshot
await expect(testSvgs).toMatchMultipleSvgSnapshots(import.meta.path, svgNames)
})

0 comments on commit 22e8380

Please sign in to comment.