Enable text-parser tests in @preserves/core; fix a couple of errors

This commit is contained in:
Tony Garnock-Jones 2023-10-29 18:12:12 +01:00
parent 5b8c07cb3f
commit 4869507b09
3 changed files with 36 additions and 11 deletions

View File

@ -172,11 +172,11 @@ export function hexDigit(n: number): string {
return '0123456789abcdef'[n];
}
export function unhexDigit(asciiCode: number) {
export function unhexDigit(asciiCode: number, errorClass: {new(msg: string): Error} = Error) {
if (asciiCode >= 48 && asciiCode <= 57) return asciiCode - 48;
if (asciiCode >= 97 && asciiCode <= 102) return asciiCode - 97 + 10;
if (asciiCode >= 65 && asciiCode <= 70) return asciiCode - 65 + 10;
throw new Error("Invalid hex digit: " + String.fromCharCode(asciiCode));
throw new errorClass("Invalid hex digit: " + String.fromCharCode(asciiCode));
}
export function underlying(b: Bytes | Uint8Array): Uint8Array {

View File

@ -4,7 +4,7 @@ import type { Value } from './values';
import { DecodeError, ShortPacket } from './codec';
import { Dictionary, Set } from './dictionary';
import { strip } from './strip';
import { Bytes, underlying, unhexDigit } from './bytes';
import { Bytes, unhexDigit } from './bytes';
import { Decoder, DecoderState, neverEmbeddedTypeDecode } from './decoder';
import { Record } from './record';
import { Annotated, newPosition, Position, updatePosition } from './annotated';
@ -106,16 +106,16 @@ export class ReaderState {
}
readHex2(): number {
const x1 = unhexDigit(this.nextcharcode());
const x2 = unhexDigit(this.nextcharcode());
const x1 = unhexDigit(this.nextcharcode(), DecodeError);
const x2 = unhexDigit(this.nextcharcode(), DecodeError);
return (x1 << 4) | x2;
}
readHex4(): number {
const x1 = unhexDigit(this.nextcharcode());
const x2 = unhexDigit(this.nextcharcode());
const x3 = unhexDigit(this.nextcharcode());
const x4 = unhexDigit(this.nextcharcode());
const x1 = unhexDigit(this.nextcharcode(), DecodeError);
const x2 = unhexDigit(this.nextcharcode(), DecodeError);
const x3 = unhexDigit(this.nextcharcode(), DecodeError);
const x4 = unhexDigit(this.nextcharcode(), DecodeError);
return (x1 << 12) | (x2 << 8) | (x3 << 4) | x4;
}
@ -346,7 +346,7 @@ export class Reader<T> {
switch (c) {
case 'f': return false;
case 't': return true;
case '{': return this.seq(new Set<T>(), (v, s) => s.add(v), '}');
case '{': return this.readSet();
case '"': return this.state.readLiteralBinary();
case 'x': switch (this.state.nextchar()) {
case '"': return this.state.readHexBinary();
@ -411,6 +411,16 @@ export class Reader<T> {
},
'}');
}
readSet(): Set<T> {
return this.seq(new Set<T>(),
(v, acc) => {
if (acc.has(v)) this.state.error(
`Duplicate value in set: ${stringify(v)}`, this.state.pos);
acc.add(v);
},
'}');
}
}
const BASE64: {[key: string]: number} = {};

View File

@ -19,6 +19,7 @@ import {
embed,
genericEmbeddedTypeDecode,
genericEmbeddedTypeEncode,
parse,
} from '../src/index';
const { Tag } = Constants;
import './test-utils';
@ -321,9 +322,23 @@ describe('common test suite', () => {
});
break;
case Symbol.for('ParseError'):
describe(tName, () => {
it('should fail with DecodeError', () => {
expect(() => parse(strip(t[0]) as string))
.toThrowFilter(e =>
DecodeError.isDecodeError(e) &&
!ShortPacket.isShortPacket(e));
});
});
break;
case Symbol.for('ParseEOF'):
case Symbol.for('ParseShort'):
/* Skipped for now, until we have an implementation of text syntax */
describe(tName, () => {
it('should fail with ShortPacket', () => {
expect(() => parse(strip(t[0]) as string))
.toThrowFilter(e => ShortPacket.isShortPacket(e));
});
});
break;
default:{
const e = new Error(preserves`Unsupported test kind ${t}`);