Skip to content

Commit bd2a252

Browse files
committed
Decouple matcher from matcher registration
1 parent 4590bdf commit bd2a252

File tree

4 files changed

+74
-61
lines changed

4 files changed

+74
-61
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ All files | 81.81 | 66.66 | 80 | 88.88 |
2626

2727
## Vitest
2828

29-
Integration with vitest is provided as `@hyperjump/json-schema-coverage/vitest`.
30-
You'll need a vitest config specifically for running schema coverage.
29+
Integration with vitest is provided. You'll need a vitest config specifically
30+
for running schema coverage. You can't run with coverage for both your js/ts
31+
code and schema at the same time.
3132

3233
`vitest-schema.config.js`
3334
```JavaScript
@@ -43,6 +44,10 @@ export default defineConfig({
4344
});
4445
```
4546

47+
```bash
48+
vitest run --config=vitest-schema.config.js --coverage
49+
```
50+
4651
When you use the provided custom matcher `matchJsonSchema`/`toMatchJsonSchema`,
4752
if vitest has coverage is enabled, it will collect coverage data from those
4853
tests.

src/vitest/json-schema-matcher.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import type { SchemaObject } from "@hyperjump/json-schema";
2+
3+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4+
export const matchJsonSchema: (instance: any, uriOrSchema: string | SchemaObject | boolean) => AsyncExpectationResult;
5+
export const toMatchJsonSchema: typeof matchJsonSchema;

src/vitest/json-schema-matcher.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { randomUUID } from "node:crypto";
2+
import { existsSync } from "node:fs";
3+
import { writeFile } from "node:fs/promises";
4+
import { registerSchema, unregisterSchema, validate } from "@hyperjump/json-schema/draft-2020-12";
5+
import "@hyperjump/json-schema/draft-2019-09";
6+
import "@hyperjump/json-schema/draft-07";
7+
import "@hyperjump/json-schema/draft-06";
8+
import "@hyperjump/json-schema/draft-04";
9+
import { BASIC } from "@hyperjump/json-schema/experimental";
10+
import { TestCoverageEvaluationPlugin } from "../test-coverage-evaluation-plugin.js";
11+
12+
/**
13+
* @import { OutputUnit, SchemaObject } from "@hyperjump/json-schema"
14+
* @import { AsyncExpectationResult } from "@vitest/expect"
15+
*/
16+
17+
/** @type (instance: any, uriOrSchema: string | SchemaObject | boolean) => AsyncExpectationResult */
18+
export const matchJsonSchema = async (instance, uriOrSchema) => {
19+
/** @type OutputUnit */
20+
let output;
21+
22+
if (typeof uriOrSchema === "string") {
23+
const uri = uriOrSchema;
24+
25+
if (existsSync(".json-schema-coverage")) {
26+
const testCoveragePlugin = new TestCoverageEvaluationPlugin();
27+
28+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
29+
output = await validate(uri, instance, {
30+
outputFormat: BASIC,
31+
plugins: [testCoveragePlugin]
32+
});
33+
34+
const coverageMapPath = `.json-schema-coverage/${randomUUID()}.json`;
35+
const coverageMapJson = JSON.stringify(testCoveragePlugin.coverageMap);
36+
await writeFile(coverageMapPath, coverageMapJson);
37+
} else {
38+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
39+
output = await validate(uri, instance, BASIC);
40+
}
41+
} else {
42+
const schema = uriOrSchema;
43+
const uri = `urn:uuid:${randomUUID()}`;
44+
registerSchema(schema, uri, "https://json-schema.org/draft/2020-12/schema");
45+
try {
46+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
47+
output = await validate(uri, instance, BASIC);
48+
} finally {
49+
unregisterSchema(uri);
50+
}
51+
}
52+
53+
return {
54+
pass: output.valid,
55+
message: () => JSON.stringify(output, null, " ")
56+
};
57+
};
58+
59+
export const toMatchJsonSchema = matchJsonSchema;

src/vitest/matchers.js

Lines changed: 3 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,7 @@
1-
import { randomUUID } from "node:crypto";
2-
import { existsSync } from "node:fs";
3-
import { writeFile } from "node:fs/promises";
41
import { expect } from "vitest";
5-
import { registerSchema, unregisterSchema, validate } from "@hyperjump/json-schema/draft-2020-12";
6-
import "@hyperjump/json-schema/draft-2019-09";
7-
import "@hyperjump/json-schema/draft-07";
8-
import "@hyperjump/json-schema/draft-06";
9-
import "@hyperjump/json-schema/draft-04";
10-
import { BASIC } from "@hyperjump/json-schema/experimental";
11-
import { TestCoverageEvaluationPlugin } from "../test-coverage-evaluation-plugin.js";
12-
13-
/**
14-
* @import { OutputUnit, SchemaObject } from "@hyperjump/json-schema"
15-
* @import { AsyncExpectationResult } from "@vitest/expect"
16-
*/
17-
18-
/** @type (instance: any, uriOrSchema: string | SchemaObject | boolean) => AsyncExpectationResult */
19-
const schemaMatcher = async (instance, uriOrSchema) => {
20-
/** @type OutputUnit */
21-
let output;
22-
23-
if (typeof uriOrSchema === "string") {
24-
const uri = uriOrSchema;
25-
26-
if (existsSync(".json-schema-coverage")) {
27-
const testCoveragePlugin = new TestCoverageEvaluationPlugin();
28-
29-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
30-
output = await validate(uri, instance, {
31-
outputFormat: BASIC,
32-
plugins: [testCoveragePlugin]
33-
});
34-
35-
const coverageMapPath = `.json-schema-coverage/${randomUUID()}.json`;
36-
const coverageMapJson = JSON.stringify(testCoveragePlugin.coverageMap);
37-
await writeFile(coverageMapPath, coverageMapJson);
38-
} else {
39-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
40-
output = await validate(uri, instance, BASIC);
41-
}
42-
} else {
43-
const schema = uriOrSchema;
44-
const uri = `urn:uuid:${randomUUID()}`;
45-
registerSchema(schema, uri, "https://json-schema.org/draft/2020-12/schema");
46-
try {
47-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
48-
output = await validate(uri, instance, BASIC);
49-
} finally {
50-
unregisterSchema(uri);
51-
}
52-
}
53-
54-
return {
55-
pass: output.valid,
56-
message: () => JSON.stringify(output, null, " ")
57-
};
58-
};
2+
import { matchJsonSchema } from "./json-schema-matcher.js";
593

604
expect.extend({
61-
matchJsonSchema: schemaMatcher,
62-
toMatchJsonSchema: schemaMatcher
5+
matchJsonSchema: matchJsonSchema,
6+
toMatchJsonSchema: matchJsonSchema
637
});

0 commit comments

Comments
 (0)