New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

preserves

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

preserves - npm Package Compare versions

Comparing version 0.0.16 to 0.1.0

src/annotations.js

14

package.json
{
"name": "preserves",
"version": "0.0.16",
"version": "0.1.0",
"description": "Experimental data serialization format",
"homepage": "https://gitlab.com/tonyg/preserves",
"license": "MIT",
"homepage": "https://gitlab.com/preserves/preserves",
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
},
"repository": "gitlab:tonyg/preserves",
"repository": "gitlab:preserves/preserves",
"scripts": {

@@ -18,10 +18,8 @@ "test": "mocha",

"devDependencies": {
"chai": "^4.2.0",
"chai-immutable": "^2.0.0-rc.2",
"mocha": "^5.2.0",
"nyc": "^13.1.0"
"nyc": "^14.1.1"
},
"dependencies": {
"immutable": "^3.8.2"
"immutable": "^4.0.0-rc.12"
}
}

@@ -10,3 +10,4 @@ "use strict";

const Values = require('./values.js');
const { List, Map, Set, Bytes, Record, Single, Double } = Values;
const Annotations = require('./annotations.js');
const { fromJS, List, Map, Set, Bytes, Record, Single, Double } = Values;

@@ -31,3 +32,4 @@ const { PreserveOn } = require('./symbols.js');

this.index = 0;
this.shortForms = options.shortForms || {};
this.placeholders = fromJS(options.placeholders || {});
this.includeAnnotations = options.includeAnnotations || false;
}

@@ -80,5 +82,4 @@

peekend(arg) {
const [a,i,r] = this.nextop();
const result = (a === 0) && (i === 3) && (r === arg);
peekend() {
const result = this.nextbyte() === 4;
if (!result) this.index--;

@@ -88,5 +89,5 @@ return result;

binarystream(arg, minor) {
binarystream(minor) {
const result = [];
while (!this.peekend(arg)) {
while (!this.peekend()) {
const chunk = this.next();

@@ -106,6 +107,6 @@ if (ArrayBuffer.isView(chunk)) {

valuestream(arg, minor, decoder) {
valuestream(minor) {
const result = [];
while (!this.peekend(arg)) result.push(this.next());
return decoder(minor, result);
while (!this.peekend()) result.push(this.next());
return this.decodecompound(minor, result);
}

@@ -131,19 +132,11 @@

decoderecord(minor, vs) {
if (minor === 3) {
if (vs.length === 0) throw new DecodeError("Too few elements in encoded record");
return new Record(vs[0], vs.slice(1));
} else {
const label = this.shortForms[minor];
if (label === void 0) throw new DecodeError("Use of unconfigured short form " + minor);
return new Record(label, vs);
}
}
decodecollection(minor, vs) {
decodecompound(minor, vs) {
switch (minor) {
case 0: return List(vs);
case 1: return Set(vs);
case 2: return this.mapFromArray(vs);
case 3: throw new DecodeError("Invalid collection type");
case 0: {
if (vs.length === 0) throw new DecodeError("Too few elements in encoded record");
return new Record(vs[0], vs.slice(1));
}
case 1: return List(vs);
case 2: return Set(vs);
case 3: return this.mapFromArray(vs);
}

@@ -160,2 +153,13 @@ }

wrap(v) {
return this.includeAnnotations ? new Annotations.Annotated(v) : v;
}
unshiftAnnotation(a, v) {
if (this.includeAnnotations) {
v.annotations.unshift(a);
}
return v;
}
next() {

@@ -168,9 +172,24 @@ const [major, minor, arg] = this.nextop();

switch (arg) {
case 0: return false;
case 1: return true;
case 2: return Single(this.nextbytes(4).getFloat32(0, false));
case 3: return Double(this.nextbytes(8).getFloat64(0, false));
case 0: return this.wrap(false);
case 1: return this.wrap(true);
case 2: return this.wrap(Single(this.nextbytes(4).getFloat32(0, false)));
case 3: return this.wrap(Double(this.nextbytes(8).getFloat64(0, false)));
case 4: throw new DecodeError("Unexpected end-of-stream marker");
case 5: {
const a = this.next();
const v = this.next();
return this.unshiftAnnotation(a, v);
}
default: throw new DecodeError("Illegal format A lead byte");
}
case 1:
return (arg > 12) ? arg - 16 : arg;
case 1: {
const n = this.wirelength(arg);
const v = this.placeholders.get(n, void 0);
if (typeof v === 'undefined') {
const e = new DecodeError("Invalid Preserves placeholder");
e.irritant = n;
throw e;
}
return this.wrap(v);
}
case 2: {

@@ -180,17 +199,16 @@ const t = arg >> 2;

switch (t) {
case 0: throw new DecodeError("Invalid format C start byte");
case 1: return this.binarystream(arg, n);
case 2: return this.valuestream(arg, n, this.decoderecord.bind(this));
case 3: return this.valuestream(arg, n, this.decodecollection.bind(this));
case 1: return this.wrap(this.binarystream(n));
case 2: return this.wrap(this.valuestream(n));
default: throw new DecodeError("Invalid format C start byte");
}
}
case 3:
throw new DecodeError("Invalid format C end byte");
return this.wrap((arg > 12) ? arg - 16 : arg);
}
case 1:
return this.decodebinary(minor, Bytes.from(this.nextbytes(this.wirelength(arg))));
return this.wrap(this.decodebinary(minor, Bytes.from(this.nextbytes(this.wirelength(arg)))));
case 2:
return this.decoderecord(minor, this.nextvalues(this.wirelength(arg)));
return this.wrap(this.decodecompound(minor, this.nextvalues(this.wirelength(arg))));
case 3:
return this.decodecollection(minor, this.nextvalues(this.wirelength(arg)));
throw new DecodeError("Invalid lead byte (major 3)");
}

@@ -213,2 +231,12 @@ }

function decode(bs, options) {
return new Decoder(bs, options).next();
}
function decodeWithAnnotations(bs, options) {
options = options || {};
options.includeAnnotations = true;
return decode(bs, options);
}
class Encoder {

@@ -220,3 +248,3 @@ constructor(options) {

this.index = 0;
this.shortForms = options.shortForms || {};
this.placeholders = fromJS(options.placeholders || {});
}

@@ -289,3 +317,3 @@

encodecollection(minor, items) {
this.header(3, minor, items.size);
this.header(2, minor, items.size);
for (const item of items) { this.push(item); }

@@ -298,7 +326,11 @@ }

for (const item of items) { this.push(item); }
this.header(0, 3, tn);
this.header(0, 0, 4);
}
push(v) {
if (typeof v === 'object' && v !== null && typeof v[PreserveOn] === 'function') {
const placeholder = this.placeholders.get(v, void 0);
if (typeof placeholder !== 'undefined') {
this.header(0, 1, placeholder);
}
else if (typeof v === 'object' && v !== null && typeof v[PreserveOn] === 'function') {
v[PreserveOn](this);

@@ -311,3 +343,3 @@ }

if (v >= -3 && v <= 12) {
this.leadbyte(0, 1, v >= 0 ? v : v + 16);
this.leadbyte(0, 3, v >= 0 ? v : v + 16);
} else {

@@ -340,9 +372,9 @@ this.encodeint(v);

else if (List.isList(v)) {
this.encodecollection(0, v);
this.encodecollection(1, v);
}
else if (Set.isSet(v)) {
this.encodecollection(1, v);
this.encodecollection(2, v);
}
else if (Map.isMap(v)) {
this.encodecollection(2, List().withMutations((l) => {
this.encodecollection(3, List().withMutations((l) => {
v.forEach((val, key) => { l.push(key).push(val); });

@@ -352,3 +384,3 @@ }));

else if (typeof v === 'object' && v !== null && typeof v[Symbol.iterator] === 'function') {
this.encodestream(3, 0, v);
this.encodestream(2, 1, v);
}

@@ -362,2 +394,6 @@ else {

function encode(v, options) {
return new Encoder(options).push(v).contents();
}
Object.assign(module.exports, {

@@ -368,3 +404,6 @@ DecodeError,

Decoder,
decode,
decodeWithAnnotations,
Encoder,
encode,
});

@@ -11,1 +11,2 @@ "use strict";

Object.assign(module.exports, require('./values.js'));
Object.assign(module.exports, require('./annotations.js'));

@@ -13,3 +13,3 @@ "use strict";

const Immutable = require('immutable');
const { List, isList, Map, Set, is } = Immutable;
const { List, Map, Set, is, hash } = Immutable;

@@ -345,12 +345,4 @@ const { PreserveOn, AsPreserve } = require('./symbols.js');

Record.prototype[PreserveOn] = function (encoder) {
if (is(encoder.shortForms[0], this.label)) {
encoder.header(2, 0, this.fields.size);
} else if (is(encoder.shortForms[1], this.label)) {
encoder.header(2, 1, this.fields.size);
} else if (is(encoder.shortForms[2], this.label)) {
encoder.header(2, 2, this.fields.size);
} else {
encoder.header(2, 3, this.fields.size + 1);
encoder.push(this.label);
}
encoder.header(2, 0, this.fields.size + 1);
encoder.push(this.label);
for (const field of this.fields) { encoder.push(field); }

@@ -394,4 +386,4 @@ };

if (!ctor.isClassOf(r)) {
throw new Error("Record: attempt to retrieve field "+label+"."+name+
" from non-"+label+": "+(r && r.toString()));
throw new Error("Record: attempt to retrieve field "+label.toString()+"."+name+
" from non-"+label.toString()+": "+(r && r.toString()));
}

@@ -427,3 +419,3 @@ return r.get(i);

fromJS,
List, Map, Set, is,
List, Map, Set, is, hash,
Float, Single, Double,

@@ -430,0 +422,0 @@ Bytes,

"use strict";
const chai = require('chai');
const expect = chai.expect;
chai.use(require('chai-immutable'));
const assert = require('assert');
const Immutable = require('immutable');

@@ -15,16 +12,17 @@

it('should yield entries', () => {
expect(fromJS(Array.from(bs.entries()))).to.equal(fromJS([[0,10],[1,20],[2,30],[3,40]]));
assert(is(fromJS(Array.from(bs.entries())),
fromJS([[0,10],[1,20],[2,30],[3,40]])));
});
it('should implement every', () => {
expect(bs.every((b) => !(b & 1))).to.be.true;
expect(bs.every((b) => b !== 50)).to.be.true;
expect(bs.every((b) => b !== 20)).to.be.false;
assert(bs.every((b) => !(b & 1)));
assert(bs.every((b) => b !== 50));
assert(!(bs.every((b) => b !== 20)));
});
it('should implement find', () => {
expect(bs.find((b) => b > 20)).to.equal(30);
expect(bs.find((b) => b > 50)).to.be.undefined;
assert.strictEqual(bs.find((b) => b > 20), 30);
assert.strictEqual(bs.find((b) => b > 50), void 0);
});
it('should implement findIndex', () => {
expect(bs.findIndex((b) => b > 20)).to.equal(2);
expect(bs.findIndex((b) => b > 50)).to.equal(-1);
assert.strictEqual(bs.findIndex((b) => b > 20), 2);
assert.strictEqual(bs.findIndex((b) => b > 50), -1);
});

@@ -34,55 +32,55 @@ it('should implement forEach', () => {

bs.forEach((b) => vs.push(b));
expect(fromJS(vs)).to.equal(fromJS([10, 20, 30, 40]));
assert(is(fromJS(vs), fromJS([10, 20, 30, 40])));
});
it('should implement includes', () => {
expect(bs.includes(20)).to.be.true;
expect(bs.includes(50)).to.be.false;
assert(bs.includes(20));
assert(!bs.includes(50));
});
it('should implement indexOf', () => {
expect(bs.indexOf(20)).to.equal(1);
expect(bs.indexOf(50)).to.equal(-1);
assert.strictEqual(bs.indexOf(20), 1);
assert.strictEqual(bs.indexOf(50), -1);
});
it('should implement join', () => expect(bs.join('-')).to.equal('10-20-30-40'));
it('should implement join', () => assert.strictEqual(bs.join('-'), '10-20-30-40'));
it('should implement keys', () => {
expect(fromJS(Array.from(bs.keys()))).to.equal(fromJS([0,1,2,3]));
assert(is(fromJS(Array.from(bs.keys())), fromJS([0,1,2,3])));
});
it('should implement values', () => {
expect(fromJS(Array.from(bs.values()))).to.equal(fromJS([10,20,30,40]));
assert(is(fromJS(Array.from(bs.values())), fromJS([10,20,30,40])));
});
it('should implement filter', () => {
expect(is(bs.filter((b) => b !== 30), Bytes.of(10,20,40))).to.be.true;
assert(is(bs.filter((b) => b !== 30), Bytes.of(10,20,40)));
});
it('should implement slice', () => {
const vs = bs.slice(2);
expect(Object.is(vs._view.buffer, bs._view.buffer)).to.be.false;
expect(vs._view.buffer.byteLength).to.equal(2);
expect(vs.get(0)).to.equal(30);
expect(vs.get(1)).to.equal(40);
expect(vs.size).to.equal(2);
assert(!Object.is(vs._view.buffer, bs._view.buffer));
assert.strictEqual(vs._view.buffer.byteLength, 2);
assert.strictEqual(vs.get(0), 30);
assert.strictEqual(vs.get(1), 40);
assert.strictEqual(vs.size, 2);
});
it('should implement subarray', () => {
const vs = bs.subarray(2);
expect(Object.is(vs._view.buffer, bs._view.buffer)).to.be.true;
expect(vs._view.buffer.byteLength).to.equal(4);
expect(vs.get(0)).to.equal(30);
expect(vs.get(1)).to.equal(40);
expect(vs.size).to.equal(2);
assert(Object.is(vs._view.buffer, bs._view.buffer));
assert.strictEqual(vs._view.buffer.byteLength, 4);
assert.strictEqual(vs.get(0), 30);
assert.strictEqual(vs.get(1), 40);
assert.strictEqual(vs.size, 2);
});
it('should implement reverse', () => {
const vs = bs.reverse();
expect(Object.is(vs._view.buffer, bs._view.buffer)).to.be.false;
expect(bs.get(0)).to.equal(10);
expect(bs.get(3)).to.equal(40);
expect(vs.get(0)).to.equal(40);
expect(vs.get(3)).to.equal(10);
assert(!Object.is(vs._view.buffer, bs._view.buffer));
assert.strictEqual(bs.get(0), 10);
assert.strictEqual(bs.get(3), 40);
assert.strictEqual(vs.get(0), 40);
assert.strictEqual(vs.get(3), 10);
});
it('should implement sort', () => {
const vs = bs.reverse().sort();
expect(Object.is(vs._view.buffer, bs._view.buffer)).to.be.false;
expect(bs.get(0)).to.equal(10);
expect(bs.get(3)).to.equal(40);
expect(vs.get(0)).to.equal(10);
expect(vs.get(3)).to.equal(40);
assert(!Object.is(vs._view.buffer, bs._view.buffer));
assert.strictEqual(bs.get(0), 10);
assert.strictEqual(bs.get(3), 40);
assert.strictEqual(vs.get(0), 10);
assert.strictEqual(vs.get(3), 40);
});
});
});
"use strict";
const chai = require('chai');
const expect = chai.expect;
chai.use(require('chai-immutable'));
const assert = require('assert');
const Immutable = require('immutable');
const Preserves = require('../src/index.js');
const { is, List, Set, Map, Decoder, Encoder, Bytes, Record, Single, Double } = Preserves;
const {
is, List, Set, Map,
Decoder, Encoder, decode, decodeWithAnnotations, encode,
DecodeError, EncodeError, ShortPacket,
Bytes, Record, Single, Double,
annotate,
stripAnnotations,
PreserveOn,
} = Preserves;

@@ -15,8 +20,2 @@ const fs = require('fs');

const shortForms = {
0: Symbol.for('discard'),
1: Symbol.for('capture'),
2: Symbol.for('observe'),
};
const Discard = Record.makeConstructor('discard', []);

@@ -28,8 +27,8 @@ const Capture = Record.makeConstructor('capture', ['pattern']);

it('should have constructorInfo', () => {
expect(Discard.constructorInfo.label).to.equal(Symbol.for('discard'));
expect(Capture.constructorInfo.label).to.equal(Symbol.for('capture'));
expect(Observe.constructorInfo.label).to.equal(Symbol.for('observe'));
expect(Discard.constructorInfo.arity).to.equal(0);
expect(Capture.constructorInfo.arity).to.equal(1);
expect(Observe.constructorInfo.arity).to.equal(1);
assert.strictEqual(Discard.constructorInfo.label, Symbol.for('discard'));
assert.strictEqual(Capture.constructorInfo.label, Symbol.for('capture'));
assert.strictEqual(Observe.constructorInfo.label, Symbol.for('observe'));
assert.strictEqual(Discard.constructorInfo.arity, 0);
assert.strictEqual(Capture.constructorInfo.arity, 1);
assert.strictEqual(Observe.constructorInfo.arity, 1);
});

@@ -42,10 +41,10 @@ })

it('instance comparison should ignore pointer and fieldname differences', () => {
expect(is(C1(9,9), C2(9,9))).to.be.true;
expect(is(C1(9,9), C2(9,8))).to.be.false;
assert(is(C1(9,9), C2(9,9)));
assert(!is(C1(9,9), C2(9,8)));
});
it('comparison based on pointer equality should not work', () => {
expect(C1.constructorInfo === C2.constructorInfo).to.be.false;
assert.notStrictEqual(C1.constructorInfo, C2.constructorInfo);
});
it('comparison based on .equals should work', () => {
expect(is(C1.constructorInfo, C2.constructorInfo)).to.be.true;
assert(is(C1.constructorInfo, C2.constructorInfo));
});

@@ -56,107 +55,182 @@ });

it('should have correct getConstructorInfo', () => {
expect(Discard().getConstructorInfo().equals(Discard.constructorInfo)).to.be.true;
expect(Capture(Discard()).getConstructorInfo().equals(Capture.constructorInfo)).to.be.true;
expect(Observe(Capture(Discard())).getConstructorInfo().equals(Observe.constructorInfo))
.to.be.true;
expect(is(Observe(Capture(Discard())).getConstructorInfo(), Observe.constructorInfo))
.to.be.true;
assert(Discard().getConstructorInfo().equals(Discard.constructorInfo));
assert(Capture(Discard()).getConstructorInfo().equals(Capture.constructorInfo));
assert(Observe(Capture(Discard())).getConstructorInfo().equals(Observe.constructorInfo));
assert(is(Observe(Capture(Discard())).getConstructorInfo(), Observe.constructorInfo));
});
});
describe('hex samples', () => {
const samples = fs.readFileSync(__dirname + '/samples.txt').toString().split(/\n/)
.filter((h) => h) // filters out empty lines
.map(Bytes.fromHex);
class SimpleStream {
constructor(t, n, items) {
this.t = t;
this.n = n;
this.items = items;
}
function manyFalses(n) {
return List().withMutations((l) => {
for (let i = 0; i < n; i++) { l.push(false); }
});
[PreserveOn](e) {
e.encodestream(this.t, this.n, this.items);
}
}
// As new samples are added to samples.txt, we will need to update this list:
const samplesExpected = [
{ expected: new Single(1), },
{ expected: new Double(1), },
{ expected: new Double(-1.202e+300), },
{ expected: 0, },
{ expected: 1, },
{ expected: 12, },
{ expected: -3, },
{ expected: -2, },
{ expected: -1, },
{ expected: "hello", encodesTo: '5568656c6c6f', },
{ expected: "hello", encodesTo: '5568656c6c6f', },
{ expected: Bytes.from("hello"), encodesTo: '6568656c6c6f', },
{ expected: Symbol.for("hello"), encodesTo: '7568656c6c6f', },
{ expected: Immutable.Seq([1, 2, 3, 4]), },
{ expected: Preserves.fromJS(["abc", "def"]), encodesTo: 'c25361626353646566' },
{ expected: Preserves.fromJS([["a", 1], ["b", 2], ["c", 3]]),
encodesTo: 'c3c2516111c2516212c2516313', },
{ expected: 13, },
{ expected: 127, },
{ expected: -128, },
{ expected: -127, },
{ expected: -4, },
{ expected: 128, },
{ expected: 255, },
{ expected: 256, },
{ expected: 32767, },
{ expected: -257, },
{ expected: -256, },
{ expected: -255, },
{ expected: -254, },
{ expected: -129, },
{ expected: 32768, },
{ expected: 65535, },
{ expected: 65536, },
{ expected: 131072, },
{ expected: "hello", },
{ expected: Bytes.from("hello"), },
{ expected: Symbol.for("hello"), },
{ expected: Capture(Discard()), },
{ expected: Observe(new Record(Symbol.for('speak'), [Discard(), Capture(Discard())])), },
{ expected:
new Record([Symbol.for('titled'), Symbol.for('person'), 2, Symbol.for('thing'), 1],
[101, "Blackwell", new Record(Symbol.for('date'), [1821, 2, 3]), "Dr"]), },
{ expected: List([1, 2, 3, 4]), },
{ expected: List([-2, -1, 0, 1]), },
{ expected: Preserves.fromJS(["hello",
Symbol.for('there'),
Bytes.from('world'),
[],
Set(),
true,
false]), },
{ expected: manyFalses(14), },
{ expected: manyFalses(15), },
{ expected: manyFalses(100), },
{ expected: manyFalses(200), },
{ expected:
Map()
.set(Symbol.for('a'), 1)
.set('b', true)
.set(Preserves.fromJS([1, 2, 3]), Bytes.from('c'))
.set(Map().set(Symbol.for('first-name'), 'Elizabeth'),
Map().set(Symbol.for('surname'), 'Blackwell')), },
];
class StringStream extends SimpleStream { constructor(items) { super(1, 1, items); }}
class BytesStream extends SimpleStream { constructor(items) { super(1, 2, items); }}
class SymbolStream extends SimpleStream { constructor(items) { super(1, 3, items); }}
class RecordStream extends SimpleStream { constructor(items) { super(2, 0, items); }}
// Not needed -- an ordinary array will do!
// class SequenceStream extends SimpleStream { constructor(items) { super(2, 1, items); }}
class SetStream extends SimpleStream { constructor(items) { super(2, 2, items); }}
class DictionaryStream extends SimpleStream { constructor(items) { super(2, 3, items); }}
samples.forEach((s, sampleIndex) => {
it('[' + sampleIndex + '] ' + s.toHex() + ' should decode OK', () => {
const actual = new Decoder(s, { shortForms }).next();
const expected = samplesExpected[sampleIndex].expected;
expect(is(actual, expected),
'[' + sampleIndex + '] actual ' + util.inspect(actual) +
', expected ' + util.inspect(expected))
.to.be.true;
describe('common test suite', () => {
const samples_bin = fs.readFileSync(__dirname + '/../../../tests/samples.bin');
const samples = decodeWithAnnotations(samples_bin);
const TestCases = Record.makeConstructor('TestCases', ['mapping', 'cases']);
const ExpectedPlaceholderMapping =
Record.makeConstructor('ExpectedPlaceholderMapping', ['table']);
const expectedPlaceholderMapping = TestCases._mapping(samples.peel()).strip();
const placeholders_decode = ExpectedPlaceholderMapping._table(expectedPlaceholderMapping);
const placeholders_encode = placeholders_decode.mapEntries((e) => [e[1],e[0]]);
function DS(bs) {
return decode(bs, {placeholders: placeholders_decode});
}
function D(bs) {
return decodeWithAnnotations(bs, {placeholders: placeholders_decode});
}
function E(v) {
return encode(v, {placeholders: placeholders_encode});
}
const expectedValues = {
annotation1: { forward: annotate(9, "abc"),
back: 9 },
annotation2: { forward: annotate(List([List(), annotate(List(), "x")]), "abc", "def"),
back: List([List(), List()]) },
annotation3: { forward: annotate(5,
annotate(2, 1),
annotate(4, 3)),
back: 5 },
annotation5: { forward: annotate(new Record(Symbol.for('R'),
[annotate(Symbol.for('f'),
Symbol.for('af'))]),
Symbol.for('ar')),
back: new Record(Symbol.for('R'), [Symbol.for('f')]) },
annotation6: { forward: new Record(annotate(Symbol.for('R'),
Symbol.for('ar')),
[annotate(Symbol.for('f'),
Symbol.for('af'))]),
back: new Record(Symbol.for('R'), [Symbol.for('f')]) },
annotation7: { forward: annotate(List(), Symbol.for('a'), Symbol.for('b'), Symbol.for('c')),
back: List() },
bytes1: { forward: new BytesStream([Bytes('he'), Bytes('ll'), Bytes('o')]),
back: Bytes('hello') },
list1: { forward: [1, 2, 3, 4],
back: List([1, 2, 3, 4]) },
list2: {
forward: [ new StringStream([Bytes('abc')]),
new StringStream([Bytes('def')]), ],
back: List(["abc", "def"])
},
list3: {
forward: [List(["a", 1]), List(["b", 2]), List(["c", 3])],
back: List([List(["a", 1]), List(["b", 2]), List(["c", 3])])
},
record2: { value: Observe(new Record(Symbol.for("speak"), [
Discard(),
Capture(Discard())
])) },
string0a: { forward: new StringStream([]), back: '' },
string1: { forward: new StringStream([Bytes('he'), Bytes('ll'), Bytes('o')]),
back: 'hello' },
string2: { forward: new StringStream([Bytes('he'), Bytes('llo')]),
back: 'hello' },
symbol1: { forward: new SymbolStream([Bytes('he'), Bytes('ll'), Bytes('o')]),
back: Symbol.for('hello') },
};
function runTestCase(variety, tName, binaryForm, annotatedTextForm) {
describe(tName, () => {
const textForm = annotatedTextForm.strip();
const {forward, back} = (function () {
const entry = expectedValues[tName] || {value: textForm};
if ('value' in entry) {
return {forward: entry.value, back: entry.value};
} else if ('forward' in entry && 'back' in entry) {
return entry;
} else {
throw new Error('Invalid expectedValues entry for ' + tName);
}
})();
it('should match the expected value', () => assert(is(textForm, back)));
it('should round-trip', () => assert(is(DS(E(textForm)), back)));
it('should go forward', () => assert(is(DS(E(forward)), back)));
it('should go back', () => assert(is(DS(binaryForm), back)));
it('should go back with annotations',
() => assert(is(D(E(annotatedTextForm)), annotatedTextForm)));
if (variety !== 'nondeterministic') {
it('should encode correctly',
() => assert(is(E(forward), binaryForm),
E(forward) + ' ' + binaryForm));
}
if (variety !== 'nondeterministic' && variety !== 'streaming') {
it('should encode correctly with annotations',
() => assert(is(E(annotatedTextForm), binaryForm),
E(annotatedTextForm) + ' ' + binaryForm));
}
});
});
}
samples.forEach((s, sampleIndex) => {
it('[' + sampleIndex + '] ' + s.toHex() + ' should encode OK', () => {
const entry = samplesExpected[sampleIndex];
const actualHex = entry.encodesTo || s.toHex();
const expected = new Encoder({ shortForms }).push(entry.expected).contents();
expect(actualHex).to.equal(expected.toHex());
});
const tests = TestCases._cases(samples.peel()).peel();
tests.forEach((t0, tName0) => {
const tName = Symbol.keyFor(tName0.strip());
const t = t0.peel();
switch (t.label) {
case Symbol.for('Test'):
runTestCase('normal', tName, t.get(0).strip(), t.get(1));
break;
case Symbol.for('StreamingTest'):
runTestCase('streaming', tName, t.get(0).strip(), t.get(1));
break;
case Symbol.for('NondeterministicTest'):
runTestCase('nondeterministic', tName, t.get(0).strip(), t.get(1));
break;
case Symbol.for('DecodeError'):
describe(tName, () => {
it('should fail with DecodeError', () => {
try {
D(t.get(0).strip());
assert.fail("but it didn't");
} catch (e) {
assert(e instanceof DecodeError);
assert(!(e instanceof ShortPacket));
}
});
});
break;
case Symbol.for('DecodeShort'):
describe(tName, () => {
it('should fail with ShortPacket', () => {
try {
D(t.get(0).strip());
assert.fail("but it didn't");
} catch (e) {
assert(e instanceof ShortPacket);
}
});
});
break;
case Symbol.for('ParseError'):
case Symbol.for('ParseShort'):
/* Skipped for now, until we have an implementation of text syntax */
break;
default:{
const e = new Error('Unsupported test kind');
e.irritant = t;
e.testKind = t.label;
console.error(e);
throw e;
}
}
});

@@ -169,4 +243,4 @@ });

const bs = Bytes.from(u.subarray(4));
expect(new Decoder(bs).next()).to.equal("333");
assert.strictEqual(new Decoder(bs).next(), "333");
});
});

@@ -7,6 +7,3 @@ "use strict";

const chai = require('chai');
const expect = chai.expect;
chai.use(require('chai-immutable'));
const assert = require('assert');
const Immutable = require('immutable');

@@ -23,21 +20,21 @@

it('should reuse RecordConstructorInfo (1)', () => {
expect(C1.constructorInfo instanceof V1.RecordConstructorInfo).to.be.true;
assert(C1.constructorInfo instanceof V1.RecordConstructorInfo);
});
it('should reuse RecordConstructorInfo (2)', () => {
expect(C1.constructorInfo instanceof V2.RecordConstructorInfo).to.be.true;
assert(C1.constructorInfo instanceof V2.RecordConstructorInfo);
});
it('should identify RecordConstructorInfo', () => {
expect(Object.is(V1.RecordConstructorInfo, V2.RecordConstructorInfo)).to.be.true;
assert(Object.is(V1.RecordConstructorInfo, V2.RecordConstructorInfo));
});
it('should produce identical module instances', () => { expect(V1 === V2).to.be.true; });
it('should produce identical module instances', () => { assert.strictEqual(V1, V2); });
it('should produce distinct constructor instances', () => { expect(C1 === C2).to.be.false; });
it('should produce distinct constructor instances', () => { assert.notStrictEqual(C1, C2); });
it('should produce distinct constructor info', () => {
expect(Object.is(C1.constructorInfo, C2.constructorInfo)).to.be.false;
assert(!Object.is(C1.constructorInfo, C2.constructorInfo));
});
it('should produce compatible constructor info', () => {
expect(Immutable.is(C1.constructorInfo, C2.constructorInfo)).to.be.true;
assert(Immutable.is(C1.constructorInfo, C2.constructorInfo));
});
it('should produce compatible record instances', () => {
expect(Immutable.is(C1(1,2), C2(1,2))).to.be.true;
assert(Immutable.is(C1(1,2), C2(1,2)));
});

@@ -51,4 +48,4 @@ });

const I2 = require('../src/index.js');
expect(Object.is(I1, I2)).to.be.true;
assert(Object.is(I1, I2));
});
});
"use strict";
const chai = require('chai');
const expect = chai.expect;
chai.use(require('chai-immutable'));
const assert = require('assert');
const Immutable = require('immutable');

@@ -13,3 +10,3 @@

it('should print reasonably', () => {
expect(Single(123.45).toString()).to.equal("123.45");
assert.strictEqual(Single(123.45).toString(), "123.45");
});

@@ -20,4 +17,4 @@ });

it('should print reasonably', () => {
expect(Double(123.45).toString()).to.equal("123.45");
assert.strictEqual(Double(123.45).toString(), "123.45");
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc