UNPKG

@almela/obx

Version:

Fast & Lightweight Object Manipulation Library for Javascript

1,134 lines (1,123 loc) 26.4 kB
"use strict"; var obx = _interopRequireWildcard(require("./index")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const deepCopyCheck = (a, b) => obx.reduce_r(a, (acc, [k, v], p) => { console.log(acc, b, k, v, p); return acc && b[p] !== undefined && b[p] !== v; }, true); describe("eq", () => { test("equal empty objects", () => { expect(obx.eq({}, {})).toBe(true); }); test("equal simple objects", () => { expect(obx.eq({ foo: "bar" }, { foo: "bar" })).toBe(true); }); test("equal different order objects", () => { expect(obx.eq({ foo: "bar", bar: "baz" }, { bar: "baz", foo: "bar" })).toBe(true); }); test("equal empty arrays", () => { expect(obx.eq([], [])).toBe(true); }); test("equal simple arrays", () => { expect(obx.eq([1, 2, 3], [1, 2, 3])).toBe(true); }); test("equal different order arrays", () => { // Note that array order matters expect(obx.eq([1, 2, 3], [3, 2, 1])).toBe(false); }); test("equal undefined arrays", () => { const a = []; a[1] = 1; const b = [undefined, 1]; expect(obx.eq(a, b)).toBe(true); }); test("equal nested objects", () => { expect(obx.eq({ foo: { bar: { baz: [1, 2, 3] } } }, { foo: { bar: { baz: [1, 2, 3] } } })).toBe(true); }); test("equal nested objects 2", () => { expect(obx.eq({ foo: [{ foo: "bar" }] }, { foo: [{ foo: "bar" }] })).toBe(true); }); test("different empty objects", () => { expect(obx.eq({}, [])).toBe(false); expect(obx.eq([], {})).toBe(false); }); test("different object keys", () => { expect(obx.eq({ foo: "bar" }, { baz: "bar" })).toBe(false); }); test("different object values", () => { expect(obx.eq({ foo: "bar" }, { foo: "baz" })).toBe(false); }); test("different objects", () => { expect(obx.eq({ foo: "bar" }, { bar: "baz" })).toBe(false); }); test("different nested arrays", () => { expect(obx.eq({ foo: { bar: { baz: [1, 2, 3] } } }, { foo: { bar: { baz: [3, 2, 1] } } })).toBe(false); }); test("different objects depth 0", () => { expect(obx.eq({ foo: "bar" }, { foo: "baz" }, { depth: 0 })).toBe(true); }); test("different objects depth 1", () => { expect(obx.eq({ foo: { bar: "baz" } }, { foo: {} }, { depth: 1 })).toBe(true); }); test("different objects depth 2", () => { expect(obx.eq({ foo: { bar: "baz" } }, { foo: {} }, { depth: 2 })).toBe(false); }); test("different arrays depth 0", () => { expect(obx.eq([1, 2, 3], [3, 2, 1], { depth: 0 })).toBe(true); }); test("different arrays depth 1", () => { expect(obx.eq([[1], [1], [1]], [[], [], []], { depth: 1 })).toBe(true); }); test("different arrays depth 2", () => { expect(obx.eq([{ foo: 1, bar: [1, 2, 3] }, {}, {}], [{ foo: 1, bar: [4, 5, 6] }, {}, {}], { depth: 2 })).toBe(true); }); test("functions", () => { // Functions are impossible to diff, this test is only here to verify that we don't diff them expect(obx.eq({ foo: x => x + 1 }, { foo: x => x + 2 })).toBe(true); }); }); describe("set", () => { test("empty object", () => { const o = {}; obx.set(o, "foo", "bar"); expect(obx.eq(o, { foo: "bar" })).toBe(true); }); test("deep empty object", () => { const o = {}; obx.set(o, "foo.bar.baz", "bar"); expect(obx.eq(o, { foo: { bar: { baz: "bar" } } })).toBe(true); }); test("empty object with array", () => { const o = {}; obx.set(o, "foo.0", 1); expect(obx.eq(o, { foo: [1] })).toBe(true); }); test("empty object with deep array", () => { const o = {}; obx.set(o, "foo.0.bar", "baz"); expect(obx.eq(o, { foo: [{ bar: "baz" }] })).toBe(true); }); test("empty object with deep array index 2", () => { const o = {}; obx.set(o, "foo.2.bar", "baz"); const arr = []; arr[2] = { bar: "baz" }; const res = { foo: arr }; expect(obx.eq(o, res)).toBe(true); }); test("deep undefined array index 2", () => { const o = {}; obx.set(o, "foo.2.bar", "baz"); const res = { foo: [undefined, undefined, { bar: "baz" }] }; expect(obx.eq(o, res)).toBe(true); }); }); describe("get", () => { test("empty object", () => { const o = {}; expect(obx.get(o, "foo")).toBe(null); expect(obx.eq(o, {})).toBe(true); // o should not change }); test("simple object", () => { const o = { foo: "bar" }; expect(obx.get(o, "foo")).toBe("bar"); expect(obx.eq(o, { foo: "bar" })).toBe(true); // o should not change }); test("deep object", () => { const o = { foo: { bar: "baz" } }; expect(obx.get(o, "foo.bar")).toBe("baz"); expect(obx.eq(o, { foo: { bar: "baz" } })).toBe(true); // o should not change }); test("empty array", () => { const o = []; expect(obx.get(o, "foo")).toBe(null); expect(obx.get(o, "0")).toBe(null); }); test("simple array", () => { const o = [1, 2, 3]; expect(obx.get(o, "1")).toBe(2); expect(obx.get(o, "3")).toBe(null); // invalid key }); test("deep array", () => { const o = [{ foo: { bar: "baz" } }, { foo: { bar: "baz" } }, { foo: { bar: "baz" } }]; expect(obx.get(o, "1.foo.bar")).toBe("baz"); expect(obx.get(o, "0.foo.baz")).toBe(null); // invalid key }); test("simple invalid key", () => { const o = [{ foo: "bar" }]; expect(obx.get(o, "bar")).toBe(null); }); test("deep invalid key", () => { const o = [{ foo: "bar" }]; expect(obx.get(o, "bar.foo.baz.0.haz")).toBe(null); }); }); describe("len", () => { test("empty object", () => { expect(obx.len({})).toBe(0); }); test("simple object", () => { expect(obx.len({ foo: "bar" })).toBe(1); }); test("long object", () => { expect(obx.len({ one: 1, two: 2, three: 3, four: 4, five: 5, six: 6, seven: 7, eight: 8, nine: 9, ten: 10 })).toBe(10); }); test("nested object", () => { // remember that this is non-recursive length, so the number of keys is 1 expect(obx.len({ foo: { bar: "baz" } }, { depth: 1 })).toBe(1); }); test("empty array", () => { expect(obx.len([], 1)).toBe(0); }); test("simple array", () => { expect(obx.len([1], 1)).toBe(1); }); test("long array", () => { expect(obx.len([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1)).toBe(10); }); test("nested array", () => { // remember that this is non-recursive length, so the number of values is 2 expect(obx.len([[1, 2, 3], [1, 2, 3]], { depth: 1 })).toBe(2); }); }); describe("rec len", () => { test("empty object", () => { expect(obx.len({})).toBe(0); }); test("simple object", () => { expect(obx.len({ foo: "bar" })).toBe(1); }); test("deep object", () => { // Note that len_r counts the number of *keys* of an object, hence 7 expect(obx.len({ foo: { bar: "baz", baz: "bar", haz: [1, 2, 3] } })).toBe(7); }); test("empty array", () => { expect(obx.len([])).toBe(0); }); test("simple array", () => { expect(obx.len([1, 2, 3])).toBe(3); }); test("deep array", () => { // array indicies are counted, hence 12 expect(obx.len([[1, 2, 3], [4, 5, 6], [7, 8, 9]])).toBe(12); }); test("object depth 0", () => { expect(obx.len({ foo: "bar" }, { depth: 0 })).toBe(0); }); test("object depth 1", () => { expect(obx.len({ foo: "bar", bar: [1, 2, 3] }, { depth: 1 })).toBe(2); }); test("array depth 0", () => { expect(obx.len([1, 2, 3], { depth: 0 })).toBe(0); }); test("array depth 1", () => { expect(obx.len([[1, 2, 3], [4, 5, 6], [7, 8, 9]], { depth: 1 })).toBe(3); }); }); describe("isEmptyObj", () => { test("empty object", () => { expect(obx.isEmptyObj({})).toBe(true); }); test("empty array", () => { // only works for object types expect(obx.isEmptyObj([])).toBe(false); }); test("filled object", () => { expect(obx.isEmptyObj({ foo: "bar" })).toBe(false); }); test("filled array", () => { expect(obx.isEmptyObj([1])).toBe(false); }); test("undefined object", () => { expect(obx.isEmptyObj({ foo: undefined })).toBe(false); }); test("undefined array", () => { expect(obx.isEmptyObj([undefined])).toBe(false); }); }); describe("isEmptyArr", () => { test("empty array", () => { expect(obx.isEmptyArr([])).toBe(true); }); test("empty object", () => { // only works for array types expect(obx.isEmptyArr({})).toBe(false); }); test("filled array", () => { expect(obx.isEmptyArr([1, 2, 3])).toBe(false); }); test("filled object", () => { expect(obx.isEmptyArr({ foo: "bar" })).toBe(false); }); test("undefined array", () => { expect(obx.isEmptyArr([undefined, undefined])).toBe(true); }); test("null array", () => { expect(obx.isEmptyArr([null])).toBe(false); }); }); describe("cp", () => { test("empty object", () => { const o = {}; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("simple object", () => { const o = { foo: "bar" }; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("deep object", () => { const o = { foo: "bar", bar: { baz: "haz" } }; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("empty array", () => { const o = []; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("simple array", () => { const o = [1, 2, 3]; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("deep array", () => { const o = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("complex object", () => { const o = { foo: "bar", bar: "baz", baz: [{ foo: "bar", bar: 4 }, { foo: "baz", baz: { foo: 3 } }, { foo: { bar: { baz: { foo: { baz: 42 } } } } }, [[[12]], 5, [60]]] }; const n = obx.cp(o); expect(obx.eq(o, n)).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); }); describe("map", () => { test("empty object", () => { const o = {}; // Note that map will callback on every value of the object, including sub objects! const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis, 1); expect(obx.eq(n, {})).toBe(true); }); test("simple object", () => { const o = { foo: "bar", bar: "baz", baz: "foo" }; // Note that map will callback on every value of the object, including sub objects! const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis, 1); expect(obx.eq(n, { foo: "bar!", bar: "baz!", baz: "foo!" })).toBe(true); // expect(deepCopyCheck(n, o)).toBe(true); }); test("deep object", () => { const o = { foo: "bar", bar: { baz: "foo" } }; // Note that map will callback on every value of the object, including sub objects! const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis, { depth: 1 }); expect(obx.eq(n, { foo: "bar!", bar: { baz: "foo" } })).toBe(true); }); test("empty array", () => { const o = []; const n = obx.map(o, ([_, v]) => v + 1, { depth: 1 }); expect(obx.eq(n, [])).toBe(true); }); test("simple array", () => { const o = [1, 2, 3]; const n = obx.map(o, ([_, v]) => v + 1, { depth: 1 }); expect(obx.eq(n, [2, 3, 4])).toBe(true); }); test("deep array", () => { const o = [1, [1, 2, 3], 3]; const n = obx.map(o, ([_, v]) => v instanceof Object ? v : v + 1, { depth: 1 }); expect(obx.eq(n, [2, [1, 2, 3], 4])).toBe(true); }); }); describe("rec map", () => { test("deep object", () => { const o = { foo: "bar", bar: { baz: { haz: "wow" }, foo: "bar" }, raz: "faz" }; // Note that map will callback on every value of the object, including sub objects! const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis); expect(obx.eq(n, { foo: "bar!", bar: { baz: { haz: "wow!" }, foo: "bar!" }, raz: "faz!" })).toBe(true); }); test("complex object", () => { const o = { foo: "bar", bar: [{ foo: "bar", bar: "baz" }, { foo: "bar", bar: "baz" }, { foo: "bar", bar: "baz" }], raz: "faz" }; // Note that map will callback on every value of the object, including sub objects. const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis); expect(obx.eq(n, { foo: "bar!", bar: [{ foo: "bar!", bar: "baz!" }, { foo: "bar!", bar: "baz!" }, { foo: "bar!", bar: "baz!" }], raz: "faz!" })).toBe(true); }); test("simple object depth 0", () => { const o = { foo: "bar", bar: "baz" }; const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; // depth 0 should have no effect const n = obx.map(o, emphasis, { depth: 0 }); expect(obx.eq(n, { foo: "bar", bar: "baz" })).toBe(true); }); test("deep object depth 2", () => { const o = { foo: "bar", bar: { baz: ["foo", "bar", "baz"] } }; const emphasis = ([_, v]) => v instanceof Object ? v : v + "!"; const n = obx.map(o, emphasis, { depth: 2 }); expect(obx.eq(n, { foo: "bar!", bar: { baz: ["foo", "bar", "baz"] } })).toBe(true); }); }); describe("reduce", () => { test("empty object", () => { const o = {}; const combineVals = (a, [k, v]) => [...a, v]; const n = obx.reduce(o, combineVals, []); expect(obx.eq(n, [])).toBe(true); }); test("simple object values", () => { const o = { foo: "bar", bar: "baz" }; const combineVals = (a, [k, v]) => [...a, v]; const n = obx.reduce(o, combineVals, []).join(", "); expect(n).toBe("bar, baz"); }); test("simple object keys", () => { const o = { foo: "bar", bar: "baz" }; const combineKeys = (a, [k, v]) => [...a, k]; const n = obx.reduce(o, combineKeys, []).join(", "); expect(n).toBe("foo, bar"); }); test("empty array", () => { const o = []; const combineVals = (a, [k, v]) => [...a, v]; const n = obx.reduce(o, combineVals, []); expect(obx.eq(n, [])).toBe(true); }); test("simple array values", () => { const o = ["foo", "bar", "baz"]; const combineVals = (a, [k, v]) => [...a, v]; const n = obx.reduce(o, combineVals, []).join(", "); expect(n).toBe("foo, bar, baz"); }); test("simple array keys", () => { const o = [1, 2, 3, 4, 5]; const combineVals = (a, [k, v]) => a + parseInt(k); const n = obx.reduce(o, combineVals, 0); expect(n).toBe(10); }); }); describe("rec reduce", () => { test("flatten deep object", () => { const o = { isActive: true, balance: "$3,722.54", age: 39, friends: [{ id: 0, name: "Patrice Meyer" }, { id: 1, name: "Lee Watson" }, { id: 2, name: "Strong Munoz" }] }; const flatten = (a, [k, v]) => v instanceof Object ? a : k in a ? a : (a[k] = v, a); const n = obx.reduce(o, flatten, {}); expect(obx.eq(n, { isActive: true, balance: "$3,722.54", age: 39, id: 0, name: "Patrice Meyer" })).toBe(true); }); test("invert object", () => { const o = { isActive: true, balance: "$3,722.54", age: 39, friends: [{ id: 0, name: "Patrice Meyer" }, { id: 1, name: "Lee Watson" }, { id: 2, name: "Strong Munoz" }] }; // this also flattens the object const invert = (a, [k, v]) => v instanceof Object ? a : (a[v] = k, a); const n = obx.reduce(o, invert, {}); expect(obx.eq(n, { true: "isActive", "$3,722.54": "balance", 39: "age", 0: "id", "Patrice Meyer": "name", 1: "id", "Lee Watson": "name", 2: "id", "Strong Munoz": "name" })).toBe(true); }); }); describe("zip", () => { test("simple objects", () => { const a = { foo: "bar", bar: "baz", baz: "haz" }; const b = [4, 5, 6]; const z = obx.zip([a, b]); expect(obx.eq(z.next().value, ["bar", 4])).toBe(true); expect(obx.eq(z.next().value, ["baz", 5])).toBe(true); expect(obx.eq(z.next().value, ["haz", 6])).toBe(true); }); test("deep objects", () => { const a = { foo: "bar", bar: { baz: "haz" } }; const b = [4, 5]; const z = obx.zip([a, b]); const v1 = z.next().value; const v2 = z.next().value; expect(obx.eq(v1, ["bar", 4])).toBe(true); expect(obx.eq(v2, [{ baz: "haz" }, 5])).toBe(true); expect(obx.eq(v2, ["haz", 5])).toBe(false); }); test("many objects", () => { const a = ["a", "b", "c"]; const b = [1, 2, 3]; const c = ["x", "y", "z"]; const d = [3, 2, 1]; const z = obx.zip([a, b, c, d]); const v1 = z.next().value; const v2 = z.next().value; const v3 = z.next().value; expect(obx.eq(v1, ["a", 1, "x", 3])).toBe(true); expect(obx.eq(v2, ["b", 2, "y", 2])).toBe(true); expect(obx.eq(v3, ["c", 3, "z", 1])).toBe(true); }); test("stop early", () => { const a = ["a", "b", "c"]; const b = [1]; const z = obx.zip([a, b]); const v1 = z.next().value; const v2 = z.next().value; expect(obx.eq(v1, ["a", 1])).toBe(true); expect(v2).toBe(undefined); }); test("only one object", () => { const o = { foo: "foo", bar: "bar", baz: [{ id: 0, name: "Patrice Meyer" }, { id: 1, name: "Lee Watson" }, { id: 2, name: "Strong Munoz" }] }; const z = obx.zip([o]); expect(obx.eq(z.next().value, ["foo"])).toBe(true); expect(obx.eq(z.next().value, ["bar"])).toBe(true); expect(obx.eq(z.next().value, [[{ id: 0, name: "Patrice Meyer" }, { id: 1, name: "Lee Watson" }, { id: 2, name: "Strong Munoz" }]])).toBe(true); expect(obx.eq(z.next().value, [{ id: 0, name: "Patrice Meyer" }])).toBe(true); expect(obx.eq(z.next().value, [0])).toBe(true); expect(obx.eq(z.next().value, ["Patrice Meyer"])).toBe(true); expect(obx.eq(z.next().value, [{ id: 1, name: "Lee Watson" }])).toBe(true); expect(obx.eq(z.next().value, [1])).toBe(true); expect(obx.eq(z.next().value, ["Lee Watson"])).toBe(true); expect(obx.eq(z.next().value, [{ id: 2, name: "Strong Munoz" }])).toBe(true); expect(obx.eq(z.next().value, [2])).toBe(true); expect(obx.eq(z.next().value, ["Strong Munoz"])).toBe(true); }); test("stop last", () => { const a = ["a", "b", "c"]; const b = [1]; const z = obx.zip([a, b], { last: true }); const v1 = z.next().value; const v2 = z.next().value; const v3 = z.next().value; expect(obx.eq(v1, ["a", 1])).toBe(true); expect(obx.eq(v2, ["b", null])).toBe(true); expect(obx.eq(v3, ["c", null])).toBe(true); }); test("only keys", () => { const a = { a: 0, b: 1, c: 2 }; const b = ["a", "b", "c"]; // the opposite of what we would normally get const z = obx.zip([a, b], { key: true, val: false }); const v1 = z.next().value; const v2 = z.next().value; const v3 = z.next().value; expect(obx.eq(v1, ["a", "0"])).toBe(true); expect(obx.eq(v2, ["b", "1"])).toBe(true); expect(obx.eq(v3, ["c", "2"])).toBe(true); }); test("key vals", () => { const a = { a: 0, b: 1, c: 2 }; const b = ["a", "b", "c"]; // the opposite of what we would normally get const z = obx.zip([a, b], { key: true, val: true }); const v1 = z.next().value; const v2 = z.next().value; const v3 = z.next().value; expect(obx.eq(v1, [["a", 0], [0, "a"]])).toBe(true); expect(obx.eq(v2, [["b", 1], [1, "b"]])).toBe(true); expect(obx.eq(v3, [["c", 2], [2, "c"]])).toBe(true); }); }); describe("sub", () => { test("empty object", () => { const a = {}; const b = {}; obx.sub(a, b); expect(obx.eq(a, {})).toBe(true); }); test("simple object", () => { const a = { foo: "bar", bar: "baz", list: [1, 2, 3] }; const b = { foo: "bar", list: [1, 2, 3] }; obx.sub(a, b); expect(obx.eq(a, { bar: "baz" })).toBe(true); }); test("empty array", () => { const a = []; const b = []; obx.sub(a, b); expect(obx.eq(a, [])).toBe(true); }); test("simple array", () => { const a = [1, 2, 3]; const b = [1, 2, 3]; obx.sub(a, b); expect(obx.eq(a, [])).toBe(true); }); test("simple array 2", () => { const a = [{ foo: "bar" }, 2, { bar: "baz" }]; const b = []; b[2] = { bar: "baz" }; obx.sub(a, b); expect(obx.eq(a, [{ foo: "bar" }, 2])).toBe(true); }); test("simple array 3", () => { const a = [1, 2, 3]; const b = [1, 2]; const res = []; res[2] = 3; obx.sub(a, b); expect(obx.eq(a, res)).toBe(true); }); test("complex object", () => { const a = { foo: "bar", bar: "baz", baz: { haz: "baz", gaz: [{ key: "val", foo: "bar" }, 2, 3] } }; const b = { bar: "baz", baz: { gaz: [{ key: "var", foo: "ball" }, 2, 3] } }; const res = { foo: "bar", baz: { haz: "baz", gaz: [{ key: "val", foo: "bar" }] } }; obx.sub(a, b); expect(obx.eq(a, res)).toBe(true); }); }); describe("add", () => { test("empty object", () => { const a = {}; const b = {}; obx.add(a, b); expect(obx.eq(a, {})).toBe(true); }); test("simple object", () => { const a = { foo: "bar", bar: "baz", list: [1, 2, 3] }; const b = { foo: "bar", haz: 5 }; obx.add(a, b); expect(obx.eq(a, { foo: "bar", bar: "baz", list: [1, 2, 3], haz: 5 })).toBe(true); }); test("empty array", () => { const a = []; const b = []; obx.add(a, b); expect(obx.eq(a, [])).toBe(true); }); test("simple array", () => { const a = [1, 2, 3]; const b = [2, 3, 4]; obx.add(a, b); // doesn't override keys expect(obx.eq(a, [1, 2, 3])).toBe(true); }); test("complex object", () => { const a = { foo: "bar", bar: "baz", baz: { haz: "baz", gaz: [{ key: "val", foo: "bar" }, 2, 3] } }; const b = { foo: "bar", bar: "baz", baz: { haz: "baz", gaz: [{ key: "val", foo: "bar", new: "hello" }, 2, 3] } }; const res = b; obx.add(a, b); expect(obx.eq(a, res)).toBe(true); }); }); describe("prototype polution", () => { const BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}'); test("add", () => { const victim = {}; try { obx.add({}, BAD_JSON); } catch (e) {} expect(Object.keys(victim.__proto__).length).toBe(0); delete Object.prototype.polluted; }); test("cp", () => { const victim = {}; try { obx.cp({ "__proto__.polluted": true }); } catch (e) {} expect(Object.keys(victim.__proto__).length).toBe(0); delete Object.prototype.polluted; }); test("set", () => { const victim = {}; try { obx.set({}, "__proto__.polluted", true); } catch (e) {} expect(Object.keys(victim.__proto__).length).toBe(0); delete Object.prototype.polluted; }); }); //# sourceMappingURL=index.test.js.map