@typespec/spec-api 0.1.0-dev.0 → 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/expectation.d.ts +8 -5
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +12 -8
- package/dist/expectation.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/match-engine.d.ts +58 -0
- package/dist/match-engine.d.ts.map +1 -0
- package/dist/match-engine.js +156 -0
- package/dist/match-engine.js.map +1 -0
- package/dist/matchers/datetime.d.ts +8 -0
- package/dist/matchers/datetime.d.ts.map +1 -0
- package/dist/matchers/datetime.js +47 -0
- package/dist/matchers/datetime.js.map +1 -0
- package/dist/matchers/index.d.ts +39 -0
- package/dist/matchers/index.d.ts.map +1 -0
- package/dist/matchers/index.js +36 -0
- package/dist/matchers/index.js.map +1 -0
- package/dist/matchers/local-url.d.ts +3 -0
- package/dist/matchers/local-url.d.ts.map +1 -0
- package/dist/matchers/local-url.js +22 -0
- package/dist/matchers/local-url.js.map +1 -0
- package/dist/request-validations.d.ts +2 -2
- package/dist/request-validations.d.ts.map +1 -1
- package/dist/request-validations.js +54 -19
- package/dist/request-validations.js.map +1 -1
- package/dist/response-utils.d.ts +48 -11
- package/dist/response-utils.d.ts.map +1 -1
- package/dist/response-utils.js +70 -30
- package/dist/response-utils.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/expectation.ts +13 -9
- package/src/index.ts +10 -0
- package/src/match-engine.ts +221 -0
- package/src/matchers/datetime.ts +66 -0
- package/src/matchers/index.ts +48 -0
- package/src/matchers/local-url.ts +24 -0
- package/src/request-validations.ts +78 -27
- package/src/response-utils.ts +106 -34
- package/src/types.ts +2 -0
- package/temp/.tsbuildinfo +1 -1
- package/test/match-engine.test.ts +303 -0
- package/test/matchers/datetime.test.ts +232 -0
- package/test/matchers/local-url.test.ts +82 -0
- package/test/matchers/matcher-test-utils.ts +17 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import deepEqual from "deep-equal";
|
|
2
|
-
import * as prettier from "prettier";
|
|
3
2
|
import { parseString } from "xml2js";
|
|
3
|
+
import { matchValues } from "./match-engine.js";
|
|
4
4
|
import { ValidationError } from "./validation-error.js";
|
|
5
5
|
export const BODY_NOT_EQUAL_ERROR_MESSAGE = "Body provided doesn't match expected body";
|
|
6
6
|
export const BODY_EMPTY_ERROR_MESSAGE = "Body should exists";
|
|
@@ -24,33 +24,67 @@ export const validateBodyEquals = (request, expectedBody) => {
|
|
|
24
24
|
}
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const result = matchValues(request.body, expectedBody);
|
|
28
|
+
if (!result.pass) {
|
|
29
|
+
throw new ValidationError(`${BODY_NOT_EQUAL_ERROR_MESSAGE}: ${result.message}`, expectedBody, request.body);
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
|
-
export const validateXmlBodyEquals = (request, expectedBody) => {
|
|
32
|
+
export const validateXmlBodyEquals = (request, expectedBody, config) => {
|
|
33
|
+
const resolvedConfig = config ?? { baseUrl: "" };
|
|
34
|
+
// When expectedBody is a Resolver (e.g. from xml`...`), serialize() already includes the XML declaration.
|
|
35
|
+
// When it's a plain string, we need to prepend it.
|
|
36
|
+
const expectedXml = typeof expectedBody === "string"
|
|
37
|
+
? `<?xml version='1.0' encoding='UTF-8'?>` + expectedBody
|
|
38
|
+
: expectedBody.serialize(resolvedConfig);
|
|
32
39
|
if (request.rawBody === undefined || isBodyEmpty(request.rawBody)) {
|
|
33
|
-
throw new ValidationError(BODY_EMPTY_ERROR_MESSAGE,
|
|
40
|
+
throw new ValidationError(BODY_EMPTY_ERROR_MESSAGE, expectedXml, request.rawBody);
|
|
34
41
|
}
|
|
35
|
-
|
|
36
|
-
let actualParsedBody = "";
|
|
42
|
+
let actualParsed;
|
|
37
43
|
parseString(request.rawBody, (err, result) => {
|
|
38
|
-
if (err !== null)
|
|
44
|
+
if (err !== null)
|
|
39
45
|
throw err;
|
|
40
|
-
|
|
41
|
-
actualParsedBody = result;
|
|
46
|
+
actualParsed = result;
|
|
42
47
|
});
|
|
43
|
-
let
|
|
44
|
-
parseString(
|
|
45
|
-
if (err !== null)
|
|
48
|
+
let expectedParsed;
|
|
49
|
+
parseString(expectedXml, (err, result) => {
|
|
50
|
+
if (err !== null)
|
|
46
51
|
throw err;
|
|
47
|
-
|
|
48
|
-
expectedParsedBody = result;
|
|
52
|
+
expectedParsed = result;
|
|
49
53
|
});
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
// If the expected body is a DynValue with matchers, use matcher-aware comparison
|
|
55
|
+
const matchers = typeof expectedBody !== "string" && "getMatchers" in expectedBody
|
|
56
|
+
? expectedBody.getMatchers(resolvedConfig)
|
|
57
|
+
: [];
|
|
58
|
+
if (matchers.length > 0) {
|
|
59
|
+
const matcherMap = new Map();
|
|
60
|
+
for (const { serialized, matcher } of matchers) {
|
|
61
|
+
matcherMap.set(serialized, matcher);
|
|
62
|
+
}
|
|
63
|
+
expectedParsed = substituteMatchers(expectedParsed, matcherMap);
|
|
64
|
+
const result = matchValues(actualParsed, expectedParsed);
|
|
65
|
+
if (!result.pass) {
|
|
66
|
+
throw new ValidationError(`${BODY_NOT_EQUAL_ERROR_MESSAGE}: ${result.message}`, expectedXml, request.rawBody);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (!deepEqual(actualParsed, expectedParsed, { strict: true })) {
|
|
71
|
+
throw new ValidationError(BODY_NOT_EQUAL_ERROR_MESSAGE, expectedXml, request.rawBody);
|
|
72
|
+
}
|
|
52
73
|
}
|
|
53
74
|
};
|
|
75
|
+
function substituteMatchers(value, matcherMap) {
|
|
76
|
+
if (typeof value === "string") {
|
|
77
|
+
return matcherMap.get(value) ?? value;
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
return value.map((v) => substituteMatchers(v, matcherMap));
|
|
81
|
+
}
|
|
82
|
+
if (typeof value === "object" && value !== null) {
|
|
83
|
+
const obj = value;
|
|
84
|
+
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, substituteMatchers(v, matcherMap)]));
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
54
88
|
export const validateCoercedDateBodyEquals = (request, expectedBody) => {
|
|
55
89
|
if (expectedBody == null) {
|
|
56
90
|
if (!isBodyEmpty(request.rawBody)) {
|
|
@@ -58,8 +92,9 @@ export const validateCoercedDateBodyEquals = (request, expectedBody) => {
|
|
|
58
92
|
}
|
|
59
93
|
return;
|
|
60
94
|
}
|
|
61
|
-
|
|
62
|
-
|
|
95
|
+
const result = matchValues(coerceDate(request.body), expectedBody);
|
|
96
|
+
if (!result.pass) {
|
|
97
|
+
throw new ValidationError(`${BODY_NOT_EQUAL_ERROR_MESSAGE}: ${result.message}`, expectedBody, request.body);
|
|
63
98
|
}
|
|
64
99
|
};
|
|
65
100
|
export const validateBodyEmpty = (request) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-validations.js","sourceRoot":"","sources":["../src/request-validations.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"request-validations.js","sourceRoot":"","sources":["../src/request-validations.ts"],"names":[],"mappings":"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"}
|
package/dist/response-utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type MockValueMatcher } from "./match-engine.js";
|
|
2
|
+
import { MockBody, MockMultipartBody, Resolver, ResolverConfig } from "./types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Serialize the provided content as json to use in a MockResponse body.
|
|
4
5
|
* @content Object to return as json.
|
|
@@ -6,24 +7,60 @@ import { MockBody, MockMultipartBody, ResolverConfig } from "./types.js";
|
|
|
6
7
|
*/
|
|
7
8
|
export declare function json(content: unknown, contentType?: string): MockBody;
|
|
8
9
|
/**
|
|
9
|
-
* Sends the provided XML
|
|
10
|
-
* The XML declaration prefix
|
|
11
|
-
*
|
|
10
|
+
* Sends the provided XML content in a MockResponse body.
|
|
11
|
+
* The XML declaration prefix is automatically prepended.
|
|
12
|
+
*
|
|
13
|
+
* Can be used as a plain function or as a tagged template literal.
|
|
14
|
+
* When used as a tagged template, interpolated matchers (e.g. `match.localUrl`)
|
|
15
|
+
* are resolved at serialization time via `expandDyns`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* // Plain string
|
|
20
|
+
* xml("<Root>hello</Root>")
|
|
21
|
+
*
|
|
22
|
+
* // Tagged template with matcher
|
|
23
|
+
* xml`<Root><Link>${match.localUrl("/next")}</Link></Root>`
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
12
26
|
* @returns {MockBody} response body with application/xml content type.
|
|
13
27
|
*/
|
|
14
|
-
export declare function xml(
|
|
28
|
+
export declare function xml(content: string): MockBody;
|
|
29
|
+
export declare function xml(strings: TemplateStringsArray, ...values: unknown[]): MockBody;
|
|
15
30
|
export declare function multipart(config: Partial<Pick<MockMultipartBody, "contentType" | "parts" | "files">>): MockMultipartBody;
|
|
16
|
-
export interface DynValue
|
|
31
|
+
export interface DynValue extends Resolver {
|
|
17
32
|
readonly isDyn: true;
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
(config: ResolverConfig): string;
|
|
34
|
+
/** Returns all matchers embedded in this template with their serialized values. */
|
|
35
|
+
getMatchers(config: ResolverConfig): Array<{
|
|
36
|
+
serialized: string;
|
|
37
|
+
matcher: MockValueMatcher;
|
|
38
|
+
}>;
|
|
20
39
|
}
|
|
21
40
|
export interface DynItem<T extends keyof ResolverConfig> {
|
|
22
41
|
readonly isDyn: true;
|
|
23
42
|
readonly name: T;
|
|
24
43
|
}
|
|
25
44
|
export declare function dynItem<const T extends keyof ResolverConfig>(name: T): DynItem<T>;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Tagged template for building strings with deferred resolution.
|
|
47
|
+
* Interpolated values can be:
|
|
48
|
+
* - `dynItem("baseUrl")` — resolved from `ResolverConfig`
|
|
49
|
+
* - Matchers (e.g. `match.localUrl(...)`) — resolved via `expandDyns`
|
|
50
|
+
* - Other `dyn` templates — recursively resolved
|
|
51
|
+
* - Plain strings/numbers — used as-is
|
|
52
|
+
*/
|
|
53
|
+
export declare function dyn(strings: readonly string[], ...values: unknown[]): DynValue;
|
|
54
|
+
export interface ExpandDynsOptions {
|
|
55
|
+
/** When true, matchers are resolved to their `toJSON()` value. Default: true. */
|
|
56
|
+
resolveMatchers?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Recursively expands all dynamic values.
|
|
60
|
+
* - Dyn functions are called with the config.
|
|
61
|
+
* - Resolvable matchers (e.g. `match.localUrl`) are resolved via `resolve(config)`.
|
|
62
|
+
* - By default, matchers are resolved to their `toJSON()` plain value.
|
|
63
|
+
* Pass `{ resolveMatchers: false }` to preserve matchers for use with `matchValues`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function expandDyns<T>(value: T, config: ResolverConfig, options?: ExpandDynsOptions): T;
|
|
29
66
|
//# sourceMappingURL=response-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-utils.d.ts","sourceRoot":"","sources":["../src/response-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"response-utils.d.ts","sourceRoot":"","sources":["../src/response-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,GAAE,MAA2B,GAAG,QAAQ,CAKzF;AAiBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;AAC/C,wBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;AAenF,wBAAgB,SAAS,CACvB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,GAC1E,iBAAiB,CAMnB;AAED,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACxC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC;IACjC,mFAAmF;IACnF,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;CAC/F;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,cAAc;IACrD,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CAClB;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAKjF;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAoB9E;AAiBD,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAG9F"}
|
package/dist/response-utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isMatcher } from "./match-engine.js";
|
|
1
2
|
/**
|
|
2
3
|
* Serialize the provided content as json to use in a MockResponse body.
|
|
3
4
|
* @content Object to return as json.
|
|
@@ -15,18 +16,23 @@ function createResolver(content) {
|
|
|
15
16
|
const expanded = expandDyns(content, config);
|
|
16
17
|
return JSON.stringify(expanded);
|
|
17
18
|
},
|
|
19
|
+
resolve: (config) => {
|
|
20
|
+
// Preserve matchers so matchValues can use them for flexible validation
|
|
21
|
+
return expandDyns(content, config, { resolveMatchers: false });
|
|
22
|
+
},
|
|
18
23
|
};
|
|
19
24
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const XML_DECLARATION = `<?xml version='1.0' encoding='UTF-8'?>`;
|
|
26
|
+
export function xml(content, ...values) {
|
|
27
|
+
if (typeof content !== "string") {
|
|
28
|
+
return {
|
|
29
|
+
contentType: "application/xml",
|
|
30
|
+
rawContent: dyn `${XML_DECLARATION}${dyn(content, ...values)}`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
27
33
|
return {
|
|
28
34
|
contentType: "application/xml",
|
|
29
|
-
rawContent:
|
|
35
|
+
rawContent: XML_DECLARATION + content,
|
|
30
36
|
};
|
|
31
37
|
}
|
|
32
38
|
export function multipart(config) {
|
|
@@ -42,40 +48,74 @@ export function dynItem(name) {
|
|
|
42
48
|
name,
|
|
43
49
|
};
|
|
44
50
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
result.push(strings[i + 1]);
|
|
51
|
+
/**
|
|
52
|
+
* Tagged template for building strings with deferred resolution.
|
|
53
|
+
* Interpolated values can be:
|
|
54
|
+
* - `dynItem("baseUrl")` — resolved from `ResolverConfig`
|
|
55
|
+
* - Matchers (e.g. `match.localUrl(...)`) — resolved via `expandDyns`
|
|
56
|
+
* - Other `dyn` templates — recursively resolved
|
|
57
|
+
* - Plain strings/numbers — used as-is
|
|
58
|
+
*/
|
|
59
|
+
export function dyn(strings, ...values) {
|
|
60
|
+
const template = (config) => {
|
|
61
|
+
let result = strings[0];
|
|
62
|
+
values.forEach((v, i) => {
|
|
63
|
+
result += String(expandDyns(v, config));
|
|
64
|
+
result += strings[i + 1];
|
|
62
65
|
});
|
|
63
|
-
return result
|
|
66
|
+
return result;
|
|
64
67
|
};
|
|
65
|
-
template.keys = dynKeys;
|
|
66
68
|
template.isDyn = true;
|
|
69
|
+
template.serialize = template;
|
|
70
|
+
template.resolve = template;
|
|
71
|
+
template.getMatchers = (config) => {
|
|
72
|
+
const result = [];
|
|
73
|
+
for (const v of values) {
|
|
74
|
+
collectMatchers(v, config, result);
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
67
78
|
return template;
|
|
68
79
|
}
|
|
69
|
-
|
|
80
|
+
function collectMatchers(value, config, out) {
|
|
81
|
+
if (isMatcher(value)) {
|
|
82
|
+
out.push({ serialized: String(value.serialize(config)), matcher: value });
|
|
83
|
+
}
|
|
84
|
+
else if (typeof value === "function" && "isDyn" in value && value.isDyn) {
|
|
85
|
+
const dynVal = value;
|
|
86
|
+
if (dynVal.getMatchers) {
|
|
87
|
+
out.push(...dynVal.getMatchers(config));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Recursively expands all dynamic values.
|
|
93
|
+
* - Dyn functions are called with the config.
|
|
94
|
+
* - Resolvable matchers (e.g. `match.localUrl`) are resolved via `resolve(config)`.
|
|
95
|
+
* - By default, matchers are resolved to their `toJSON()` plain value.
|
|
96
|
+
* Pass `{ resolveMatchers: false }` to preserve matchers for use with `matchValues`.
|
|
97
|
+
*/
|
|
98
|
+
export function expandDyns(value, config, options) {
|
|
99
|
+
const resolve = options?.resolveMatchers ?? true;
|
|
100
|
+
return _expandDyns(value, config, resolve);
|
|
101
|
+
}
|
|
102
|
+
function _expandDyns(value, config, resolveMatchers) {
|
|
70
103
|
if (typeof value === "string") {
|
|
71
104
|
return value;
|
|
72
105
|
}
|
|
73
106
|
else if (Array.isArray(value)) {
|
|
74
|
-
return value.map((v) =>
|
|
107
|
+
return value.map((v) => _expandDyns(v, config, resolveMatchers));
|
|
75
108
|
}
|
|
76
109
|
else if (typeof value === "object" && value !== null) {
|
|
110
|
+
// DynItem — resolve from config
|
|
111
|
+
if ("isDyn" in value && value.isDyn && "name" in value) {
|
|
112
|
+
return config[value.name];
|
|
113
|
+
}
|
|
114
|
+
if (isMatcher(value)) {
|
|
115
|
+
return resolveMatchers ? value.serialize(config) : value;
|
|
116
|
+
}
|
|
77
117
|
const obj = value;
|
|
78
|
-
return Object.fromEntries(Object.entries(obj).map(([key, v]) => [key,
|
|
118
|
+
return Object.fromEntries(Object.entries(obj).map(([key, v]) => [key, _expandDyns(v, config, resolveMatchers)]));
|
|
79
119
|
}
|
|
80
120
|
else if (typeof value === "function") {
|
|
81
121
|
if ("isDyn" in value && value.isDyn) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-utils.js","sourceRoot":"","sources":["../src/response-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response-utils.js","sourceRoot":"","sources":["../src/response-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export interface ResolverConfig {
|
|
|
86
86
|
}
|
|
87
87
|
export interface Resolver {
|
|
88
88
|
serialize(config: ResolverConfig): string;
|
|
89
|
+
/** Returns the expanded content with matchers preserved (for comparison). */
|
|
90
|
+
resolve(config: ResolverConfig): unknown;
|
|
89
91
|
}
|
|
90
92
|
export interface MockMultipartBody {
|
|
91
93
|
kind: "multipart";
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/spec-api",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.1",
|
|
4
4
|
"description": "Spec api to implement mock api",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": ">=
|
|
12
|
+
"node": ">=22.0.0"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -22,21 +22,21 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/microsoft/typespec#readme",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"deep-equal": "^2.2.
|
|
25
|
+
"deep-equal": "^2.2.3",
|
|
26
26
|
"express": "^5.2.1",
|
|
27
27
|
"xml2js": "^0.6.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/deep-equal": "^1.0.
|
|
30
|
+
"@types/deep-equal": "^1.0.4",
|
|
31
31
|
"@types/express": "^5.0.6",
|
|
32
|
-
"@types/multer": "^2.
|
|
33
|
-
"@types/node": "~25.0
|
|
34
|
-
"@types/xml2js": "^0.4.
|
|
35
|
-
"@vitest/coverage-v8": "^4.0
|
|
36
|
-
"@vitest/ui": "^4.0
|
|
37
|
-
"rimraf": "~6.1.
|
|
38
|
-
"typescript": "~5.9.
|
|
39
|
-
"vitest": "^4.0
|
|
32
|
+
"@types/multer": "^2.1.0",
|
|
33
|
+
"@types/node": "~25.5.0",
|
|
34
|
+
"@types/xml2js": "^0.4.14",
|
|
35
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
36
|
+
"@vitest/ui": "^4.1.0",
|
|
37
|
+
"rimraf": "~6.1.3",
|
|
38
|
+
"typescript": "~5.9.3",
|
|
39
|
+
"vitest": "^4.1.0"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"watch": "tsc -p ./tsconfig.build.json --watch",
|
package/src/expectation.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { matchValues } from "./match-engine.js";
|
|
2
2
|
import {
|
|
3
3
|
validateBodyEmpty,
|
|
4
4
|
validateBodyEquals,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
validateRawBodyEquals,
|
|
10
10
|
validateXmlBodyEquals,
|
|
11
11
|
} from "./request-validations.js";
|
|
12
|
-
import { CollectionFormat, RequestExt } from "./types.js";
|
|
12
|
+
import { CollectionFormat, RequestExt, Resolver, ResolverConfig } from "./types.js";
|
|
13
13
|
import { ValidationError } from "./validation-error.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -89,18 +89,22 @@ export class RequestExpectation {
|
|
|
89
89
|
* @param expected Expected value
|
|
90
90
|
*/
|
|
91
91
|
public deepEqual(actual: unknown, expected: unknown, message = "Values not deep equal"): void {
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const result = matchValues(actual, expected);
|
|
93
|
+
if (!result.pass) {
|
|
94
|
+
throw new ValidationError(`${message}: ${result.message}`, expected, actual);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
/**
|
|
98
|
-
* Expect the body of the request to be semantically equivalent to the provided XML
|
|
99
|
-
*
|
|
100
|
-
*
|
|
99
|
+
* Expect the body of the request to be semantically equivalent to the provided XML.
|
|
100
|
+
* Accepts a plain string or a Resolver (e.g. from `xml\`...\``).
|
|
101
|
+
* When a Resolver with matchers is provided, matcher-aware comparison is used.
|
|
102
|
+
* The XML declaration prefix will automatically be added.
|
|
103
|
+
* @param expectedBody expected XML body as a string or Resolver.
|
|
104
|
+
* @param config resolver config (required when expectedBody is a Resolver).
|
|
101
105
|
* @throws {ValidationError} if there is an error.
|
|
102
106
|
*/
|
|
103
|
-
public xmlBodyEquals(expectedBody: string): void {
|
|
104
|
-
validateXmlBodyEquals(this.originalRequest, expectedBody);
|
|
107
|
+
public xmlBodyEquals(expectedBody: string | Resolver, config?: ResolverConfig): void {
|
|
108
|
+
validateXmlBodyEquals(this.originalRequest, expectedBody, config);
|
|
105
109
|
}
|
|
106
110
|
}
|
package/src/index.ts
CHANGED