@daiso-tech/core
Version:
The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.
230 lines • 8.79 kB
JavaScript
/**
* @module Serde
*/
import { beforeEach, vi } from "vitest";
import {} from "../../../serde/contracts/_module.js";
/**
* The `flexibleSerdeAdapterTestSuite` function simplifies the process of testing your custom implementation of {@link IFlexibleSerdeAdapter | `IFlexibleSerdeAdapter`} with `vitest`.
*
* IMPORT_PATH: `"@daiso-tech/core/serde/test-utilities"`
* @group TestUtilities
* @example
* ```ts
* import { describe, expect, test } from "vitest";
* import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/super-json-serde-adapter";
* import { flexibleSerdeAdapterTestSuite } from "@daiso-tech/core/serde/test-utilities";
*
* describe("class: SuperJsonSerdeAdapter", () => {
* flexibleSerdeAdapterTestSuite({
* createAdapter: () => new SuperJsonSerdeAdapter(),
* expect,
* test,
* });
* });
* ```
*/
export function flexibleSerdeAdapterTestSuite(settings) {
const { expect, test, createAdapter } = settings;
let flexibleSerdeAdapter;
class User {
name;
age;
static deserialize(serializedUser) {
return new User(serializedUser.name, serializedUser.age);
}
constructor(name, age) {
this.name = name;
this.age = age;
}
serialize() {
return {
version: "1",
name: this.name,
age: this.age,
};
}
getInfo() {
return `name: ${this.name}, age: ${this.age.toString()}`;
}
}
const array_ = [0, -1, 1, -1.5, 1.5, true, false, "str"];
const object_ = {
a: 0,
b: -1,
c: 1,
d: -1.5,
e: 1.5,
i: "str",
j: true,
l: false,
};
beforeEach(() => {
flexibleSerdeAdapter = createAdapter();
});
test("Should work with positive integer", () => {
const value = 1;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with negative integer", () => {
const value = -1;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with positive decimal", () => {
const value = 1.5;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with negative decimal", () => {
const value = -1.5;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with true", () => {
const value = true;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with false", () => {
const value = false;
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with string", () => {
const value = "str";
expect(flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value))).toBe(value);
});
test("Should work with array of number, boolean, string, object, array", () => {
const value = [
...array_,
array_,
{
...object_,
object_,
array: [
...array_,
array_,
{
...object_,
object_,
array_,
},
],
},
];
const deserializedValue = flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value));
expect(deserializedValue).toEqual(value);
});
test("Should work with object of number, boolean, string, array, object", () => {
const value = {
...object_,
object_,
array: [
...array_,
array_,
{
...object_,
object_,
array_,
},
],
};
const deserializedValue = flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value));
expect(deserializedValue).toEqual(value);
});
test("Should work with custom ISerdeTransformerAdapter", () => {
const transformer = {
name: User.name,
isApplicable(value) {
return (value instanceof User &&
value.constructor.name === User.name);
},
deserialize(serializedValue) {
return User.deserialize(serializedValue);
},
serialize(deserializedValue) {
return deserializedValue.serialize();
},
};
flexibleSerdeAdapter.registerCustom(transformer);
const value = new User("a", 20);
const deserializedValue = flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value));
expect(deserializedValue).toBeInstanceOf(User);
expect(deserializedValue.age).toBe(value.age);
expect(deserializedValue.name).toBe(value.name);
});
test("Should call on the first ISerdeTransformerAdapter when same name is used", () => {
const transformer1 = {
name: User.name,
isApplicable: (value) => {
return (value instanceof User &&
value.constructor.name === User.name);
},
deserialize: (serializedValue) => {
return User.deserialize(serializedValue);
},
serialize: (deserializedValue) => {
return deserializedValue.serialize();
},
};
const isApplicable = vi.spyOn(transformer1, "isApplicable");
const serialize = vi.spyOn(transformer1, "serialize");
const deserialize = vi.spyOn(transformer1, "deserialize");
flexibleSerdeAdapter.registerCustom(transformer1);
const transformer2 = {
name: User.name,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
isApplicable: vi.fn((value) => {
return (value instanceof User &&
value.constructor.name === User.name);
}),
deserialize: vi.fn((serializedValue) => {
return User.deserialize(serializedValue);
}),
serialize: vi.fn((deserializedValue) => {
return deserializedValue.serialize();
}),
};
flexibleSerdeAdapter.registerCustom(transformer2);
const value = new User("a", 20);
flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value));
expect(isApplicable).toHaveBeenCalled();
expect(serialize).toHaveBeenCalled();
expect(deserialize).toHaveBeenCalled();
});
test("Should not call on the second ISerdeTransformerAdapter when same name is used", () => {
const transformer1 = {
name: User.name,
isApplicable: (value) => {
return (value instanceof User &&
value.constructor.name === User.name);
},
deserialize: (serializedValue) => {
return User.deserialize(serializedValue);
},
serialize: (deserializedValue) => {
return deserializedValue.serialize();
},
};
flexibleSerdeAdapter.registerCustom(transformer1);
const transformer2 = {
name: User.name,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
isApplicable: vi.fn((value) => {
return (value instanceof User &&
value.constructor.name === User.name);
}),
deserialize: vi.fn((serializedValue) => {
return User.deserialize(serializedValue);
}),
serialize: vi.fn((deserializedValue) => {
return deserializedValue.serialize();
}),
};
const isApplicable = vi.spyOn(transformer2, "isApplicable");
const serialize = vi.spyOn(transformer2, "serialize");
const deserialize = vi.spyOn(transformer2, "deserialize");
flexibleSerdeAdapter.registerCustom(transformer2);
const value = new User("a", 20);
flexibleSerdeAdapter.deserialize(flexibleSerdeAdapter.serialize(value));
expect(isApplicable).not.toHaveBeenCalled();
expect(serialize).not.toHaveBeenCalled();
expect(deserialize).not.toHaveBeenCalled();
});
}
//# sourceMappingURL=flexible-serde-adapter.test-suite.js.map