@typespec/spec-api 0.1.0-alpha.14-dev.4 → 0.1.0-alpha.14
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 +11 -0
- package/package.json +1 -1
- package/test/match-engine.test.ts +56 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @typespec/spec-api
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.14
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#10011](https://github.com/microsoft/typespec/pull/10011) Add matcher framework for flexible value comparison in scenarios. `match.dateTime()` enables semantic datetime comparison that handles precision and timezone differences across languages.
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- [#9995](https://github.com/microsoft/typespec/pull/9995) Remove prettier used for ValidationError message, in validateXmlBodyEquals.
|
|
12
|
+
|
|
13
|
+
|
|
3
14
|
## 0.1.0-alpha.13
|
|
4
15
|
|
|
5
16
|
### Bump dependencies
|
package/package.json
CHANGED
|
@@ -217,6 +217,62 @@ describe("integration with expandDyns", () => {
|
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
219
|
|
|
220
|
+
describe("integration with expandDyns({ resolveMatchers: false })", () => {
|
|
221
|
+
const config: ResolverConfig = { baseUrl: "http://localhost:3000" };
|
|
222
|
+
|
|
223
|
+
it("should preserve matcher objects instead of resolving them to plain strings", () => {
|
|
224
|
+
const content = { timestamp: match.dateTime.rfc3339("2022-08-26T18:38:00.000Z") };
|
|
225
|
+
const expanded = expandDyns(content, config, { resolveMatchers: false });
|
|
226
|
+
// Matcher must survive as a matcher, not be converted to a plain string
|
|
227
|
+
expect(isMatcher(expanded.timestamp)).toBe(true);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("should allow matchValues to do semantic datetime comparison after expandDyns with resolveMatchers:false", () => {
|
|
231
|
+
// Regression test: query params/headers with datetime matchers must use semantic comparison.
|
|
232
|
+
// Without resolveMatchers:false, expandDyns converts the matcher to the plain string
|
|
233
|
+
// "2022-08-26T18:38:00.000Z", and a strict === comparison against the actual value
|
|
234
|
+
// "2022-08-26T18:38:00Z" (no milliseconds) would fail even though they represent the
|
|
235
|
+
// same point in time.
|
|
236
|
+
const queryDef = { input: match.dateTime.utcRfc3339("2022-08-26T18:38:00.000Z") };
|
|
237
|
+
const expanded = expandDyns(queryDef, config, { resolveMatchers: false });
|
|
238
|
+
|
|
239
|
+
// The actual query string received from an HTTP request (no milliseconds)
|
|
240
|
+
const actualQueryValue = "2022-08-26T18:38:00Z";
|
|
241
|
+
|
|
242
|
+
// Simulates what createHandler does: isMatcher → deepEqual → matchValues → matcher.check()
|
|
243
|
+
expect(isMatcher(expanded.input)).toBe(true);
|
|
244
|
+
expectPass(matchValues(actualQueryValue, expanded.input, "$", config));
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("should allow matchValues to do semantic datetime comparison for header values after expandDyns with resolveMatchers:false", () => {
|
|
248
|
+
// Regression test: headers with datetime matchers must use semantic comparison, same as query params.
|
|
249
|
+
// Without resolveMatchers:false the matcher is serialized early and isMatcher() returns false,
|
|
250
|
+
// so the code falls through to containsHeader() with String(value) — a strict string equality
|
|
251
|
+
// that fails for semantically equivalent but format-different datetime strings.
|
|
252
|
+
const headerDef = { "x-ms-date": match.dateTime.rfc7231("Fri, 26 Aug 2022 18:38:00 GMT") };
|
|
253
|
+
const expanded = expandDyns(headerDef, config, { resolveMatchers: false });
|
|
254
|
+
|
|
255
|
+
// isMatcher must still be true so createHandler routes through deepEqual / matchValues
|
|
256
|
+
expect(isMatcher(expanded["x-ms-date"])).toBe(true);
|
|
257
|
+
// Semantic check passes for the exact same RFC 7231 string
|
|
258
|
+
expectPass(matchValues("Fri, 26 Aug 2022 18:38:00 GMT", expanded["x-ms-date"], "$", config));
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it("should demonstrate why resolveMatchers:true (default) breaks semantic query param matching", () => {
|
|
262
|
+
// With the default resolveMatchers:true, the matcher is eagerly converted to a plain string.
|
|
263
|
+
// A strict string comparison then fails for semantically equivalent but format-different values.
|
|
264
|
+
const queryDef = { input: match.dateTime.utcRfc3339("2022-08-26T18:38:00.000Z") };
|
|
265
|
+
const expandedWithResolve = expandDyns(queryDef, config); // resolveMatchers: true (default)
|
|
266
|
+
|
|
267
|
+
// The matcher is gone — replaced by its serialized string
|
|
268
|
+
expect(isMatcher(expandedWithResolve.input)).toBe(false);
|
|
269
|
+
expect(expandedWithResolve.input).toBe("2022-08-26T18:38:00.000Z");
|
|
270
|
+
|
|
271
|
+
// Strict string comparison fails for an equivalent datetime without milliseconds
|
|
272
|
+
expect(expandedWithResolve.input === "2022-08-26T18:38:00Z").toBe(false);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
220
276
|
describe("integration with json() Resolver", () => {
|
|
221
277
|
const config: ResolverConfig = { baseUrl: "http://localhost:3000" };
|
|
222
278
|
|