gristlabs_grist-core/test/common/marshal.js
Paul Fitzpatrick bcbf57d590 (core) bump mocha version to allow parallel tests; move more tests to core
Summary:
This uses a newer version of mocha in grist-core so that tests can be run in parallel. That allows more tests to be moved without slowing things down overall. Tests moved are venerable browser tests; only the ones that "just work" or worked without too much trouble to are moved, in order to keep the diff from growing too large. Will wrestle with more in follow up.

Parallelism is at the file level, rather than the individual test.

The newer version of mocha isn't needed for grist-saas repo; tests are parallelized in our internal CI by other means. I've chosen to allocate files to workers in a cruder way than our internal CI, based on initial characters rather than an automated process. The automated process would need some reworking to be compatible with mocha running in parallel mode.

Test Plan: this diff was tested first on grist-core, then ported to grist-saas so saas repo history will correctly track history of moved files.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3927
2023-06-27 02:55:34 -04:00

168 lines
7.8 KiB
JavaScript

var assert = require('chai').assert;
var marshal = require('app/common/marshal');
var MemBuffer = require('app/common/MemBuffer');
describe("marshal", function() {
function binStringToArray(binaryString) {
var a = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) {
a[i] = binaryString.charCodeAt(i);
}
return a;
}
function arrayToBinString(array) {
return String.fromCharCode.apply(String, array);
}
var samples = [
[null, 'N'],
[1, 'i\x01\x00\x00\x00'],
[1000000, 'i@B\x0f\x00'],
[-123456, 'i\xc0\x1d\xfe\xff'],
[1.23, 'g\xae\x47\xe1\x7a\x14\xae\xf3\x3f', 2],
[-625e-4, 'g\x00\x00\x00\x00\x00\x00\xb0\xbf', 2],
[12.34, 'f\x0512.34', 0],
[6.02e23, 'f\x086.02e+23', 0],
[true, 'T'],
[false, 'F'],
[MemBuffer.stringToArray('Hello world'), 's\x0b\x00\x00\x00Hello world'],
['Résumé', 's\x08\x00\x00\x00R\xc3\xa9sum\xc3\xa9'],
[[1, 2, 3],
'[\x03\x00\x00\x00i\x01\x00\x00\x00i\x02\x00\x00\x00i\x03\x00\x00\x00'],
[{'This': 4, 'is': 0, 'a': MemBuffer.stringToArray('test')},
'{s\x04\x00\x00\x00Thisi\x04\x00\x00\x00s\x01\x00\x00\x00as\x04\x00\x00\x00tests\x02\x00\x00\x00isi\x00\x00\x00\x000'],
];
describe('basic data structures', function() {
it("should serialize correctly", function() {
var m0 = new marshal.Marshaller({ stringToBuffer: true, version: 0 });
var m2 = new marshal.Marshaller({ stringToBuffer: true, version: 2 });
for (var i = 0; i < samples.length; i++) {
var value = samples[i][0];
var expected = binStringToArray(samples[i][1]);
var version = samples[i].length === 3 ? samples[i][2] : 0;
var currentMarshaller = version >= 2 ? m2 : m0;
currentMarshaller.marshal(value);
var marshalled = currentMarshaller.dump();
assert.deepEqual(marshalled, expected,
"Wrong serialization of " + JSON.stringify(value) +
"\n actual: " + escape(arrayToBinString(marshalled)) + "\n" +
"\n expected: " + escape(arrayToBinString(expected)));
}
});
it("should deserialize correctly", function() {
var m = new marshal.Unmarshaller();
var values = [];
m.on('value', function(val) { values.push(val); });
for (var i = 0; i < samples.length; i++) {
values.length = 0;
var expected = samples[i][0];
m.push(binStringToArray(samples[i][1]));
assert.strictEqual(values.length, 1);
var value = values[0];
if (typeof expected === 'string') {
// This tests marshals JS strings to Python strings, but unmarshalls to Uint8Arrays. So
// when the source is a string, we need to tweak the returned value for comparison.
value = MemBuffer.arrayToString(value);
}
assert.deepEqual(value, expected);
}
});
it("should support stringToBuffer and bufferToString", function() {
var mY = new marshal.Marshaller({ stringToBuffer: true });
var mN = new marshal.Marshaller({ stringToBuffer: false });
var uY = new marshal.Unmarshaller({ bufferToString: true });
var uN = new marshal.Unmarshaller({ bufferToString: false });
var helloBuf = MemBuffer.stringToArray("hello");
function passThrough(m, u, value) {
var ret = null;
u.on('value', function(v) { ret = v; });
m.marshal(value);
u.push(m.dump());
return ret;
}
// No conversion, no change.
assert.deepEqual(passThrough(mN, uN, "hello"), "hello");
assert.deepEqual(passThrough(mN, uN, helloBuf), helloBuf);
// If convert to strings on the way back, then see all strings.
assert.deepEqual(passThrough(mN, uY, "hello"), "hello");
assert.deepEqual(passThrough(mN, uY, helloBuf), "hello");
// If convert to buffers on the way forward, and no conversion back, then see all buffers.
assert.deepEqual(passThrough(mY, uN, "hello"), helloBuf);
assert.deepEqual(passThrough(mY, uN, helloBuf), helloBuf);
// If convert to buffers on the way forward, and to strings back, then see all strings.
assert.deepEqual(passThrough(mY, uY, "hello"), "hello");
assert.deepEqual(passThrough(mY, uY, helloBuf), "hello");
});
});
function mkbuf(arg) { return new Uint8Array(arg); }
function dumps(codeStr, value) {
var m = new marshal.Marshaller();
m.marshal(marshal.wrap(codeStr, value));
return m.dump();
}
describe('int64', function() {
it("should serialize 32-bit values correctly", function() {
assert.deepEqual(dumps('INT64', 0x7FFFFFFF), mkbuf([73, 255, 255, 255, 127, 0, 0, 0, 0]));
assert.deepEqual(dumps('INT64', -0x80000000), mkbuf([73, 0, 0, 0, 128, 255, 255, 255, 255]));
// TODO: larger values fail now, but of course it's better to fix, and change this test.
assert.throws(function() { dumps('INT64', 0x7FFFFFFF+1); }, /int64/);
assert.throws(function() { dumps('INT64', -0x80000000-1); }, /int64/);
});
it("should deserialize 32-bit values correctly", function() {
assert.strictEqual(marshal.loads([73, 255, 255, 255, 127, 0, 0, 0, 0]), 0x7FFFFFFF);
assert.strictEqual(marshal.loads([73, 0, 0, 0, 128, 255, 255, 255, 255]), -0x80000000);
// Can be verified in Python with: marshal.loads("".join(chr(r) for r in [73, 255, ...]))
assert.strictEqual(marshal.loads([73, 255, 255, 255, 127, 255, 255, 255, 255]), -0x80000001);
assert.strictEqual(marshal.loads([73, 0, 0, 0, 128, 0, 0, 0, 0]), 0x80000000);
// Be sure to test with low and high 32-bit words being positive or negative. Note that
// integers that are too large to be safely represented are currently returned as strings.
assert.strictEqual(marshal.loads([73, 1, 2, 3, 190, 4, 5, 6, 200]), '-4033530898337824255');
assert.strictEqual(marshal.loads([73, 1, 2, 3, 190, 4, 5, 6, 20]), '1442846248544698881');
assert.strictEqual(marshal.loads([73, 1, 2, 3, 90, 4, 5, 6, 200]), '-4033530900015545855');
assert.strictEqual(marshal.loads([73, 1, 2, 3, 90, 4, 5, 6, 20]), '1442846246866977281');
});
});
describe('interned strings', function() {
it("should parse interned strings correctly", function() {
var testData = '{t\x03\x00\x00\x00aaat\x03\x00\x00\x00bbbR\x01\x00\x00\x00R\x00\x00\x00\x000';
assert.deepEqual(marshal.loads(binStringToArray(testData)),
{ 'aaa': MemBuffer.stringToArray('bbb'),
'bbb': MemBuffer.stringToArray('aaa')
});
});
});
describe('longs', function() {
// This is generated as [991**i for i in xrange(10)] + [-678**i for i in xrange(10)].
// Note how overly large values currently get stringified.
const sampleData = [1, 991, 982081, 973242271, 964483090561, 955802742745951,
'947200518061237441', '938675713398686304031', '930227631978098127294721',
'921855583290295244149068511',
-1, -678, -459684, -311665752, -211309379856, -143267759542368, '-97135540969725504',
'-65857896777473891712', '-44651654015127298580736', '-30273821422256308437739008'];
const serialized = "[\x14\x00\x00\x00i\x01\x00\x00\x00i\xdf\x03\x00\x00iA\xfc\x0e\x00i\x9f\x7f\x02:I\x81\x08\xac\x8f\xe0\x00\x00\x00I_\xeb\xf4*Le\x03\x00I\xc1$\x1bJ\xda!%\rl\x05\x00\x00\x00\x1fG&>\x130\xf0\x15.\x03l\x06\x00\x00\x00\x01Q@\x17n\x1b\x84m\xbbO\x18\x00l\x06\x00\x00\x00\xdf\x123\x03\x86/\xd0r4(Q_i\xff\xff\xff\xffiZ\xfd\xff\xffi\\\xfc\xf8\xffi\xa8[l\xedI\xf0\xbe\xfa\xcc\xce\xff\xff\xffI\xa0\xaf\x15\xe0\xb2}\xff\xffI\xc0!oy\xbd\xe7\xa6\xfel\xfb\xff\xff\xff\x80\x1dYG\xc1\x00\xb2\x0f9\x00l\xfa\xff\xff\xff\x00!Rv\x9f\x00p\x11I\x17\x01\x00l\xfa\xff\xff\xff\x00f\xda]\x8c'\xa3.\xb2+!\x03";
it("should deserialize arbitrarily long integers correctly", function() {
assert.deepEqual(marshal.loads(binStringToArray(serialized)), sampleData);
});
});
});