bun-match-svg 0.0.2 → 0.0.4
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/index.ts +91 -0
- package/package.json +1 -1
- package/tests/toMatchMultipleSvgSnapshots.test.ts +59 -0
package/index.ts
CHANGED
|
@@ -68,9 +68,96 @@ async function toMatchSvgSnapshot(
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
async function toMatchMultipleSvgSnapshots(
|
|
72
|
+
// biome-ignore lint/suspicious/noExplicitAny: bun doesn't expose
|
|
73
|
+
this: any,
|
|
74
|
+
receivedMaybePromise: string[] | Promise<string[]>,
|
|
75
|
+
testPathOriginal: string,
|
|
76
|
+
svgNames: string[],
|
|
77
|
+
): Promise<MatcherResult> {
|
|
78
|
+
const passed = []
|
|
79
|
+
const failed = []
|
|
80
|
+
for (let index = 0; index < svgNames.length; index++) {
|
|
81
|
+
const svgName = svgNames[index]
|
|
82
|
+
const received = await receivedMaybePromise
|
|
83
|
+
const testPath = testPathOriginal.replace(/\.test\.tsx?$/, "")
|
|
84
|
+
const snapshotDir = path.join(path.dirname(testPath), "__snapshots__")
|
|
85
|
+
const snapshotName = svgName
|
|
86
|
+
? `${svgName}.snap.svg`
|
|
87
|
+
: `${path.basename(testPath)}.snap.svg`
|
|
88
|
+
const filePath = path.join(snapshotDir, snapshotName)
|
|
89
|
+
|
|
90
|
+
if (!fs.existsSync(snapshotDir)) {
|
|
91
|
+
fs.mkdirSync(snapshotDir, { recursive: true })
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const updateSnapshot =
|
|
95
|
+
process.argv.includes("--update-snapshots") ||
|
|
96
|
+
process.argv.includes("-u") ||
|
|
97
|
+
Boolean(process.env.BUN_UPDATE_SNAPSHOTS)
|
|
98
|
+
|
|
99
|
+
if (!fs.existsSync(filePath) || updateSnapshot) {
|
|
100
|
+
console.log("Writing snapshot to", filePath)
|
|
101
|
+
fs.writeFileSync(filePath, received[index] as any)
|
|
102
|
+
passed.push({
|
|
103
|
+
message: `Snapshot ${svgName} created at ${filePath}`,
|
|
104
|
+
pass: true,
|
|
105
|
+
})
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const existingSnapshot = fs.readFileSync(filePath, "utf-8")
|
|
110
|
+
|
|
111
|
+
const result = await looksSame(
|
|
112
|
+
Buffer.from(received[index]),
|
|
113
|
+
Buffer.from(existingSnapshot),
|
|
114
|
+
{
|
|
115
|
+
strict: false,
|
|
116
|
+
tolerance: 2,
|
|
117
|
+
},
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if (result.equal) {
|
|
121
|
+
passed.push({
|
|
122
|
+
message: `Snapshot ${svgName} matches`,
|
|
123
|
+
pass: true,
|
|
124
|
+
})
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const diffPath = filePath.replace(".snap.svg", ".diff.png")
|
|
129
|
+
await looksSame.createDiff({
|
|
130
|
+
reference: Buffer.from(existingSnapshot),
|
|
131
|
+
current: Buffer.from(received[index]),
|
|
132
|
+
diff: diffPath,
|
|
133
|
+
highlightColor: "#ff00ff",
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
failed.push({
|
|
137
|
+
message: `Snapshot ${svgName} does not match. Diff saved at ${diffPath}`,
|
|
138
|
+
pass: false,
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
let aggregatedMessage = ""
|
|
142
|
+
if (failed.length === 0) {
|
|
143
|
+
for (const result of passed) aggregatedMessage += `${result.message}\n`
|
|
144
|
+
return {
|
|
145
|
+
pass: true,
|
|
146
|
+
message: () => aggregatedMessage,
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
for (const result of failed) aggregatedMessage += `${result.message}\n`
|
|
150
|
+
return {
|
|
151
|
+
pass: false,
|
|
152
|
+
message: () => aggregatedMessage,
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
71
156
|
expect.extend({
|
|
72
157
|
// biome-ignore lint/suspicious/noExplicitAny:
|
|
73
158
|
toMatchSvgSnapshot: toMatchSvgSnapshot as any,
|
|
159
|
+
// biome-ignore lint/suspicious/noExplicitAny:
|
|
160
|
+
toMatchMultipleSvgSnapshots: toMatchMultipleSvgSnapshots as any,
|
|
74
161
|
})
|
|
75
162
|
|
|
76
163
|
declare module "bun:test" {
|
|
@@ -79,5 +166,9 @@ declare module "bun:test" {
|
|
|
79
166
|
testPath: string,
|
|
80
167
|
svgName?: string,
|
|
81
168
|
): Promise<MatcherResult>
|
|
169
|
+
toMatchMultipleSvgSnapshots(
|
|
170
|
+
testPath: string,
|
|
171
|
+
svgNames?: string[],
|
|
172
|
+
): Promise<MatcherResult>
|
|
82
173
|
}
|
|
83
174
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { expect, test, beforeAll, afterAll } from "bun:test"
|
|
2
|
+
import * as fs from "node:fs"
|
|
3
|
+
import * as path from "node:path"
|
|
4
|
+
import "../index"
|
|
5
|
+
|
|
6
|
+
const testSvgs = [
|
|
7
|
+
`<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
|
|
8
|
+
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
|
|
9
|
+
</svg>`,
|
|
10
|
+
`<svg width="400" height="110" xmlns="http://www.w3.org/2000/svg">
|
|
11
|
+
<defs>
|
|
12
|
+
<pattern id="patt1" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
|
|
13
|
+
<circle cx="10" cy="10" r="10" fill="red" />
|
|
14
|
+
</pattern>
|
|
15
|
+
</defs>
|
|
16
|
+
|
|
17
|
+
<rect width="200" height="100" x="0" y="0" stroke="black" fill="url(#patt1)" />
|
|
18
|
+
</svg>
|
|
19
|
+
`,
|
|
20
|
+
`<svg height="220" width="500" xmlns="http://www.w3.org/2000/svg">
|
|
21
|
+
<polygon points="100,10 150,190 50,190" style="fill:lime;stroke:purple;stroke-width:3" />
|
|
22
|
+
</svg>`,
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const svgNames: string[] = []
|
|
26
|
+
for (let i = 0; i < testSvgs.length; i++) svgNames.push(`test${i + 1}`)
|
|
27
|
+
|
|
28
|
+
const snapshotDir = path.join(__dirname, "__snapshots__")
|
|
29
|
+
const snapshotPaths = svgNames.map((svgName) =>
|
|
30
|
+
path.join(snapshotDir, `${svgName}.snap.svg`),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
beforeAll(() => {
|
|
34
|
+
if (!fs.existsSync(snapshotDir)) {
|
|
35
|
+
fs.mkdirSync(snapshotDir, { recursive: true })
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
afterAll(() => {
|
|
40
|
+
for (const snapshotPath of snapshotPaths)
|
|
41
|
+
if (fs.existsSync(snapshotPath)) {
|
|
42
|
+
fs.unlinkSync(snapshotPath)
|
|
43
|
+
}
|
|
44
|
+
if (fs.existsSync(snapshotDir)) {
|
|
45
|
+
fs.rmdirSync(snapshotDir, { recursive: true })
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test("toMatchMultipleSvgSnapshots creates and matches snapshots", async () => {
|
|
50
|
+
// First run: create snapshot
|
|
51
|
+
await expect(testSvgs).toMatchMultipleSvgSnapshots(import.meta.path, svgNames)
|
|
52
|
+
|
|
53
|
+
// Verify snapshot was created
|
|
54
|
+
for (const snapshotPath of snapshotPaths)
|
|
55
|
+
expect(fs.existsSync(snapshotPath)).toBe(true)
|
|
56
|
+
|
|
57
|
+
// Second run: match existing snapshot
|
|
58
|
+
await expect(testSvgs).toMatchMultipleSvgSnapshots(import.meta.path, svgNames)
|
|
59
|
+
})
|