jsonbinpack
Version:
A space-efficient schema-driven binary JSON serialization format based on JSON Schema
401 lines (400 loc) • 18.7 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var tap_1 = __importDefault(require("tap"));
var fc = __importStar(require("fast-check"));
var dictionaries_1 = require("../../lib/encoder/string/dictionaries");
var encode_1 = require("../../lib/encoder/string/encode");
var decode_1 = require("../../lib/encoder/string/decode");
var limits_1 = require("../../lib/utils/limits");
var encoder_1 = require("../../lib/encoder");
tap_1.default.test('STRING_BROTLI: "The quick brown fox jumps over the lazy dog"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'The quick brown fox jumps over the lazy dog';
var bytesWritten = encode_1.STRING_BROTLI(buffer, 0, value, {}, context);
var result = decode_1.STRING_BROTLI(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('STRING_BROTLI: "" at offset 1', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = '';
var bytesWritten = encode_1.STRING_BROTLI(buffer, 1, value, {}, context);
var result = decode_1.STRING_BROTLI(buffer, 1, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('STRING_DICTIONARY_COMPRESSOR: "The quick brown fox jumps over the lazy dog"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'The quick brown fox jumps over the lazy dog';
var options = dictionaries_1.ENGLISH_DICTIONARY;
var bytesWritten = encode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, value, options, context);
var result = decode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, options);
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('STRING_DICTIONARY_COMPRESSOR: "foo bar baz" with [ bar ]', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'foo bar baz';
var options = {
index: ['bar'],
dictionary: {
bar: 0
}
};
var bytesWritten = encode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, value, options, context);
var result = decode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, options);
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('STRING_DICTIONARY_COMPRESSOR: "foo bar foo" with [ bar ]', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'foo bar foo';
var options = {
index: ['bar'],
dictionary: {
bar: 0
}
};
var bytesWritten = encode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, value, options, context);
var result = decode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, options);
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('STRING_DICTIONARY_COMPRESSOR: "bar foo foo" with [ bar ]', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'bar foo foo';
var options = {
index: ['bar'],
dictionary: {
bar: 0
}
};
var bytesWritten = encode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, value, options, context);
var result = decode_1.STRING_DICTIONARY_COMPRESSOR(buffer, 0, options);
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "https://google.com"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'https://google.com';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "https://google.com/"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'https://google.com/';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "https://google.com/foo"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'https://google.com/foo';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "https://google.com/foo?q=x"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'https://google.com/foo?q=x';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "https://google.com/foo#hello"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'https://google.com/foo#hello';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('URL_PROTOCOL_HOST_REST: should handle "git://github.com/gruntjs/grunt.git"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'git://github.com/gruntjs/grunt.git';
var bytesWritten = encode_1.URL_PROTOCOL_HOST_REST(buffer, 0, value, {}, context);
var result = decode_1.URL_PROTOCOL_HOST_REST(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, value);
test.end();
});
tap_1.default.test('RFC3339_DATE_INTEGER_TRIPLET: should handle "2014-10-01"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var bytesWritten = encode_1.RFC3339_DATE_INTEGER_TRIPLET(buffer, 0, '2014-10-01', {}, context);
test.is(bytesWritten, 4);
var result = decode_1.RFC3339_DATE_INTEGER_TRIPLET(buffer, 0, {});
test.is(result.bytes, bytesWritten);
test.is(result.value, '2014-10-01');
test.end();
});
tap_1.default.test('BOUNDED_PREFIX_LENGTH_8BIT_FIXED (ASCII)', function (test) {
var arbitrary = fc.nat(limits_1.UINT8_MAX - 1).chain(function (maximum) {
return fc.tuple(fc.nat(10), fc.nat(maximum), fc.constant(maximum), fc.string({
maxLength: maximum
}));
});
fc.assert(fc.property(arbitrary, function (_a) {
var _b = __read(_a, 4), offset = _b[0], minimum = _b[1], maximum = _b[2], value = _b[3];
fc.pre(Buffer.byteLength(value, 'utf8') >= minimum);
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(offset + limits_1.UINT8_MAX + 1));
var bytesWritten = encode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, offset, value, {
minimum: minimum, maximum: maximum
}, context);
var result = decode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, offset, {
minimum: minimum, maximum: maximum
});
return bytesWritten > 0 && result.bytes === bytesWritten && result.value === value;
}), {
verbose: false
});
test.end();
});
tap_1.default.test('ROOF_PREFIX_LENGTH_ENUM_VARINT (ASCII)', function (test) {
var arbitrary = fc.nat(1000).chain(function (maximum) {
return fc.tuple(fc.nat(10), fc.constant(maximum), fc.string({
maxLength: maximum
}));
});
fc.assert(fc.property(arbitrary, function (_a) {
var _b = __read(_a, 3), offset = _b[0], maximum = _b[1], value = _b[2];
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(2048));
var bytesWritten = encode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, offset, value, {
maximum: maximum
}, context);
var result = decode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, offset, {
maximum: maximum
});
return bytesWritten > 0 && result.bytes === bytesWritten && result.value === value;
}), {
verbose: false
});
test.end();
});
tap_1.default.test('FLOOR_PREFIX_LENGTH_ENUM_VARINT (ASCII)', function (test) {
var arbitrary = fc.nat(2000).chain(function (minimum) {
return fc.tuple(fc.nat(10), fc.constant(minimum), fc.string({
minLength: minimum, maxLength: 2000
}));
});
fc.assert(fc.property(arbitrary, function (_a) {
var _b = __read(_a, 3), offset = _b[0], minimum = _b[1], value = _b[2];
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(2048));
var bytesWritten = encode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, offset, value, {
minimum: minimum
}, context);
var result = decode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, offset, {
minimum: minimum
});
return bytesWritten > 0 && result.bytes === bytesWritten && result.value === value;
}), {
verbose: false
});
test.end();
});
tap_1.default.test('STRING_BROTLI (ASCII)', function (test) {
fc.assert(fc.property(fc.nat(10), fc.string({
maxLength: 1000
}), function (offset, value) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(2048));
var bytesWritten = encode_1.STRING_BROTLI(buffer, offset, value, {}, context);
var result = decode_1.STRING_BROTLI(buffer, offset, {});
return result.bytes === bytesWritten && result.value === value;
}), {
verbose: false
});
test.end();
});
tap_1.default.test('STRING_DICTIONARY_COMPRESSOR (ASCII)', function (test) {
fc.assert(fc.property(fc.nat(10), fc.string({
maxLength: 1000
}), function (offset, value) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(2048));
var options = {
index: [],
dictionary: {}
};
var bytesWritten = encode_1.STRING_DICTIONARY_COMPRESSOR(buffer, offset, value, options, context);
var result = decode_1.STRING_DICTIONARY_COMPRESSOR(buffer, offset, options);
return result.bytes === bytesWritten && result.value === value;
}), {
verbose: false
});
test.end();
});
tap_1.default.test('BOUNDED_PREFIX_LENGTH_8BIT_FIXED: shared string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(7));
var options = {
minimum: 0,
maximum: 4
};
var bytesWritten1 = encode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, 0, 'foo', options, context);
var bytesWritten2 = encode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, bytesWritten1, 'foo', options, context);
test.is(bytesWritten1, 4);
test.is(bytesWritten2, 3);
var decode1 = decode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, 0, options);
test.is(decode1.bytes, bytesWritten1);
test.is(decode1.value, 'foo');
var decode2 = decode_1.BOUNDED_PREFIX_LENGTH_8BIT_FIXED(buffer, decode1.bytes, options);
test.is(decode2.bytes, bytesWritten2);
test.is(decode2.value, 'foo');
test.end();
});
tap_1.default.test('ROOF_PREFIX_LENGTH_ENUM_VARINT: shared string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(7));
var options = {
maximum: 4
};
var bytesWritten1 = encode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, 0, 'foo', options, context);
var bytesWritten2 = encode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, bytesWritten1, 'foo', options, context);
test.is(bytesWritten1, 4);
test.is(bytesWritten2, 3);
var decode1 = decode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, 0, options);
test.is(decode1.bytes, bytesWritten1);
test.is(decode1.value, 'foo');
var decode2 = decode_1.ROOF_PREFIX_LENGTH_ENUM_VARINT(buffer, decode1.bytes, options);
test.is(decode2.bytes, bytesWritten2);
test.is(decode2.value, 'foo');
test.end();
});
tap_1.default.test('FLOOR_PREFIX_LENGTH_ENUM_VARINT: shared string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(7));
var options = {
minimum: 2
};
var bytesWritten1 = encode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, 0, 'foo', options, context);
var bytesWritten2 = encode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, bytesWritten1, 'foo', options, context);
test.is(bytesWritten1, 4);
test.is(bytesWritten2, 3);
var decode1 = decode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, 0, options);
test.is(decode1.bytes, bytesWritten1);
test.is(decode1.value, 'foo');
var decode2 = decode_1.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, decode1.bytes, options);
test.is(decode2.bytes, bytesWritten2);
test.is(decode2.value, 'foo');
test.end();
});
tap_1.default.test('UTF8_STRING_NO_LENGTH: should handle a string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(3));
var value = 'foo';
var options = {
size: 3
};
var bytesWritten = encode_1.UTF8_STRING_NO_LENGTH(buffer, 0, value, options, context);
var result = decode_1.UTF8_STRING_NO_LENGTH(buffer, 0, options);
test.is(bytesWritten, result.bytes);
test.is(result.value, value);
test.end();
});
tap_1.default.test('SHARED_STRING_POINTER_RELATIVE_OFFSET: should handle a shared string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'foo';
var options = {
size: 3
};
var bytesWritten1 = encode_1.UTF8_STRING_NO_LENGTH(buffer, 0, value, options, context);
test.is(context.strings.get('foo'), 0);
var bytesWritten2 = encode_1.SHARED_STRING_POINTER_RELATIVE_OFFSET(buffer, bytesWritten1, value, options, context);
var result = decode_1.SHARED_STRING_POINTER_RELATIVE_OFFSET(buffer, bytesWritten1, options);
test.is(result.value, value);
test.is(result.bytes, bytesWritten2);
test.end();
});
tap_1.default.test('STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH: should handle "foo"', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(4));
var value = 'foo';
var bytesWritten = encode_1.STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH(buffer, 0, value, {}, context);
var result = decode_1.STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH(buffer, 0, {});
test.is(result.value, value);
test.is(result.bytes, bytesWritten);
test.end();
});
tap_1.default.test('STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH: should handle a shared string', function (test) {
var context = encoder_1.getDefaultEncodingContext();
var buffer = new encoder_1.ResizableBuffer(Buffer.allocUnsafe(10));
var value = 'foo';
var bytesWritten1 = encode_1.STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH(buffer, 0, value, {}, context);
var bytesWritten2 = encode_1.STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH(buffer, bytesWritten1, value, {}, context);
var result = decode_1.STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH(buffer, bytesWritten1, {});
test.is(bytesWritten1, 4);
test.is(result.value, value);
test.is(result.bytes, bytesWritten2);
test.end();
});