Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/tests/unit/schema-validation/utils.ts
6451 views
1
/*
2
* utils.ts
3
*
4
* Copyright (C) 2021-2022 Posit Software, PBC
5
*
6
*/
7
8
import { fileLoader } from "../../utils.ts";
9
import { unitTest } from "../../test.ts";
10
import { initYamlIntelligenceResourcesFromFilesystem } from "../../../src/core/schema/utils.ts";
11
import {
12
initState,
13
setInitializer,
14
} from "../../../src/core/lib/yaml-validation/state.ts";
15
import { ensureSchemaResources } from "../../../src/core/schema/yaml-schema.ts";
16
import { convertFromYaml } from "../../../src/core/lib/yaml-schema/from-yaml.ts";
17
import { setSchemaDefinition } from "../../../src/core/lib/yaml-validation/schema.ts";
18
import { ValidationError } from "../../../src/core/lib/yaml-schema/validated-yaml.ts";
19
import { isEqual } from "../../../src/core/lodash.ts";
20
import { assertRejects } from "testing/asserts";
21
import { readYamlFromString } from "../../../src/core/yaml.ts";
22
import { readAnnotatedYamlFromMappedString } from "../../../src/core/schema/annotated-yaml.ts";
23
import {
24
asMappedString,
25
MappedString,
26
} from "../../../src/core/lib/mapped-text.ts";
27
import {
28
AnnotatedParse,
29
Schema,
30
} from "../../../src/core/lib/yaml-schema/types.ts";
31
import { navigate } from "../../../src/core/lib/yaml-intelligence/annotated-yaml.ts";
32
import { idSchema } from "../../../src/core/lib/yaml-schema/common.ts";
33
34
export const schemaTestFile = fileLoader("schema-validation");
35
36
export async function fullInit() {
37
await initYamlIntelligenceResourcesFromFilesystem();
38
await ensureSchemaResources();
39
}
40
41
export function readSelfValidatingSchemaTestFile(file: string): {
42
annotation: AnnotatedParse;
43
mappedYaml: MappedString;
44
schema: Schema;
45
} {
46
const mappedYaml = asMappedString(Deno.readTextFileSync(file));
47
const annotatedYaml = readAnnotatedYamlFromMappedString(
48
mappedYaml,
49
);
50
const annotation = navigate(["value"], annotatedYaml)!;
51
52
// deno-lint-ignore no-explicit-any
53
let schema = convertFromYaml((annotatedYaml.result as any).schema);
54
if (schema.$id === undefined) {
55
schema = idSchema(schema, String(Math.random()).slice(2));
56
}
57
setSchemaDefinition(schema);
58
59
return { annotation, schema, mappedYaml };
60
}
61
62
export function schemaFromString(schemaStr: string) {
63
const yaml = readYamlFromString(schemaStr);
64
const schema = convertFromYaml(yaml);
65
setSchemaDefinition(schema);
66
return schema;
67
}
68
69
export function expectValidationError(e: ValidationError) {
70
let willThrow = e instanceof ValidationError;
71
const goodE = e as ValidationError;
72
const result = {
73
toHaveLength(l: number) {
74
if (!willThrow) return result;
75
if (goodE.validationErrors.length !== l) {
76
willThrow = false;
77
}
78
return result;
79
},
80
toHaveInfo(key: string, which?: number) {
81
if (!willThrow) return result;
82
if (which === undefined) {
83
which = 0;
84
}
85
if (goodE.validationErrors[which] === undefined) {
86
willThrow = false;
87
return result;
88
}
89
if (goodE.validationErrors[which].niceError.info[key] === undefined) {
90
willThrow = false;
91
return result;
92
}
93
return result;
94
},
95
forSchemaPathToEndWith(spec: string | string[], which?: number) {
96
if (!willThrow) return result;
97
if (typeof spec === "string") {
98
spec = [spec];
99
}
100
if (which === undefined) {
101
which = 0;
102
}
103
if (goodE.validationErrors[which] === undefined) {
104
willThrow = false;
105
return result;
106
}
107
if (
108
!isEqual(
109
spec,
110
goodE.validationErrors[which].schemaPath.slice(-spec.length),
111
)
112
) {
113
willThrow = false;
114
return result;
115
}
116
return result;
117
},
118
go() {
119
if (willThrow) {
120
throw e;
121
}
122
},
123
};
124
return result;
125
}
126
127
export type ValidationChecker = ReturnType<typeof expectValidationError>;
128
129
export async function assertYamlValidationFails(
130
fun: () => Promise<unknown>,
131
checker: (e: ValidationError) => ValidationChecker,
132
) {
133
await assertRejects(async () => {
134
try {
135
await fun();
136
} catch (e) {
137
if (e instanceof ValidationError) {
138
checker(e).go();
139
}
140
}
141
});
142
}
143
144
// deno-lint-ignore require-await
145
export async function yamlValidationUnitTest(
146
name: string,
147
fun: () => Promise<unknown>,
148
) {
149
unitTest(name, async () => {
150
setInitializer(fullInit);
151
await initState();
152
await fun();
153
});
154
}
155
156