import { getObjectProperty, setObjectProperty, removeObjectProperty, haveObjectProperty, addFieldsToUnion, getProperties, objectIntersection, defaults, omit, } from "./objects"; describe("Have object property", () => { it("Utils: test haveObjectProperty() - null/undefined argument", () => { expect(haveObjectProperty(null, ["field"])).toBe(false); expect(haveObjectProperty(null, ["field", "field2"])).toBe(false); expect(haveObjectProperty(undefined, ["field"])).toBe(false); expect(haveObjectProperty(undefined, ["field", "field2"])).toBe(false); }); it("Utils: test haveObjectProperty() - simple object", () => { expect(haveObjectProperty({ field: 1 }, ["field"])).toBe(true); expect(haveObjectProperty({ field: null }, ["field"])).toBe(true); }); it("Utils: test haveObjectProperty() - difficult object", () => { expect(haveObjectProperty({ field: 1, field2: { subField: "subField" } }, ["field2", "subField"])).toBe(true); expect(haveObjectProperty({ field: 1, field2: { subField: null } }, ["field2", "subField"])).toBe(true); }); it("Primitive field", () => { expect(haveObjectProperty({ field: 1, field2: 2 }, ["field2", "field4"])).toBe(false); }); it("Empty sub object", () => { const object = { a: 1, b: { c: {} } }; expect(haveObjectProperty(object, ["b", "c", "d"])).toBe(false); }); }); describe("Add field to union", () => { it("Utils: addFieldsToUnion() - simple object", () => { const union = {}; const object = { a: 1, b: 2, c: 3 }; addFieldsToUnion(object, union); expect(union.hasOwnProperty("a")).toBe(true); expect(union.hasOwnProperty("b")).toBe(true); expect(union.hasOwnProperty("c")).toBe(true); }); it("Utils addFieldsToUnion() - difficult objects", () => { const union = {}; const object = { a: 1, b: 2, d: { e: 4, f: 5 }, g: { c: 3, y: { a: 1 } }, }; addFieldsToUnion(object, union); expect(haveObjectProperty(union, ["a"])).toBe(true); expect(haveObjectProperty(union, ["b"])).toBe(true); expect(haveObjectProperty(union, ["d"])).toBe(true); expect(haveObjectProperty(union, ["g"])).toBe(true); expect(haveObjectProperty(union, ["d", "e"])).toBe(true); expect(haveObjectProperty(union, ["d", "f"])).toBe(true); expect(haveObjectProperty(union, ["g", "c"])).toBe(true); expect(haveObjectProperty(union, ["g", "y", "a"])).toBe(true); }); it("Utils addFieldsToUnion() - several objects", () => { const union: any = {}; const object = { a: 1, b: 2, d: { e: 4, f: 5 }, g: { c: 3, y: { a: 1 } }, }; const object2 = { c: 3, y: { u: 2 }, d: { e: 4 }, }; addFieldsToUnion(object, union); addFieldsToUnion(object2, union); expect(haveObjectProperty(union, ["a"])).toBe(true); expect(haveObjectProperty(union, ["b"])).toBe(true); expect(haveObjectProperty(union, ["d"])).toBe(true); expect(haveObjectProperty(union, ["g"])).toBe(true); expect(haveObjectProperty(union, ["d", "e"])).toBe(true); expect(haveObjectProperty(union, ["d", "f"])).toBe(true); expect(haveObjectProperty(union, ["g", "c"])).toBe(true); expect(haveObjectProperty(union, ["g", "y", "a"])).toBe(true); expect(haveObjectProperty(union, ["c"])).toBe(true); expect(haveObjectProperty(union, ["y", "u"])).toBe(true); }); }); class WithGetter { get field() { return 5; } get field2() { return undefined; } } class WithGetterExtended extends WithGetter { get field3() { return 3; } constructor() { super(); } } describe("Get/Set object property by path", () => { let obj: any; beforeEach(() => { obj = { test: "string", field: 5, flag: true, obj2: { field2: null, obj3: { field3: true }, }, }; }); it("Utils: test getItemProperty()", () => { const value = getObjectProperty(obj, ["test"]); expect(value).toBe(obj.test); const value2 = getObjectProperty(obj, ["obj2", "obj3", "field3"]); expect(value2).toBe(obj.obj2.obj3.field3); }); it("Get property from not existing path", () => { expect(() => getObjectProperty(obj, ["notExistField", "field"])).toThrow(); }); it("Get property from getter", () => { const instance1 = new WithGetter(); const value = getObjectProperty(instance1, ["field"]); expect(value).toBe(5); const value2 = getObjectProperty(instance1, ["field2"]); expect(value2).toBe(undefined); const instance2 = new WithGetterExtended(); const value3 = getObjectProperty(instance2, ["field3"]); expect(value3).toBe(3); }); it("Utils: test setItemProperty()", () => { const path1 = ["flag"]; setObjectProperty(obj, path1, false); expect(obj.flag).toBe(false); expect(path1.length).toBe(1); const path2 = ["obj2", "obj3", "field3"]; setObjectProperty(obj, path2, false); expect(path2.length).toBe(3); expect(obj.obj2.obj3.field3).toBe(false); const path3 = ["obj2", "obj3", "obj4", "field4"]; setObjectProperty(obj, path3, 10, true); expect(obj.obj2.obj3.obj4.field4).toBe(10); expect(path3.length).toBe(4); }); }); describe("Remove object property", () => { it("Utils: removeObjectProperty() - simple object", () => { const object = { a: 1, b: 2, c: 3 }; removeObjectProperty(object, ["a"]); expect(haveObjectProperty(object, ["a"])).toBe(false); expect(haveObjectProperty(object, ["b"])).toBe(true); expect(haveObjectProperty(object, ["c"])).toBe(true); }); it("Utils: removeObjectProperty() - difficult objects", () => { const object = { a: 1, b: { c: { d: 5 } } }; removeObjectProperty(object, ["b", "c", "d"]); expect(haveObjectProperty(object, ["b", "c", "d"])).toBe(false); expect(haveObjectProperty(object, ["b", "c"])).toBe(true); expect(haveObjectProperty(object, ["b"])).toBe(true); expect(haveObjectProperty(object, ["a"])).toBe(true); }); it("Utils: removeObjectProperty() - throw exception if wrong path", () => { const object = { a: 1 }; expect(() => removeObjectProperty(object, ["c", "d"])).toThrow(); }); }); describe("Get properties", () => { it("null argument", () => { const result = getProperties(null); expect(result.length).toBe(0); }); it("undefined argument", () => { const result = getProperties(undefined); expect(result.length).toBe(0); }); it("Simple object", () => { const obj: any = { a: "1", b: "1", c: "1" }; const result = getProperties(obj); expect(result.length).toBe(3); expect(result.flat().includes("a")).toBe(true); expect(result.flat().includes("b")).toBe(true); expect(result.flat().includes("c")).toBe(true); }); it("Null field in object", () => { const obj: any = { a: "1", b: { c: null } }; const result = getProperties(obj); expect(result[2][0]).toBe("b"); expect(result[2][1]).toBe("c"); }); it("Undefined field in object", () => { const obj: any = { a: "1", b: { c: undefined } }; const result = getProperties(obj); expect(result[2][0]).toBe("b"); expect(result[2][1]).toBe("c"); }); }); describe("Intersection", () => { it("Utils: objectIntersection() - test simple objects", () => { const objects = [ { field1: 1, field2: 2, field3: 3 }, { field1: 1, field3: 3, field4: 4 }, ]; const result = objectIntersection(...objects); expect(result.hasOwnProperty("field1")).toBe(true); expect(result.hasOwnProperty("field2")).toBe(false); expect(result.hasOwnProperty("field3")).toBe(true); expect(result.hasOwnProperty("field4")).toBe(false); }); it("Utils: objectIntersection() - test difficult objects", () => { const objects = [ { field1: 1, field2: 2, field3: 3, field4: { subField1: 2, subField2: 3, subs: null } }, { field1: 1, field3: 3, field4: 4 }, { field2: 3, field3: 3, field4: { subField1: 2, subField3: { subSubField1: 5, subSubField2: 2 } } }, ]; const result = objectIntersection(...objects); expect(result.hasOwnProperty("field3")).toBe(true); expect(result.hasOwnProperty("field4")).toBe(true); expect(result.hasOwnProperty("field1")).toBe(false); }); it("Utils: objectIntersection() - various data types of field", () => { const objects = [ { field1: 1, field2: 2 }, { field1: "1", field2: "2", field3: "3" }, ]; const result = objectIntersection(...objects); expect(result.hasOwnProperty("field1")).toBe(true); expect(result.hasOwnProperty("field2")).toBe(true); expect(result.hasOwnProperty("field3")).toBe(false); }); it("Utils: objectIntersection() - test primitives", () => { expect(() => objectIntersection(1, "string", false)).toThrow(new Error("Argument can not be primitive!")); expect(() => objectIntersection("string", false, 1)).toThrow(new Error("Argument can not be primitive!")); expect(() => objectIntersection(false, 1, "string")).toThrow(new Error("Argument can not be primitive!")); }); it("Utils: objectIntersection() - test call with null/undefined", () => { expect(() => objectIntersection({ a: 1 }, null)).toThrow(new Error("Argument can not be null/undefined!")); }); it("Utils: objectIntersection() - test once argument", () => { const object = { field1: 1, field2: 2, field3: 3 }; const result = objectIntersection(object); expect(result.hasOwnProperty("field1")).toBe(true); expect(result.hasOwnProperty("field2")).toBe(true); expect(result.hasOwnProperty("field3")).toBe(true); }); }); describe("defaults function", () => { it("Call with null and null", () => { const result = defaults(null, null); expect(result).toEqual({}); }); it("Call with {} and null", () => { const result = defaults({}, null); expect(result).toEqual({}); }); it("Call with {} and {}", () => { const result = defaults({}, {}); expect(result).toEqual({}); }); it("Call with object and null", () => { const result = defaults({ a: "a", b: "b" }, null); expect(result).toEqual({ a: "a", b: "b" }); }); it("Source have identical fields", () => { const result = defaults({ a: "a", b: "b" }, { a: "a1", b: "b1", c: "c1" }); expect(result).toEqual({ a: "a", b: "b", c: "c1" }); }); it("Object have field with null value", () => { const result = defaults({ a: "a", b: null }, { a: "a1", b: "b1", c: "c1" }); expect(result).toEqual({ a: "a", b: "b1", c: "c1" }); }); it("Object have felid with undefined value", () => { const result = defaults({ a: "a", b: undefined }, { a: "a1", b: "b1", c: "c1" }); expect(result).toEqual({ a: "a", b: "b1", c: "c1" }); }); it("Source have field with null value", () => { const result = defaults({ a: "a", b: "b" }, { a: "a1", b: null, c: "c1" }); expect(result).toEqual({ a: "a", b: "b", c: "c1" }); }); }); describe("omit function", () => { it("", () => { const obj = { a: "a", b: "b", c: "c", d: "d" }; const result = omit(obj); expect(result).toBe(obj); }); });