Skip to content

Commit

Permalink
Support snapshots in node:test
Browse files Browse the repository at this point in the history
  • Loading branch information
sz-piotr committed Apr 21, 2024
1 parent f85adb6 commit a1f8136
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 28 deletions.
7 changes: 7 additions & 0 deletions examples/example-node-runner/.mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
process.env.NODE_ENV = 'test'
module.exports = {
spec: 'src/**/*.test.ts',
require: 'ts-node/register/transpile-only',
watchExtensions: 'ts',
extension: 'ts',
}
20 changes: 20 additions & 0 deletions examples/example-node-runner/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "example-node-runner",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "ts-node -T ./src/index.ts",
"format": "biome format .",
"format:fix": "biome format --write .",
"lint": "biome check ./src",
"lint:fix": "biome check --apply ./src",
"typecheck": "tsc --noEmit",
"test": "node --test --loader ts-node/esm src/*.test.ts",
"test:fix": "pnpm lint:fix && pnpm format:fix && pnpm test && pnpm typecheck"
},
"dependencies": {
"earl": "workspace:^1.2.1",
"example-plugin": "workspace:^1.0.0"
}
}
38 changes: 38 additions & 0 deletions examples/example-node-runner/src/basics.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { describe, it } from 'node:test'
import { expect } from 'earl'

describe('basics', () => {
it('works', (ctx) => {
class Person {
constructor(readonly name: string) {}
}

const response = {
trimmed: true,
timestamp: '12345',
name: 'Alice Duck',
age: 15,
nested: {
b: new Person('Jack'),
deep: {
nested: true,
},
},
}

expect(response).toEqual({
trimmed: true,
timestamp: expect.anything(),
name: expect.regex(/[Dd]uck/),
age: expect.a(Number),
nested: {
b: expect.a(Person),
deep: expect.a(Object),
},
})

expect(true).toEqual(true)

expect(response).toMatchSnapshot(ctx)
})
})
16 changes: 16 additions & 0 deletions examples/example-node-runner/src/basics.test.ts.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// works 1

{
age: 15
name: "Alice Duck"
nested: {
b: Person {
name: "Jack"
}
deep: {
nested: true
}
}
timestamp: "12345"
trimmed: true
}
9 changes: 9 additions & 0 deletions examples/example-node-runner/src/snapshots.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { describe, it } from 'node:test'
import { expect } from 'earl'

describe('snapshots', () => {
it('work', (ctx) => {
expect({ very: { nested: { wow: 'wow' } } }).toMatchSnapshot(ctx)
expect('totally different thing').toMatchSnapshot(ctx)
})
})
13 changes: 13 additions & 0 deletions examples/example-node-runner/src/snapshots.test.ts.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// work 1

{
very: {
nested: {
wow: "wow"
}
}
}

// work 2

"totally different thing"
11 changes: 11 additions & 0 deletions examples/example-node-runner/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"strict": true
}
}
7 changes: 6 additions & 1 deletion examples/example-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
"license": "MIT",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./types.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js"
}
},
"scripts": {
"start": "ts-node -T ./src/index.ts",
"format": "biome format .",
Expand Down
9 changes: 0 additions & 9 deletions examples/example-plugin/types.d.ts

This file was deleted.

6 changes: 5 additions & 1 deletion packages/earl/src/errors/AssertionError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ export class AssertionError extends Error {
file: () => {
cleaned = cleaned ?? getCleanStack(error)
parsed = parsed ?? ErrorStackParser.parse({ stack: cleaned } as Error)
return parsed[0]?.fileName
const fileName = parsed[0]?.fileName
if (fileName?.startsWith('file://')) {
return fileName.slice(7)
}
return fileName
},
stack: () => {
cleaned = cleaned ?? getCleanStack(error)
Expand Down
36 changes: 35 additions & 1 deletion packages/earl/src/validators/snapshots/TestContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export interface TestContext extends MochaTestContext, UvuTestContext {}
export type TestContext = NodeTestContext | MochaTestContext | UvuTestContext

export interface NodeTestContext {
name: string
}

export interface MochaTestContext {
test?: {
Expand All @@ -11,3 +15,33 @@ export interface UvuTestContext {
__test__?: string
__suite__?: string
}

export function getTestFile(context: TestContext): string | undefined {
if ('test' in context) {
const file = context.test?.file
if (typeof file === 'string') {
return file
}
}
}

export function getTestName(context: TestContext): string | undefined {
if ('test' in context) {
if (typeof context.test?.fullTitle === 'function') {
const title = context.test.fullTitle()
if (typeof title === 'string') {
return title
}
}
}
if ('__test__' in context) {
const parts = [context.__test__]
if (context.__suite__) {
parts.unshift(context.__suite__)
}
return parts.filter((x) => x !== undefined).join(' ')
}
if ('name' in context && typeof context.name === 'string') {
return context.name
}
}
18 changes: 2 additions & 16 deletions packages/earl/src/validators/snapshots/getSnapshot.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readFileSync } from 'node:fs'
import path from 'node:path'

import type { TestContext } from './TestContext.js'
import { getTestFile, getTestName, type TestContext } from './TestContext.js'
import { parseSnapshot } from './format.js'
import type { SnapshotUpdateMode } from './getSnapshotUpdateMode.js'

Expand All @@ -18,7 +18,7 @@ export function getSnapshot(
context: TestContext,
mode: SnapshotUpdateMode,
) {
const filePath = context.test?.file ?? controlFileName
const filePath = getTestFile(context) ?? controlFileName
if (!filePath) {
throw new TypeError(
'Invalid test context. Cannot determine test file path.',
Expand Down Expand Up @@ -58,17 +58,3 @@ export function getSnapshot(
expected: typeof expected === 'string' ? expected : undefined,
}
}

function getTestName(context: TestContext) {
const name = context.test?.fullTitle()
if (name) {
return name
}
if (context.__test__ !== undefined) {
const parts = [context.__test__]
if (context.__suite__) {
parts.unshift(context.__suite__)
}
return parts.join(' ')
}
}
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a1f8136

Please sign in to comment.