diff --git a/src/json.test.ts b/src/json.test.ts new file mode 100644 index 0000000..24678ba --- /dev/null +++ b/src/json.test.ts @@ -0,0 +1,35 @@ +import { expect, test } from "vitest"; + +import { jsonStringify } from "./json"; + +const values: any[] = [ + 1, + "hello, world", + '"and"', + ['"and"'], + {}, + [true, false], + { foo: 1, bar: "charlie" }, + [1, 2, 3], + { foo: [1, 2, 3], bar: { foo: 1, bar: "charlie" } } + // 100n, // @todo returns "100" which is correct but we need to adapt the test +]; + +test("jsonStringify re-parse", async () => { + for (let v of values) { + expect(JSON.parse(jsonStringify(v))).toEqual(v); + } +}); + +test("jsonStringify order", () => { + expect(jsonStringify({ a: 1, b: "bar" })).toBe( + jsonStringify({ b: "bar", a: 1 }) + ); + expect(jsonStringify({ a: { c: 100, z: 1 }, b: "bar" })).toBe( + jsonStringify({ b: "bar", a: { z: 1, c: 100 } }) + ); +}); + +test("jsonStringify undefined", () => { + expect(jsonStringify({ a: 1, b: undefined })).toBe(jsonStringify({ a: 1 })); +}); diff --git a/src/json.ts b/src/json.ts index 6481691..06920da 100644 --- a/src/json.ts +++ b/src/json.ts @@ -7,7 +7,10 @@ const errorCell = new Error("cell"); * @param obj * @returns */ -export const jsonStringify = (obj: T) => { +export const jsonStringify = ( + obj: T, + options: { skipNull?: boolean } = {} +) => { if (obj instanceof Cell) throw errorCell; let out = ""; const aux = (v: T) => { @@ -24,13 +27,17 @@ export const jsonStringify = (obj: T) => { } switch (typeof v) { case "object": { + if (v === null) { + out += "null"; + break; + } out += "{"; let first = true; // sort objects alphabetically for (const [k, elt] of Object.entries(v).sort(([k1, _v1], [k2, _v2]) => k1 < k2 ? -1 : k1 > k2 ? 1 : 0 )) { - if (elt === undefined || elt === null) continue; + if (elt === undefined || (options.skipNull && elt === null)) continue; if (!first) out += ","; out += JSON.stringify(k); out += ":"; @@ -46,9 +53,6 @@ export const jsonStringify = (obj: T) => { case "bigint": out += `"${v.toString()}"`; break; - // case "boolean": - // out += v ? "true" : "false"; - // break; default: out += JSON.stringify(v); } diff --git a/src/utils.test.ts b/src/utils.test.ts new file mode 100644 index 0000000..b72ed6b --- /dev/null +++ b/src/utils.test.ts @@ -0,0 +1,27 @@ +import { describe, it, expect } from "vitest"; + +import { intersection } from "./utils"; + +describe("intersection function", () => { + it("returns the correct intersection of two arrays with common elements", () => { + expect(intersection([1, 2, 3], [2, 3, 4])).toEqual([2, 3]); + }); + + it("returns an empty array when there are no common elements", () => { + expect(intersection([1, 2, 3], [4, 5, 6])).toEqual([]); + }); + + it("handles identical arrays correctly", () => { + expect(intersection([1, 2, 3], [1, 2, 3])).toEqual([1, 2, 3]); + }); + + it("returns an empty array when one or both input arrays are empty", () => { + expect(intersection([], [1, 2, 3])).toEqual([]); + expect(intersection([1, 2, 3], [])).toEqual([]); + expect(intersection([], [])).toEqual([]); + }); + + it("correctly handles duplicates in the input arrays", () => { + expect(intersection([1, 2, 2, 3], [2, 2, 3, 4])).toEqual([2, 2, 3]); + }); +}); diff --git a/vitest.config.mjs b/vitest.config.mjs index d37dfd5..86a7857 100644 --- a/vitest.config.mjs +++ b/vitest.config.mjs @@ -3,5 +3,8 @@ import { defineConfig } from "vite"; export default defineConfig({ test: { environment: "happy-dom", + coverage: { + exclude: ["src/index.ts", "src/types.ts"], + }, }, });