Switched to deno
This commit is contained in:
parent
b9388a8f11
commit
f915a4b889
15 changed files with 238 additions and 8993 deletions
|
@ -1,10 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
[*.{ts,json}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
max_line_length = off
|
||||
|
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,5 +1,3 @@
|
|||
.venv
|
||||
node_modules
|
||||
.rts2_cache_*
|
||||
.coverage
|
||||
/dist/
|
||||
deno.d.ts
|
||||
.vscode
|
||||
.local
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
image: node:latest
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
test:
|
||||
before_script:
|
||||
- npm install
|
||||
script:
|
||||
- npm test
|
73
README.md
73
README.md
|
@ -1,73 +0,0 @@
|
|||
tk-serializer
|
||||
=============
|
||||
|
||||
[![pipeline status](https://gitlab.com/thunderk/tk-serializer/badges/master/pipeline.svg)](https://gitlab.com/thunderk/tk-serializer/commits/master)
|
||||
[![coverage report](https://gitlab.com/thunderk/tk-serializer/badges/master/coverage.svg)](https://gitlab.com/thunderk/tk-serializer/commits/master)
|
||||
[![npm version](https://img.shields.io/npm/v/tk-serializer.svg)](https://npmjs.com/tk-serializer)
|
||||
[![npm size](https://img.shields.io/bundlephobia/min/tk-serializer.svg)](https://bundlephobia.com/result?p=tk-serializer)
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
This library offers a generic serialization system for Javascript.
|
||||
|
||||
Deep objects state may be serialized to a string, and reconstructed back.
|
||||
|
||||
Class instances are reconstructed properly, as long as they are in the provided namespace. Circular references are handled.
|
||||
|
||||
Be warned that resulting serialized value may be quite large.
|
||||
|
||||
Typescript definitions are included.
|
||||
|
||||
Issues can be reported on [GitLab](https://gitlab.com/thunderk/tk-serializer/issues).
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
Import in node:
|
||||
|
||||
```shell
|
||||
npm install tk-serializer
|
||||
```
|
||||
|
||||
```javascript
|
||||
import { Serializer } from "tk-serializer";
|
||||
```
|
||||
|
||||
Import in browser:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/tk-serializer"></script>
|
||||
```
|
||||
|
||||
```javascript
|
||||
const Serializer = tkSerializer.Serializer;
|
||||
```
|
||||
|
||||
Use
|
||||
---
|
||||
|
||||
Suppose you have 2 classes Class1 and Class2, whose instances you want to serialize:
|
||||
|
||||
```javascript
|
||||
const namespace = {
|
||||
Class1,
|
||||
Class2
|
||||
};
|
||||
const obj = {
|
||||
a: [1, "a", new Class1()],
|
||||
b: new Class2("x"),
|
||||
c: new Class3()
|
||||
};
|
||||
|
||||
let serializer = new Serializer(namespace);
|
||||
|
||||
// Optionally, some class instances may be ignored (they will be replaced by *undefined*)
|
||||
serializer.addIgnoredClass(Class3);
|
||||
|
||||
// Serialize the object to a string
|
||||
let state = serializer.serialize(obj);
|
||||
|
||||
// Reconstruct the object back (*c* will be undefined)
|
||||
let nobj = serializer.unserialize(state);
|
||||
```
|
|
@ -1,16 +0,0 @@
|
|||
# Activation script for virtual nodejs environment
|
||||
# Usage:
|
||||
# source activate_node
|
||||
|
||||
vdir="./.venv"
|
||||
expected="12.13.0"
|
||||
|
||||
if [ \! -f "./activate_node" ]
|
||||
then
|
||||
echo "Not in project directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -x "${vdir}/bin/nodeenv" || ( python3 -m venv "${vdir}" && "${vdir}/bin/pip" install --upgrade nodeenv )
|
||||
test "$(${vdir}/node/bin/nodejs --version)" = "v${expected}" || "${vdir}/bin/nodeenv" --node=${expected} --force "${vdir}/node"
|
||||
source "${vdir}/node/bin/activate"
|
1
all.ts
Normal file
1
all.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { Serializer } from "./serializer.ts";
|
|
@ -1,27 +0,0 @@
|
|||
module.exports = {
|
||||
transform: {
|
||||
"^.+\\.ts$": "ts-jest"
|
||||
},
|
||||
moduleFileExtensions: [
|
||||
"ts",
|
||||
"js",
|
||||
"json",
|
||||
"node"
|
||||
],
|
||||
watchPathIgnorePatterns: [
|
||||
"<rootDir>/dist/",
|
||||
"<rootDir>/node_modules/",
|
||||
],
|
||||
restoreMocks: true,
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: [
|
||||
"src/**/*.ts",
|
||||
"!src/**/*.test.ts",
|
||||
],
|
||||
coverageDirectory: ".coverage",
|
||||
coverageReporters: [
|
||||
"lcovonly",
|
||||
"html",
|
||||
"text-summary"
|
||||
]
|
||||
}
|
8604
package-lock.json
generated
8604
package-lock.json
generated
File diff suppressed because it is too large
Load diff
43
package.json
43
package.json
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"name": "tk-serializer",
|
||||
"version": "1.2.0",
|
||||
"description": "Typescript/Javascript serializer, with full object reconstruction",
|
||||
"author": {
|
||||
"name": "Michaël Lemaire",
|
||||
"url": "https://thunderk.net"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://code.thunderk.net/tslib/tk-serializer.git"
|
||||
},
|
||||
"license": "ISC",
|
||||
"source": "src/index.ts",
|
||||
"main": "dist/tk-serializer.umd.js",
|
||||
"module": "dist/tk-serializer.modern.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "microbundle build -f modern,umd",
|
||||
"test": "jest",
|
||||
"prepare": "npm run build",
|
||||
"prepublishOnly": "npm test",
|
||||
"normalize": "tk-base",
|
||||
"dev": "run-p dev:*",
|
||||
"dev:test": "jest --watchAll",
|
||||
"dev:build": "microbundle watch -f modern,umd",
|
||||
"dev:serve": "live-server --host=localhost --port=5000 --no-browser --ignorePattern='.*\\.d\\.ts' dist"
|
||||
},
|
||||
"files": [
|
||||
"/src",
|
||||
"/dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"tk-base": "^0.2.5"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/thunderk/tk-serializer/issues"
|
||||
},
|
||||
"homepage": "https://code.thunderk.net/tslib/tk-serializer",
|
||||
"keywords": [
|
||||
"typescript"
|
||||
]
|
||||
}
|
195
serializer.test.ts
Normal file
195
serializer.test.ts
Normal file
|
@ -0,0 +1,195 @@
|
|||
import {
|
||||
it,
|
||||
expect,
|
||||
patch,
|
||||
} from "https://code.thunderk.net/typescript/deno_tools/raw/1.0.0/testing.ts";
|
||||
import { Serializer } from "./serializer.ts";
|
||||
|
||||
class TestSerializerObj1 {
|
||||
a: number;
|
||||
constructor(a = 0) {
|
||||
this.a = a;
|
||||
}
|
||||
}
|
||||
|
||||
class TestSerializerObj2 {
|
||||
a = () => 1;
|
||||
b = [(obj: any) => 2];
|
||||
}
|
||||
|
||||
class TestSerializerObj3 {
|
||||
a = [1, 2];
|
||||
postUnserialize() {
|
||||
this.a.push(3);
|
||||
}
|
||||
}
|
||||
|
||||
class TestSerializerObj4 extends TestSerializerObj1 {
|
||||
}
|
||||
|
||||
const TEST_NS = {
|
||||
TestSerializerObj1,
|
||||
TestSerializerObj2,
|
||||
TestSerializerObj3,
|
||||
};
|
||||
|
||||
const TEST_NS_FLAT = [
|
||||
TestSerializerObj1,
|
||||
TestSerializerObj2,
|
||||
TestSerializerObj3,
|
||||
];
|
||||
|
||||
const TEST_NS_RENAME = {
|
||||
ob1: TestSerializerObj1,
|
||||
ob2: TestSerializerObj2,
|
||||
ob3: TestSerializerObj3,
|
||||
};
|
||||
|
||||
function checkReversability(
|
||||
obj: any,
|
||||
namespace: any = TEST_NS,
|
||||
equality?: (loaded: any, orig: any) => void,
|
||||
): any {
|
||||
var serializer = new Serializer(namespace);
|
||||
var data = serializer.serialize(obj);
|
||||
serializer = new Serializer(namespace);
|
||||
var loaded = serializer.unserialize(data);
|
||||
if (equality) {
|
||||
equality(loaded, obj);
|
||||
} else {
|
||||
expect(loaded).toEqual(obj);
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
it("serializes simple objects", () => {
|
||||
var obj = {
|
||||
"a": 5,
|
||||
"b": null,
|
||||
"c": [{ "a": 2 }, "test"],
|
||||
};
|
||||
checkReversability(obj);
|
||||
});
|
||||
|
||||
it("restores objects constructed from class", () => {
|
||||
let loaded = checkReversability(new TestSerializerObj1(5));
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
|
||||
loaded = checkReversability(new TestSerializerObj1(5), TEST_NS_FLAT);
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
|
||||
loaded = checkReversability(new TestSerializerObj1(5), TEST_NS_RENAME);
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
});
|
||||
|
||||
it("stores one version of the same object", () => {
|
||||
var a = new TestSerializerObj1(8);
|
||||
var b = new TestSerializerObj1(8);
|
||||
var c = {
|
||||
"r": a,
|
||||
"s": ["test", a],
|
||||
"t": a,
|
||||
"u": b,
|
||||
};
|
||||
var loaded = checkReversability(c);
|
||||
expect(loaded.t).toBe(loaded.r);
|
||||
expect(loaded.s[1]).toBe(loaded.r);
|
||||
expect(loaded.u).not.toBe(loaded.r);
|
||||
});
|
||||
|
||||
it("handles circular references", () => {
|
||||
var a: any = { b: {} };
|
||||
a.b.c = a;
|
||||
|
||||
checkReversability(a, undefined, (loaded) => {
|
||||
expect(Object.keys(loaded)).toEqual(["b"]);
|
||||
expect(Object.keys(loaded.b)).toEqual(["c"]);
|
||||
expect(Object.keys(loaded.b.c)).toEqual(["b"]);
|
||||
expect(Object.keys(loaded.b.c.b)).toEqual(["c"]);
|
||||
expect(loaded.b.c).toBe(loaded);
|
||||
expect(loaded.b.c.b).toBe(loaded.b);
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores some classes", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
serializer.addIgnoredClass("TestSerializerObj1");
|
||||
|
||||
let data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
|
||||
serializer = new Serializer(TEST_NS);
|
||||
serializer.addIgnoredClass(TestSerializerObj1);
|
||||
|
||||
data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
|
||||
serializer = new Serializer(TEST_NS_RENAME);
|
||||
serializer.addIgnoredClass(TestSerializerObj1);
|
||||
|
||||
data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
});
|
||||
|
||||
it("ignores functions", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj2() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
let expected = <any> new TestSerializerObj2();
|
||||
expected.a = undefined;
|
||||
expected.b[0] = undefined;
|
||||
expect(loaded).toEqual({ obj: expected });
|
||||
});
|
||||
|
||||
it("calls specific postUnserialize", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj3() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
let expected = new TestSerializerObj3();
|
||||
expected.a = [1, 2, 3];
|
||||
expect(loaded).toEqual({ obj: expected });
|
||||
});
|
||||
|
||||
it("handles missing classes", () => {
|
||||
const mock_error = patch(console, "error", () => {});
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
mock_error.exec(() => {
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj4() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
expect(loaded).toEqual({ obj: { a: 0 } });
|
||||
expect(mock_error.fn).toHaveBeenCalledWith(
|
||||
"Can't find class",
|
||||
"TestSerializerObj4",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("uses namespace alias to protect from property mangling", () => {
|
||||
const data = {
|
||||
a: new TestSerializerObj1(1),
|
||||
b: new TestSerializerObj1(2),
|
||||
c: [new TestSerializerObj1(3)],
|
||||
};
|
||||
|
||||
const serializer1 = new Serializer(TEST_NS);
|
||||
const serializer2 = new Serializer(TEST_NS_RENAME);
|
||||
|
||||
const dumped1 = serializer1.serialize(data);
|
||||
const dumped2 = serializer2.serialize(data);
|
||||
|
||||
expect(dumped1.length).toBeGreaterThan(dumped2.length);
|
||||
|
||||
expect(serializer1.unserialize(dumped1)).toEqual(data);
|
||||
expect(serializer2.unserialize(dumped2)).toEqual(data);
|
||||
});
|
|
@ -16,7 +16,12 @@ function isObject(value: any): boolean {
|
|||
*
|
||||
* *memo* is used to prevent circular references to be traversed
|
||||
*/
|
||||
function crawl(obj: any, callback: (item: any) => any, replace = false, memo: any[] = []) {
|
||||
function crawl(
|
||||
obj: any,
|
||||
callback: (item: any) => any,
|
||||
replace = false,
|
||||
memo: any[] = [],
|
||||
) {
|
||||
if (isObject(obj)) {
|
||||
if (memo.indexOf(obj) >= 0) {
|
||||
return obj;
|
||||
|
@ -33,7 +38,7 @@ function crawl(obj: any, callback: (item: any) => any, replace = false, memo: an
|
|||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
let subresult = obj.map(value => crawl(value, callback, replace, memo));
|
||||
let subresult = obj.map((value) => crawl(value, callback, replace, memo));
|
||||
if (replace) {
|
||||
subresult.forEach((value, index) => {
|
||||
obj[index] = value;
|
||||
|
@ -59,10 +64,10 @@ function crawl(obj: any, callback: (item: any) => any, replace = false, memo: an
|
|||
* Get the class name of an object.
|
||||
*/
|
||||
function classname(obj: Object): string {
|
||||
return (<any>obj.constructor).name;
|
||||
return (<any> obj.constructor).name;
|
||||
}
|
||||
|
||||
type SerializerNamespace = { [name: string]: { new(): any } };
|
||||
type SerializerNamespace = { [name: string]: { new (): any } };
|
||||
|
||||
/**
|
||||
* A deep serializer of javascript objects.
|
||||
|
@ -91,7 +96,7 @@ export class Serializer {
|
|||
/**
|
||||
* Add a class to the ignore list
|
||||
*/
|
||||
addIgnoredClass(cl: string | { new(): any }) {
|
||||
addIgnoredClass(cl: string | { new (): any }) {
|
||||
this.ignored.push(typeof cl === "string" ? cl : cl.name);
|
||||
}
|
||||
|
||||
|
@ -119,7 +124,7 @@ export class Serializer {
|
|||
// Collect objects
|
||||
var objects: Object[] = [];
|
||||
var stats: any = {};
|
||||
crawl(obj, value => {
|
||||
crawl(obj, (value) => {
|
||||
if (isObject(value)) {
|
||||
var vtype = classname(value);
|
||||
if (vtype != "" && this.ignored.indexOf(vtype) < 0) {
|
||||
|
@ -138,9 +143,17 @@ export class Serializer {
|
|||
//console.log("Serialize stats", stats);
|
||||
|
||||
// Serialize objects list, transforming deeper objects to links
|
||||
var fobjects = objects.map(value => <Object>{ $c: this.namespace_rev[classname(value)] || classname(value), $f: merge({}, value) });
|
||||
var fobjects = objects.map((value) =>
|
||||
<Object> {
|
||||
$c: this.namespace_rev[classname(value)] || classname(value),
|
||||
$f: merge({}, value),
|
||||
}
|
||||
);
|
||||
return JSON.stringify(fobjects, (key, value) => {
|
||||
if (key != "$f" && isObject(value) && !value.hasOwnProperty("$c") && !value.hasOwnProperty("$i")) {
|
||||
if (
|
||||
key != "$f" && isObject(value) && !value.hasOwnProperty("$c") &&
|
||||
!value.hasOwnProperty("$i")
|
||||
) {
|
||||
return { $i: objects.indexOf(value) };
|
||||
} else {
|
||||
return value;
|
||||
|
@ -156,20 +169,24 @@ export class Serializer {
|
|||
var fobjects = JSON.parse(data);
|
||||
|
||||
// Reconstruct objects
|
||||
var objects = fobjects.map((objdata: any) => merge(this.constructObject(objdata['$c']), objdata['$f']));
|
||||
var objects = fobjects.map((objdata: any) =>
|
||||
merge(this.constructObject(objdata["$c"]), objdata["$f"])
|
||||
);
|
||||
|
||||
// Reconnect links
|
||||
crawl(objects, value => {
|
||||
if (value instanceof Object && value.hasOwnProperty('$i')) {
|
||||
return objects[value['$i']];
|
||||
crawl(objects, (value) => {
|
||||
if (value instanceof Object && value.hasOwnProperty("$i")) {
|
||||
return objects[value["$i"]];
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Post unserialize hooks
|
||||
crawl(objects[0], value => {
|
||||
if (value instanceof Object && typeof value.postUnserialize === "function") {
|
||||
crawl(objects[0], (value) => {
|
||||
if (
|
||||
value instanceof Object && typeof value.postUnserialize === "function"
|
||||
) {
|
||||
value.postUnserialize();
|
||||
}
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
import * as index from "./index";
|
||||
|
||||
describe("index", () => {
|
||||
it("exposes Serializer", () => {
|
||||
expect(index.Serializer).toBeTruthy();
|
||||
});
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
export { Serializer } from "./serializer";
|
|
@ -1,172 +0,0 @@
|
|||
import { Serializer } from "./serializer";
|
||||
|
||||
class TestSerializerObj1 {
|
||||
a: number;
|
||||
constructor(a = 0) {
|
||||
this.a = a;
|
||||
}
|
||||
}
|
||||
|
||||
class TestSerializerObj2 {
|
||||
a = () => 1
|
||||
b = [(obj: any) => 2]
|
||||
}
|
||||
|
||||
class TestSerializerObj3 {
|
||||
a = [1, 2];
|
||||
postUnserialize() {
|
||||
this.a.push(3);
|
||||
}
|
||||
}
|
||||
|
||||
class TestSerializerObj4 extends TestSerializerObj1 {
|
||||
}
|
||||
|
||||
const TEST_NS = {
|
||||
TestSerializerObj1,
|
||||
TestSerializerObj2,
|
||||
TestSerializerObj3,
|
||||
};
|
||||
|
||||
const TEST_NS_FLAT = [
|
||||
TestSerializerObj1,
|
||||
TestSerializerObj2,
|
||||
TestSerializerObj3,
|
||||
];
|
||||
|
||||
const TEST_NS_RENAME = {
|
||||
ob1: TestSerializerObj1,
|
||||
ob2: TestSerializerObj2,
|
||||
ob3: TestSerializerObj3,
|
||||
}
|
||||
|
||||
describe("Serializer", () => {
|
||||
function checkReversability(obj: any, namespace: any = TEST_NS): any {
|
||||
var serializer = new Serializer(namespace);
|
||||
var data = serializer.serialize(obj);
|
||||
serializer = new Serializer(namespace);
|
||||
var loaded = serializer.unserialize(data);
|
||||
expect(loaded).toEqual(obj);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
it("serializes simple objects", () => {
|
||||
var obj = {
|
||||
"a": 5,
|
||||
"b": null,
|
||||
"c": [{ "a": 2 }, "test"]
|
||||
};
|
||||
checkReversability(obj);
|
||||
});
|
||||
|
||||
it("restores objects constructed from class", () => {
|
||||
let loaded = checkReversability(new TestSerializerObj1(5));
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
|
||||
loaded = checkReversability(new TestSerializerObj1(5), TEST_NS_FLAT);
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
|
||||
loaded = checkReversability(new TestSerializerObj1(5), TEST_NS_RENAME);
|
||||
expect(loaded.a).toBe(5);
|
||||
expect(loaded).toBeInstanceOf(TestSerializerObj1);
|
||||
});
|
||||
|
||||
it("stores one version of the same object", () => {
|
||||
var a = new TestSerializerObj1(8);
|
||||
var b = new TestSerializerObj1(8);
|
||||
var c = {
|
||||
'r': a,
|
||||
's': ["test", a],
|
||||
't': a,
|
||||
'u': b
|
||||
};
|
||||
var loaded = checkReversability(c);
|
||||
expect(loaded.t).toBe(loaded.r);
|
||||
expect(loaded.s[1]).toBe(loaded.r);
|
||||
expect(loaded.u).not.toBe(loaded.r);
|
||||
});
|
||||
|
||||
it("handles circular references", () => {
|
||||
var a: any = { b: {} };
|
||||
a.b.c = a;
|
||||
|
||||
checkReversability(a);
|
||||
});
|
||||
|
||||
it("ignores some classes", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
serializer.addIgnoredClass("TestSerializerObj1");
|
||||
|
||||
let data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
|
||||
serializer = new Serializer(TEST_NS);
|
||||
serializer.addIgnoredClass(TestSerializerObj1);
|
||||
|
||||
data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
|
||||
serializer = new Serializer(TEST_NS_RENAME);
|
||||
serializer.addIgnoredClass(TestSerializerObj1);
|
||||
|
||||
data = serializer.serialize({ a: 5, b: new TestSerializerObj1() });
|
||||
loaded = serializer.unserialize(data);
|
||||
|
||||
expect(loaded).toEqual({ a: 5, b: undefined });
|
||||
});
|
||||
|
||||
it("ignores functions", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj2() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
let expected = <any>new TestSerializerObj2();
|
||||
expected.a = undefined;
|
||||
expected.b[0] = undefined;
|
||||
expect(loaded).toEqual({ obj: expected });
|
||||
});
|
||||
|
||||
it("calls specific postUnserialize", () => {
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj3() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
|
||||
let expected = new TestSerializerObj3();
|
||||
expected.a = [1, 2, 3];
|
||||
expect(loaded).toEqual({ obj: expected });
|
||||
});
|
||||
|
||||
it("handles missing classes", () => {
|
||||
jest.spyOn(console, "error").mockImplementation();
|
||||
let serializer = new Serializer(TEST_NS);
|
||||
let data = serializer.serialize({ obj: new TestSerializerObj4() });
|
||||
let loaded = serializer.unserialize(data);
|
||||
expect(loaded).toEqual({ obj: { a: 0 } });
|
||||
expect(console.error).toHaveBeenCalledWith("Can't find class", "TestSerializerObj4");
|
||||
});
|
||||
|
||||
it("uses namespace alias to protect from property mangling", () => {
|
||||
const data = {
|
||||
a: new TestSerializerObj1(1),
|
||||
b: new TestSerializerObj1(2),
|
||||
c: [new TestSerializerObj1(3)],
|
||||
};
|
||||
|
||||
const serializer1 = new Serializer(TEST_NS);
|
||||
const serializer2 = new Serializer(TEST_NS_RENAME);
|
||||
|
||||
const dumped1 = serializer1.serialize(data);
|
||||
const dumped2 = serializer2.serialize(data);
|
||||
|
||||
expect(dumped1.length).toBeGreaterThan(dumped2.length);
|
||||
|
||||
expect(serializer1.unserialize(dumped1)).toEqual(data);
|
||||
expect(serializer2.unserialize(dumped2)).toEqual(data);
|
||||
});
|
||||
});
|
|
@ -1,21 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"target": "ESNext",
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"preserveConstEnums": true,
|
||||
"declaration": true,
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es6"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"src/**/*.test.ts"
|
||||
]
|
||||
"preserveConstEnums": true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue