"use strict"; const chai = require('chai'); const expect = chai.expect; chai.use(require('chai-immutable')); const Immutable = require('immutable'); const Preserves = require('../src/index.js'); const { is, List, Set, Map, Decoder, Encoder, Bytes, Record, Single, Double } = Preserves; const fs = require('fs'); const util = require('util'); const shortForms = { 0: Symbol.for('discard'), 1: Symbol.for('capture'), 2: Symbol.for('observe'), }; const Discard = Record.makeConstructor('discard', []); const Capture = Record.makeConstructor('capture', ['pattern']); const Observe = Record.makeConstructor('observe', ['pattern']); describe('record constructors', () => { 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); }); }); describe('records', () => { 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; }); }); describe('hex samples', () => { const samples = fs.readFileSync(__dirname + '/samples.txt').toString().split(/\n/) .filter((h) => h) // filters out empty lines .map(Bytes.fromHex); function manyFalses(n) { return List().withMutations((l) => { for (let i = 0; i < n; i++) { l.push(false); } }); } // 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')), }, ]; 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; }); }); 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()); }); }); }); describe('parsing from subarray', () => { it('should maintain alignment of nextbytes', () => { const u = Uint8Array.of(57, 57, 57, 57, 83, 51, 51, 51); const bs = Bytes.from(u.subarray(4)); expect(new Decoder(bs).next()).to.equal("333"); }); });