From b2b95285b27e167a3b7d355330f0c43be790f2cf Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 30 May 2024 15:15:17 +0200 Subject: [PATCH] feat: Make "serializeForErrorMessage" optional --- CHANGELOG.md | 1 + src/QueryBin.js | 14 ++++++++++++-- src/QueryBin.test.ts | 41 +++++++++++++++++++++++++++++++++++++++++ src/example.test.ts | 3 ++- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 623ca94..ff49a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Date: 2024-04-21T22:14:24.556Z - Breaking: Remove unused option "retryDelayMillis" +- Feature: Make "serializeForErrorMessage" optional. Default is `JSON.stringify` with 2 indent. # v0.3.0 diff --git a/src/QueryBin.js b/src/QueryBin.js index dfe8fbd..6a8e422 100644 --- a/src/QueryBin.js +++ b/src/QueryBin.js @@ -1,6 +1,7 @@ export class QueryBin { constructor(queries = {}, { timeoutMillis = 1000 } = {}) { this.values = []; + this.defaultSerializer = (item) => JSON.stringify(item, null, 2); this.timeoutMillis = timeoutMillis; this.latch = new Latch(); @@ -88,7 +89,11 @@ export class QueryBin { return new Error( queryDefinition.multipleFoundMessage + "\nFound: \n" + - results.map(queryDefinition.serializeForErrorMessage).join("\n"), + results + .map( + queryDefinition.serializeForErrorMessage ?? this.defaultSerializer, + ) + .join("\n"), ); } @@ -97,7 +102,12 @@ export class QueryBin { this.values.length === 0 ? "List is completely empty!" : "All values: \n" + - this.values.map(queryDefinition.serializeForErrorMessage).join("\n"); + this.values + .map( + queryDefinition.serializeForErrorMessage ?? + this.defaultSerializer, + ) + .join("\n"); return new Error(`${queryDefinition.noneFoundMessage}\n${values}`); } diff --git a/src/QueryBin.test.ts b/src/QueryBin.test.ts index d573ac8..d33e072 100644 --- a/src/QueryBin.test.ts +++ b/src/QueryBin.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { QueryBin, QueryDefinition } from "./QueryBin"; +import { createThreadsRpcOptions } from "vitest/workers"; function dividableBy(modulo: number): QueryDefinition { return { @@ -238,4 +239,44 @@ describe("QueryBin", () => { "No number is dividable by 3.\nList is completely empty!", ); }); + + describe("custom serializer", () => { + function createBinWithIds() { + return new QueryBin({ + byIdPrefix(expected: string): QueryDefinition<{ id: string }> { + return { + test: (item) => item.id.startsWith(expected), + multipleFoundMessage: "Multiple found.", + noneFoundMessage: "None found.", + }; + }, + }); + } + + it("uses default serialize in 'none found'", () => { + const bin = createBinWithIds(); + bin.addAll([{ id: "a" }, { id: "b" }]); + + expect(() => { + bin.get.byIdPrefix("c"); + }).toThrow( + `None found.\nAll values: \n${json({ id: "a" })}\n${json({ id: "b" })}`, + ); + }); + + it("uses serializer in 'multiple found'", () => { + const bin = createBinWithIds(); + bin.addAll([{ id: "ab" }, { id: "ac" }]); + + expect(() => { + bin.get.byIdPrefix("a"); + }).toThrow( + `Multiple found.\nFound: \n${json({ id: "ab" })}\n${json({ id: "ac" })}`, + ); + }); + }); }); + +function json(obj: unknown) { + return JSON.stringify(obj, null, 2); +} diff --git a/src/example.test.ts b/src/example.test.ts index bf7c660..8a60b71 100644 --- a/src/example.test.ts +++ b/src/example.test.ts @@ -12,9 +12,10 @@ interface Request { function byMethodAndUrl(method: Method, url: string): QueryDefinition { return { test: (item) => item.method === method && item.url.includes(url), - serializeForErrorMessage: (item) => JSON.stringify(item, null, 2), noneFoundMessage: `Could not find requests with method ${method} and URL containing ${url}.`, multipleFoundMessage: `Multiple requests found method ${method} and URL containing ${url}.`, + // optional + serializeForErrorMessage: (item) => JSON.stringify(item, null, 2), }; }