UNPKG

@deepkit/bson

Version:
253 lines 12.5 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const globals_1 = require("@jest/globals"); require("reflect-metadata"); const type_1 = require("@deepkit/type"); const bson_1 = __importDefault(require("bson")); const bson_serialize_1 = require("../src/bson-serialize"); const bson_jit_parser_1 = require("../src/bson-jit-parser"); const { calculateObjectSize, serialize, deserialize } = bson_1.default; var MyEnum; (function (MyEnum) { MyEnum[MyEnum["first"] = 0] = "first"; MyEnum[MyEnum["second"] = 1] = "second"; MyEnum[MyEnum["third"] = 2] = "third"; })(MyEnum || (MyEnum = {})); var MyEnum2; (function (MyEnum2) { MyEnum2["first"] = "first"; MyEnum2["second"] = "second"; MyEnum2["third"] = "third"; })(MyEnum2 || (MyEnum2 = {})); let DecoratedValue = class DecoratedValue { constructor(c = []) { this.c = c; } }; DecoratedValue = __decorate([ __param(0, type_1.t.array(type_1.t.string).decorated), __metadata("design:paramtypes", [Array]) ], DecoratedValue); class DecoratedValue2 { constructor() { this.items = []; } } __decorate([ type_1.t.array(type_1.t.string).decorated, __metadata("design:type", Array) ], DecoratedValue2.prototype, "items", void 0); let MyModel = class MyModel { constructor(name) { this.name = name; this.type = 'a'; this.items = new DecoratedValue; } }; __decorate([ type_1.t.literal('a').discriminant, __metadata("design:type", String) ], MyModel.prototype, "type", void 0); __decorate([ type_1.t, __metadata("design:type", DecoratedValue) ], MyModel.prototype, "items", void 0); MyModel = __decorate([ type_1.entity.name('myModel'), __param(0, type_1.t), __metadata("design:paramtypes", [String]) ], MyModel); let SimpleModel = class SimpleModel { constructor(name) { this.name = name; this.items = new DecoratedValue; } }; __decorate([ type_1.t, __metadata("design:type", DecoratedValue) ], SimpleModel.prototype, "items", void 0); SimpleModel = __decorate([ __param(0, type_1.t), __metadata("design:paramtypes", [String]) ], SimpleModel); const ab = new ArrayBuffer(2); const uint8Array = new Uint8Array(ab); uint8Array[0] = 11; uint8Array[1] = 22; globals_1.test('compare ab', () => { const other = new Uint8Array([11, 22]).buffer; globals_1.expect(ab).toEqual(other); }); const decoratedValue2 = new DecoratedValue2(); decoratedValue2.items = ['a', 'b', 'c']; const actualUndefined = Symbol('undefined'); const types = [ [type_1.t.string, 'Hello Peter'], [type_1.t.number, 1], [type_1.t.number, 0], [type_1.t.number, -1], [type_1.t.number, -90071992547409920], [type_1.t.number, 90071992547409920], [type_1.t.number, 134.444444445], [type_1.t.number, -134.444444445], [type_1.t.number, 212313134.444444445], [type_1.t.number, -1212313134.444444445], [type_1.t.bigint, -1348574839n, undefined, true], [type_1.t.bigint, -156n, undefined, true], [type_1.t.bigint, -0n, undefined, true], [type_1.t.bigint, 0n, undefined, true], [type_1.t.bigint, 555n, undefined, true], [type_1.t.bigint, 9223372036854775810n, undefined, true], [type_1.t.bigint, -9223372036854775810n, undefined, true], [type_1.t.any, -1348574839n, undefined, true], [type_1.t.any, -156n, undefined, true], [type_1.t.any, -0n, undefined, true], [type_1.t.any, 0n, undefined, true], [type_1.t.any, 555n, undefined, true], [type_1.t.any, 9223372036854775810n, undefined, true], [type_1.t.any, -9223372036854775810n, undefined, true], [type_1.t.bigint, undefined, undefined, true], [type_1.t.bigint, 'asd', actualUndefined, true], [type_1.t.boolean, false], [type_1.t.boolean, true], [type_1.t.boolean, true], [type_1.t.uuid, 'bef8de96-41fe-442f-b70c-c3a150f8c96c'], [type_1.t.uuid, 'bef8de92-41fe-442f-b70c-c3a150f8c961'], [type_1.t.mongoId, '507f191e810c19729de860ea'], [type_1.t.date, new Date('1987-10-12T00:00:00.000Z')], [type_1.t.date, new Date('2920-08-09T19:02:28.397Z')], [type_1.t.date, new Date('2020-08-09T19:02:28.397Z')], [type_1.t.date, new Date('1900-10-12T00:00:00.000Z')], [type_1.t.date, new Date('1000-10-12T00:00:00.000Z')], [type_1.t.enum(MyEnum), MyEnum.first], [type_1.t.enum(MyEnum), MyEnum.second], [type_1.t.enum(MyEnum), MyEnum.third], [type_1.t.enum(MyEnum2), MyEnum2.first], [type_1.t.enum(MyEnum2), MyEnum2.second], [type_1.t.enum(MyEnum2), MyEnum2.third], [type_1.t.type({ name: type_1.t.string }), { name: 'Peter' }], [type_1.t.union(type_1.t.string, MyModel), 'asd'], [type_1.t.union(type_1.t.string, MyModel), { name: 'foo' }, new MyModel('foo'), true], [type_1.t.union(type_1.t.string, SimpleModel), 'asd'], [type_1.t.union(type_1.t.string, SimpleModel), { name: 'foo' }, new SimpleModel('foo')], [type_1.t.union(type_1.t.mongoId, SimpleModel), '507f191e810c19729de860ea', undefined, true], [type_1.t.union(type_1.t.mongoId, SimpleModel), { name: 'foo' }, new SimpleModel('foo')], [type_1.t.union(type_1.t.string, type_1.t.array(type_1.t.string)), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.array(type_1.t.string)), ['a', 'b']], [type_1.t.union(type_1.t.string, type_1.t.uuid), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.uuid), '3c25985e-4e25-45db-9e8a-a487cc78929a'], [type_1.t.union(type_1.t.string, type_1.t.mongoId), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.mongoId), '507f191e810c19729de860ea', undefined, true], [type_1.t.union(type_1.t.string, type_1.t.uuid, type_1.t.date), '3c25985e-4e25-45db-9e8a-a487cc78929a'], [type_1.t.union(type_1.t.string, type_1.t.uuid, type_1.t.date), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.map(type_1.t.string)), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.map(type_1.t.string)), { first: 'asd', second: 'asd' }], [type_1.t.union(type_1.t.string, type_1.t.partial(MyModel)), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.partial(MyModel)), { name: 'asd' }], [type_1.t.union(type_1.t.string, type_1.t.type(ArrayBuffer)), 'asd'], [type_1.t.union(type_1.t.string, type_1.t.type(ArrayBuffer)), ab, undefined, true], [type_1.t.union(type_1.t.string, type_1.t.type(Uint8Array)), uint8Array, undefined, true], [type_1.t.type(DecoratedValue), new DecoratedValue(['a', 'b']), undefined, true], [type_1.t.type(DecoratedValue2), decoratedValue2, undefined, true], [type_1.t.union(type_1.t.string, MyModel), { type: 'a', name: 'Peter', items: new DecoratedValue(['a', 'b']), }, undefined, true], [type_1.t.array(type_1.t.string), ['Peter', 'b']], [type_1.t.array(type_1.t.number.optional), [1, undefined, 2], undefined, true], [type_1.t.array(type_1.t.string.optional), ['Peter', undefined, 'Bar'], undefined, true], [type_1.t.array(type_1.t.string.nullable), ['Peter', null, 'Bar']], [type_1.t.array(type_1.t.union(type_1.t.string, type_1.t.number)), ['Peter', 23, 'Bar']], [type_1.t.array(type_1.t.union(type_1.t.boolean, type_1.t.number)), [false, 23, true]], [type_1.t.map(type_1.t.string), { name: 'Peter' }], [type_1.t.any, { name: 'Peter', ready: false }], [type_1.t.type(ArrayBuffer), ab], [type_1.t.type(Uint8Array), new Uint8Array([22, 44, 55, 66])], [type_1.t.type(Int16Array), new Int16Array([22, 44, 55, 66])], [type_1.t.union(type_1.t.type({ type: type_1.t.literal('m'), name: type_1.t.string })), { type: 'm', name: 'Peter' }], [type_1.t.partial({ name: type_1.t.string }), {}], [type_1.t.partial({ name: type_1.t.string }), { name: 'Peter' }], [type_1.t.any, new RegExp('/abc/', 'g')], [type_1.t.any, new RegExp(/abc/, 'g')], [type_1.t.any, /abc/g], [type_1.t.any, /abc/i], [type_1.t.any, /abc/m], [type_1.t.any, /abc/gim], ]; globals_1.describe('integration', () => { for (let i = 0; i < types.length; i++) { const type = types[i]; const [field, value, expected, dontCompareToBSONJS] = type; const property = field.buildPropertySchema('test_' + i); globals_1.test(`types round-trip #${i} ${property.toString()}: ${value}`, () => { const s = type_1.t.schema({ field: field }); const sOptional = type_1.t.schema({ field: field.optional }); const sNullable = type_1.t.schema({ field: field.nullable }); const obj = { field: value }; const expectedFieldValue = expected === actualUndefined ? undefined : expected ?? value; const expectedObj = { field: expectedFieldValue }; globals_1.expect(sOptional.getProperty('field').isOptional).toBe(true); globals_1.expect(sNullable.getProperty('field').isNullable).toBe(true); const serializer = bson_serialize_1.getBSONSerializer(s); const bsonDeepkit = serializer(obj); // console.log(`types round-trip #${i} ${property.toString()}: ${value} back`, obj, deserialize(Buffer.from(bsonDeepkit))); const decoder = bson_jit_parser_1.getBSONDecoder(s); const decoded = decoder(bsonDeepkit); globals_1.expect(decoded).toEqual(expectedObj); globals_1.expect(decoder(serializer({}))).toEqual({}); //optional // expect(getBSONDecoder(sOptional)(getBSONSerializer(sOptional)({}))).toEqual({}); const optionalTrip = bson_jit_parser_1.getBSONDecoder(sOptional)(bson_serialize_1.getBSONSerializer(sOptional)({ field: undefined })); globals_1.expect(optionalTrip).toEqual({ field: undefined }); globals_1.expect('field' in optionalTrip).toEqual(true); //null globals_1.expect(bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: undefined }))).toEqual({ field: null }); globals_1.expect('field' in bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: undefined }))).toEqual(true); const nullTrip = bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: null })); globals_1.expect(nullTrip).toEqual({ field: null }); const type = field.buildPropertySchema().type; const blacklist = [ 'uuid', 'objectId', 'arrayBuffer', 'Uint8Array', 'Int16Array' ]; if (blacklist.includes(type)) return; if (dontCompareToBSONJS) return; globals_1.expect(bson_serialize_1.createBSONSizer(s)(obj)).toEqual(calculateObjectSize(obj)); //official BSON serializer has a bug not serializing LONG correctly if (field.buildPropertySchema().type === 'number' && (value > bson_serialize_1.JS_INT_MAX || value < bson_serialize_1.JS_INT_MIN)) return; const bsonOfficial = serialize(obj); globals_1.expect(obj).toEqual(deserialize(serialize(obj))); globals_1.expect(bsonDeepkit).toEqual(bsonOfficial); }); } }); //# sourceMappingURL=integration.spec.js.map