Skip to content

Commit 8ba501d

Browse files
authored
test(native): map socket-patch snapshot refresh (#1718)
1 parent bbd2fd2 commit 8ba501d

6 files changed

Lines changed: 114 additions & 18 deletions

File tree

‎scripts/test/snapshot-dependencies.mts‎

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface SnapshotDependency {
88
readonly source: string
99
readonly versionPattern: RegExp
1010
readonly snapshots: readonly string[]
11+
readonly versionSnapshots?: readonly string[]
1112
readonly testNamePattern: string
1213
}
1314

@@ -23,9 +24,29 @@ export const SNAPSHOT_DEPENDENCIES = {
2324
],
2425
testNamePattern: 'captures native help for (fix|scan create|scan reach)',
2526
},
27+
patch: {
28+
packageName: '@socketsecurity/socket-patch',
29+
source: 'package.json',
30+
versionPattern: /"@socketsecurity\/socket-patch"\s*:\s*"([^"]+)"/,
31+
snapshots: [
32+
'test/native-snapshots/socket-patch-apply-help.help.svg',
33+
'test/native-snapshots/socket-patch-rollback-help.help.svg',
34+
'test/native-snapshots/socket-patch-get-help.help.svg',
35+
'test/native-snapshots/socket-patch-scan-help.help.svg',
36+
'test/native-snapshots/socket-patch-list-help.help.svg',
37+
'test/native-snapshots/socket-patch-remove-help.help.svg',
38+
'test/native-snapshots/socket-patch-setup-help.help.svg',
39+
'test/native-snapshots/socket-patch-repair-help.help.svg',
40+
'test/native-snapshots/socket-patch-version.version.svg',
41+
],
42+
versionSnapshots: ['test/native-snapshots/socket-patch-version.version.svg'],
43+
testNamePattern:
44+
'captures bundled patch help for (apply|rollback|get|scan|list|remove|setup|repair)|captures bundled socket-patch version',
45+
},
2646
} as const satisfies Record<string, SnapshotDependency>
2747

28-
export type SnapshotDependencyName = keyof typeof SNAPSHOT_DEPENDENCIES
48+
export type SnapshotDependencyName = 'coana' | 'patch' | 'socket-patch'
49+
type SnapshotDependencyMapName = keyof typeof SNAPSHOT_DEPENDENCIES
2950

3051
export interface StaleSnapshotDependency {
3152
readonly dependencyName: SnapshotDependencyName
@@ -38,7 +59,10 @@ export async function findStaleSnapshotDependencies(): Promise<
3859
StaleSnapshotDependency[]
3960
> {
4061
const findings = await Promise.all(
41-
Object.entries(SNAPSHOT_DEPENDENCIES).map(async ([name, dependency]) => {
62+
(Object.entries(SNAPSHOT_DEPENDENCIES) as Array<[
63+
string,
64+
SnapshotDependency,
65+
]>).map(async ([name, dependency]) => {
4266
const source = await fs.readFile(
4367
path.join(ROOT, dependency.source),
4468
'utf8',
@@ -49,8 +73,9 @@ export async function findStaleSnapshotDependencies(): Promise<
4973
`Could not read ${dependency.packageName} version from ${dependency.source}`,
5074
)
5175
}
76+
const versionSnapshots = dependency.versionSnapshots ?? dependency.snapshots
5277
const snapshots = await Promise.all(
53-
dependency.snapshots.map(async snapshot => ({
78+
versionSnapshots.map(async snapshot => ({
5479
path: snapshot,
5580
contents: await fs.readFile(path.join(ROOT, snapshot), 'utf8'),
5681
})),
@@ -60,10 +85,13 @@ export async function findStaleSnapshotDependencies(): Promise<
6085
.map(snapshot => snapshot.path)
6186
if (staleSnapshots.length) {
6287
return {
63-
dependencyName: name as SnapshotDependencyName,
88+
dependencyName:
89+
name === 'patch' ? 'socket-patch' : (name as SnapshotDependencyName),
6490
packageName: dependency.packageName,
6591
version,
66-
snapshots: staleSnapshots,
92+
snapshots: dependency.versionSnapshots
93+
? dependency.snapshots
94+
: staleSnapshots,
6795
}
6896
}
6997
return undefined
@@ -78,6 +106,14 @@ export async function findStaleSnapshotDependencies(): Promise<
78106
return stale
79107
}
80108

109+
export function normalizeSnapshotDependencyName(
110+
name: string,
111+
): SnapshotDependencyMapName | undefined {
112+
if (name === 'socket-patch') {return 'patch'}
113+
if (name === 'coana' || name === 'patch') {return name}
114+
return undefined
115+
}
116+
81117
export function snapshotDependencyUpdateHint(
82118
stale: readonly StaleSnapshotDependency[],
83119
): string {

‎scripts/test/snapshots.mts‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import process from 'node:process'
66
import {
77
SNAPSHOT_DEPENDENCIES,
88
assertSnapshotDependenciesCurrent,
9+
normalizeSnapshotDependencyName,
910
} from './snapshot-dependencies.mts'
1011
import { isMainModule } from '../lib/is-main-module.mts'
1112
import { runMain } from '../lib/run-main.mts'
@@ -31,9 +32,9 @@ export interface SnapshotOptions {
3132
function missingSnapshotDependencyError(): Error {
3233
return new Error(
3334
'Provide a dependency name. Usage: pnpm snapshots:update:dep <name>. ' +
34-
'Current example: pnpm snapshots:update:dep coana. ' +
35-
'Partner names to map: socket-patch, socket-python-cli. ' +
36-
`Currently mapped: ${Object.keys(SNAPSHOT_DEPENDENCIES).join(', ')}.`,
35+
'Examples: pnpm snapshots:update:dep coana, pnpm snapshots:update:dep socket-patch, or pnpm snapshots:update:dep patch. ' +
36+
'Socket Python CLI still needs a snapshot mapping. ' +
37+
`Currently mapped: ${Object.keys(SNAPSHOT_DEPENDENCIES).join(', ')}, socket-patch.`,
3738
)
3839
}
3940

@@ -49,9 +50,10 @@ export function parseSnapshotArgs(args: readonly string[]): SnapshotOptions {
4950
if (!value?.trim()) {
5051
throw missingSnapshotDependencyError()
5152
}
52-
if (!(value in SNAPSHOT_DEPENDENCIES)) {
53+
const normalizedName = normalizeSnapshotDependencyName(value)
54+
if (!normalizedName) {
5355
throw new Error(
54-
`Unknown snapshot dependency: ${value}; available: ${Object.keys(SNAPSHOT_DEPENDENCIES).join(', ')}`,
56+
`Unknown snapshot dependency: ${value}; available: coana, socket-patch, patch`,
5557
)
5658
}
5759
if (dependencyName) {
@@ -75,7 +77,8 @@ export function nativeSnapshotArgs(update: boolean): string[] {
7577
export function dependencySnapshotArgs(
7678
dependencyName: SnapshotDependencyName,
7779
): string[] {
78-
const config = SNAPSHOT_DEPENDENCIES[dependencyName]
80+
const config =
81+
SNAPSHOT_DEPENDENCIES[normalizeSnapshotDependencyName(dependencyName)!]
7982
return [
8083
'--build',
8184
'test/native/commands/cli.native.test.mts',
@@ -165,6 +168,7 @@ export interface SnapshotWorkflowDependencies {
165168
acquireLock(): Promise<void>
166169
releaseLock(): Promise<void>
167170
createArtifactsDir(): Promise<string>
171+
assertDependenciesCurrent(): Promise<void>
168172
runNative(update: boolean, artifactsDir: string): void
169173
runDependencyNative(dependencyName: SnapshotDependencyName, artifactsDir: string): void
170174
runTerminal(update: boolean, artifactsDir: string): void
@@ -198,6 +202,7 @@ const DEFAULT_DEPENDENCIES: SnapshotWorkflowDependencies = {
198202
),
199203
)
200204
},
205+
assertDependenciesCurrent: assertSnapshotDependenciesCurrent,
201206
runNative(update, artifactsDir) {
202207
run(['scripts/test/native.mts', ...nativeSnapshotArgs(update)], {
203208
env: { ...process.env, SOCKET_CLI_NATIVE_TEST_ARTIFACTS: artifactsDir },
@@ -246,7 +251,7 @@ export async function runSnapshotWorkflow(
246251
dependencies.runDependencyNative(selectedDependencyName, artifactsDir)
247252
} else {
248253
if (!update) {
249-
await assertSnapshotDependenciesCurrent()
254+
await dependencies.assertDependenciesCurrent()
250255
}
251256
dependencies.runNative(update, artifactsDir)
252257
dependencies.runTerminal(update, artifactsDir)
@@ -269,13 +274,13 @@ const SCRIPT_META: ScriptMeta = {
269274
describe: 'builds, runs, and reports native terminal snapshot tests',
270275
help: `Usage: pnpm snapshots [--update|-u]
271276
pnpm snapshots:update
272-
pnpm snapshots:update:dep <name>
277+
pnpm snapshots:update:dep <name> (coana, socket-patch, patch)
273278
274279
Builds the native CLI, runs the focused terminal screenshot tests, and writes
275280
a self-contained HTML report into a fresh build/native-test-artifacts folder.
276281
Pass --update or -u to update the native screenshot baselines. Use the dep
277282
command to rebuild and update only snapshots affected by a pinned tool, for
278-
example: pnpm snapshots:update:dep coana.`,
283+
example: pnpm snapshots:update:dep socket-patch.`,
279284
}
280285

281286
if (isMainModule(import.meta.url)) {

‎test/native-snapshots/socket-patch-version.version.svg‎

Lines changed: 9 additions & 0 deletions
Loading

‎test/native/commands/cli.native.test.mts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { promises as fs } from 'node:fs'
12
import path from 'node:path'
23

34
import { describe, expect, it } from 'vitest'
@@ -151,6 +152,20 @@ for (const patchCommand of [
151152
}, 60_000)
152153
}
153154

155+
it('captures bundled socket-patch version', async () => {
156+
const packageMetadata = JSON.parse(
157+
await fs.readFile(path.join(process.cwd(), 'package.json'), 'utf8'),
158+
) as { dependencies: { '@socketsecurity/socket-patch': string } }
159+
await captureFlow({
160+
flow: 'socket-patch-version',
161+
args: ['patch', '--version'],
162+
expectedText: `socket-patch ${packageMetadata.dependencies['@socketsecurity/socket-patch']}`,
163+
exitCode: 0,
164+
rows: 12,
165+
checkpointName: 'version',
166+
})
167+
}, 30_000)
168+
154169
describe('native Socket CLI', () => {
155170
it('reports the version embedded in the SEA manifest', async () => {
156171
await captureFlow({

‎test/unit/scripts/test/snapshot-dependencies.test.mts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import { describe, expect, it } from 'vitest'
22

3-
import { snapshotDependencyUpdateHint } from '../../../../scripts/test/snapshot-dependencies.mts'
3+
import {
4+
findStaleSnapshotDependencies,
5+
snapshotDependencyUpdateHint,
6+
} from '../../../../scripts/test/snapshot-dependencies.mts'
47

58
describe('snapshot dependency hints', () => {
9+
it('matches pinned Coana and socket-patch versions in their snapshots', async () => {
10+
await expect(findStaleSnapshotDependencies()).resolves.toEqual([])
11+
})
12+
613
it('lists stale files and the focused refresh command', () => {
714
expect(
815
snapshotDependencyUpdateHint([

‎test/unit/scripts/test/snapshots.test.mts‎

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,19 @@ describe('native snapshot runner', () => {
2525
update: true,
2626
dependencyName: 'coana',
2727
})
28+
expect(parseSnapshotArgs(['--update', '--dep', 'patch'])).toEqual({
29+
update: true,
30+
dependencyName: 'patch',
31+
})
32+
expect(parseSnapshotArgs(['--update', '--dep', 'socket-patch'])).toEqual({
33+
update: true,
34+
dependencyName: 'socket-patch',
35+
})
2836
expect(() => parseSnapshotArgs(['--dep', 'unknown', '--update'])).toThrow(
2937
'Unknown snapshot dependency',
3038
)
3139
expect(() => parseSnapshotArgs(['--update', '--dep'])).toThrow(
32-
'Partner names to map: socket-patch, socket-python-cli',
40+
'pnpm snapshots:update:dep socket-patch',
3341
)
3442
expect(() => parseSnapshotArgs(['--update', '--dep='])).toThrow(
3543
'Provide a dependency name',
@@ -53,6 +61,18 @@ describe('native snapshot runner', () => {
5361
])
5462
})
5563

64+
it('selects patch help and version snapshots for a socket-patch refresh', () => {
65+
const patchArgs = [
66+
'--build',
67+
'test/native/commands/cli.native.test.mts',
68+
'--testNamePattern',
69+
'captures bundled patch help for (apply|rollback|get|scan|list|remove|setup|repair)|captures bundled socket-patch version',
70+
'--update',
71+
]
72+
expect(dependencySnapshotArgs('socket-patch')).toEqual(patchArgs)
73+
expect(dependencySnapshotArgs('patch')).toEqual(patchArgs)
74+
})
75+
5676
it('builds and runs only the native screenshot suites', () => {
5777
expect(nativeSnapshotArgs(false)).toEqual([
5878
'--build',
@@ -108,6 +128,7 @@ describe('native snapshot runner', () => {
108128
expect(events).toEqual([
109129
'acquire',
110130
'create-artifacts',
131+
'assert-dependencies-current',
111132
'native:false:/artifacts/run-a',
112133
'release',
113134
])
@@ -145,14 +166,17 @@ function workflowDependencies(
145166
events.push('create-artifacts')
146167
return '/artifacts/run-a'
147168
},
169+
async assertDependenciesCurrent() {
170+
events.push('assert-dependencies-current')
171+
},
148172
runNative(update, artifactsDir) {
149173
events.push(`native:${update}:${artifactsDir}`)
150174
if (nativeFails) {
151175
throw new Error('native failed')
152176
}
153177
},
154-
runDependencyNative(dependency, artifactsDir) {
155-
events.push(`dependency-native:${dependency}:${artifactsDir}`)
178+
runDependencyNative(dependencyName, artifactsDir) {
179+
events.push(`dependency-native:${dependencyName}:${artifactsDir}`)
156180
},
157181
runTerminal(update, artifactsDir) {
158182
events.push(`terminal:${update}:${artifactsDir}`)

0 commit comments

Comments
 (0)