summaryrefslogtreecommitdiff
path: root/std/testing/asserts.ts
diff options
context:
space:
mode:
authorSimon Lecoq <22963968+lowlighter@users.noreply.github.com>2020-10-21 18:53:27 +0200
committerGitHub <noreply@github.com>2020-10-21 18:53:27 +0200
commit23df1c563efee65e6d549308ed0671a9e2933c05 (patch)
tree4044912869283f4674467779fab9a56ff2ac3189 /std/testing/asserts.ts
parent322913ee5c73cd139a46dea593635c2d1a8d5f8c (diff)
feat(std/testing): Add support for object assertion against object subset (#8001)
This commit add supports for a new assertion function "assertObjectMatch" which allows to test an actual object against an expected object subset (i.e. inclusivity, not equality).
Diffstat (limited to 'std/testing/asserts.ts')
-rw-r--r--std/testing/asserts.ts42
1 files changed, 42 insertions, 0 deletions
diff --git a/std/testing/asserts.ts b/std/testing/asserts.ts
index f93e043dc..1d58f0a00 100644
--- a/std/testing/asserts.ts
+++ b/std/testing/asserts.ts
@@ -430,6 +430,48 @@ export function assertNotMatch(
}
/**
+ * Make an assertion that `actual` object is a subset of `expected` object, deeply.
+ * If not, then throw.
+ */
+export function assertObjectMatch(
+ actual: Record<PropertyKey, unknown>,
+ expected: Record<PropertyKey, unknown>,
+): void {
+ type loose = Record<PropertyKey, unknown>;
+ const seen = new WeakMap();
+ return assertEquals(
+ (function filter(a: loose, b: loose): loose {
+ // Prevent infinite loop with circular references with same filter
+ if ((seen.has(a)) && (seen.get(a) === b)) {
+ return a;
+ }
+ seen.set(a, b);
+ // Filter keys and symbols which are present in both actual and expected
+ const filtered = {} as loose;
+ const entries = [
+ ...Object.getOwnPropertyNames(a),
+ ...Object.getOwnPropertySymbols(a),
+ ]
+ .filter((key) => key in b)
+ .map((key) => [key, a[key as string]]) as Array<[string, unknown]>;
+ // Build filtered object and filter recursively on nested objects references
+ for (const [key, value] of entries) {
+ if (typeof value === "object") {
+ const subset = (b as loose)[key];
+ if ((typeof subset === "object") && (subset)) {
+ filtered[key] = filter(value as loose, subset as loose);
+ continue;
+ }
+ }
+ filtered[key] = value;
+ }
+ return filtered;
+ })(actual, expected),
+ expected,
+ );
+}
+
+/**
* Forcefully throws a failed assertion
*/
export function fail(msg?: string): void {