Skip to content

Commit 1021020

Browse files
committed
Fixes for supporting vocabularies
1 parent 2f328c1 commit 1021020

File tree

5 files changed

+70
-78
lines changed

5 files changed

+70
-78
lines changed

README.md

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ some other integration. It uses the [istanbul] coverage format, so you can
77
generate any reports that support [istanbul].
88

99
Validation is done by [@hyperjump/json-schema], so you can use any version of
10-
JSON Schema.
10+
JSON Schema, or provide your own custom keywords, vocabularies, and dialects.
1111

1212
```
1313
-------------|---------|----------|---------|---------|-------------------
@@ -50,14 +50,13 @@ code and schema code at the same time.
5050

5151
By default, it will track coverage for any file with a `*.schema.json`,
5252
`*.schema.yaml`, or `*.schema.yml` extension. You can change this with the
53-
`include` option.
53+
`include` option. For example, if you keep your schemas in a folder called
54+
`schemas` and they just have plain extensions (`*.json`) instead of schema
55+
extensions `*.schema.json`, you could use `["schemas/**/*.json"]`.
5456

55-
**Options**
56-
57-
- **include** -- An array of paths of schemas you want to track coverage for.
58-
For example, if you keep your schemas in a folder called `schemas` and they
59-
just have plain extensions (`*.json`) instead of schema extensions
60-
`*.schema.json`, you could use `["schemas/**/*.json"]`.
57+
If you use custom keywords, vocabularies, and dialects, you'll need to
58+
register them with a [globalSetup](https://vitest.dev/config/#globalsetup)
59+
script.
6160

6261
`vitest-schema.config.js`
6362
```TypeScript
@@ -66,7 +65,8 @@ import type { JsonSchemaCoverageProviderOptions } from "@hyperjump/json-schema-c
6665

6766
export default defineConfig({
6867
test: {
69-
include: ["schema-tests/"],
68+
globalSetup: ["./register-my-dialect.ts"], // Optional
69+
include: ["schema-tests/"], // Optional
7070
coverage: {
7171
provider: "custom",
7272
customProviderModule: "@hyperjump/json-schema-coverage/vitest/coverage-provider",
@@ -150,7 +150,7 @@ describe("Worksheet", () => {
150150
});
151151
```
152152

153-
## Vitest API
153+
### Vitest API
154154

155155
These are the functions available when working with the vitest integration.
156156

@@ -182,24 +182,6 @@ import { ... } from "@hyperjump/json-schema-coverage/vitest"
182182

183183
_**NOTE**: This is **not** the same as the function from
184184
[@hyperjump/json-schema] that takes the schema's `$id`._
185-
- **defineVocabulary**: (vocabularyUri: string, keywords: Record<string, string>) => void
186-
187-
If your schemas use a custom vocabulary, you can register your vocabulary
188-
with this function.
189-
190-
_**NOTE**: This is the same as the function from [@hyperjump/json-schema]_
191-
- **addKeyword**: (keywordHandler: Keyword) => void
192-
193-
If your schemas use a custom vocabulary, you can register your custom
194-
keywords with this function.
195-
196-
_**NOTE**: This is the same as the function from [@hyperjump/json-schema]_
197-
- **loadDialect**: (dialectUri: string, dialect: Record<string, boolean>, allowUnknowKeywords?: boolean) => void
198-
199-
If your schemas use a custom dialect, you can register it with this
200-
function.
201-
202-
_**NOTE**: This is the same as the function from [@hyperjump/json-schema]_
203185

204186
## Low-Level API
205187

src/vitest/build-coverage-maps.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { existsSync } from "node:fs";
2+
import { readFile } from "node:fs/promises";
3+
import { resolve } from "node:path";
4+
import { glob } from "tinyglobby";
5+
import ignore from "ignore";
6+
import { registerSchema } from "./json-schema-matchers.js";
7+
import { FileCoverageMapService } from "./file-coverage-map-service.js";
8+
9+
/**
10+
* @import { TestProject } from "vitest/node"
11+
*/
12+
13+
/** @type (projects: TestProject) => Promise<void> */
14+
export const setup = async (projects) => {
15+
const config = projects.vitest.config;
16+
17+
const coverageService = new FileCoverageMapService(".json-schema-coverage/maps");
18+
19+
// If --project filter is set pick only roots of resolved projects
20+
const roots = config.project?.length
21+
? [...new Set(projects.vitest.projects.map((project) => project.config.root))]
22+
: [config.root];
23+
24+
const include = "include" in config.coverage
25+
? /** @type string[] */ (config.coverage.include)
26+
: ["**/*.schema.(json|yaml|yml)"];
27+
28+
// Build coverage maps
29+
for (const root of roots) {
30+
const i = ignore();
31+
const gitignorePath = resolve(root, ".gitignore");
32+
if (existsSync(gitignorePath)) {
33+
const gitignore = await readFile(gitignorePath, "utf-8");
34+
i.add(gitignore);
35+
}
36+
37+
let includedFiles = await glob(include, {
38+
cwd: root,
39+
dot: true,
40+
onlyFiles: true
41+
});
42+
43+
const files = i
44+
.filter(includedFiles)
45+
.map((file) => resolve(root, file));
46+
47+
for (const schemaPath of files) {
48+
try {
49+
await registerSchema(schemaPath);
50+
} catch (_error) {
51+
}
52+
}
53+
54+
for (const file of files) {
55+
await coverageService.addFromFile(file);
56+
}
57+
}
58+
};

src/vitest/coverage-provider.js

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ import path from "node:path";
44
import coverage from "istanbul-lib-coverage";
55
import libReport from "istanbul-lib-report";
66
import reports from "istanbul-reports";
7-
import ignore from "ignore";
8-
import { glob } from "tinyglobby";
97
import { resolve } from "pathe";
108
import c from "tinyrainbow";
119
import { coverageConfigDefaults } from "vitest/config";
12-
import { registerSchema } from "./json-schema-matchers.js";
1310
import { FileCoverageMapService } from "./file-coverage-map-service.js";
1411

1512
/**
@@ -45,11 +42,6 @@ class JsonSchemaCoverageProvider {
4542
coverageFilesDirectory = ".json-schema-coverage";
4643
coverageService = new FileCoverageMapService(".json-schema-coverage/maps");
4744

48-
/** @type string[] */
49-
roots = [];
50-
51-
include = ["**/*.schema.json", "**/*.schema.yaml", "**/*.schema.yml"];
52-
5345
/** @type CoverageProvider["initialize"] */
5446
initialize(ctx) {
5547
this.ctx = ctx;
@@ -73,14 +65,8 @@ class JsonSchemaCoverageProvider {
7365
reporter: resolveCoverageReporters(config.reporter || coverageConfigDefaults.reporter)
7466
};
7567

76-
// If --project filter is set pick only roots of resolved projects
77-
this.roots = ctx.config.project?.length
78-
? [...new Set(ctx.projects.map((project) => project.config.root))]
79-
: [ctx.config.root];
80-
81-
if ("include" in config) {
82-
this.include = config.include;
83-
}
68+
const buildScriptPath = path.resolve(import.meta.dirname, "./build-coverage-maps.js");
69+
/** @type string[] */ (ctx.config.globalSetup).push(buildScriptPath);
8470
}
8571

8672
/** @type CoverageProvider["resolveOptions"] */
@@ -109,37 +95,6 @@ class JsonSchemaCoverageProvider {
10995
await this.coverageService.open();
11096

11197
await fs.mkdir(this.coverageFilesDirectory, { recursive: true });
112-
113-
// Build coverage maps
114-
for (const root of this.roots) {
115-
const i = ignore();
116-
const gitignorePath = path.resolve(root, ".gitignore");
117-
if (existsSync(gitignorePath)) {
118-
const gitignore = await fs.readFile(gitignorePath, "utf-8");
119-
i.add(gitignore);
120-
}
121-
122-
let includedFiles = await glob(this.include, {
123-
cwd: root,
124-
dot: true,
125-
onlyFiles: true
126-
});
127-
128-
const files = i
129-
.filter(includedFiles)
130-
.map((file) => path.resolve(root, file));
131-
132-
for (const schemaPath of files) {
133-
try {
134-
await registerSchema(schemaPath);
135-
} catch (_error) {
136-
}
137-
}
138-
139-
for (const file of files) {
140-
await this.coverageService.addFromFile(file);
141-
}
142-
}
14398
}
14499

145100
/** @type () => Promise<void> */

src/vitest/index.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,3 @@ export const unregisterSchema: (filePath: string) => Promise<void>;
3838
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3939
export const matchJsonSchema: (instance: any, uriOrSchema: string | SchemaObject | boolean) => AsyncExpectationResult;
4040
export const toMatchJsonSchema: typeof matchJsonSchema;
41-
42-
export { loadDialect, defineVocabulary, addKeyword } from "@hyperjump/json-schema/experimental";

src/vitest/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ expect.extend({
88
});
99

1010
export * from "./json-schema-matchers.js";
11-
export { loadDialect, defineVocabulary, addKeyword } from "@hyperjump/json-schema/experimental";

0 commit comments

Comments
 (0)