author | Alan Dipert
<alan@dipert.org> 2019-08-22 07:49:56 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-08-22 07:49:56 UTC |
parent | c9d57590a7895c4625c16c9d8eb193595c14082f |
jacl-tests.js | +30 | -11 |
jacl.js | +10 | -0 |
diff --git a/jacl-tests.js b/jacl-tests.js index cc71552..aa94009 100644 --- a/jacl-tests.js +++ b/jacl-tests.js @@ -3,18 +3,22 @@ QUnit.config.testTimeout = 100; // milliseconds QUnit.module('Reader'); const makeRead1 = (rdr, it) => { - return async str => { - const done = it.async(); + return async (str, timeout = true) => { + const done = timeout ? it.async() : null; rdr.tokenizer.stream.writeEach(str); const obj = await rdr.read(); - done(); + if (done) done(); return obj; } }; +const freshRdr = (is) => { + const rdr = Reader.of(Tokenizer.of(new BufferedStream())); + return [rdr, makeRead1(rdr, is)]; +} + QUnit.test('Integers', async is => { - const rdr = Reader.of(Tokenizer.of(new BufferedStream())), - read1 = makeRead1(rdr, is); + var [rdr, read1] = freshRdr(is); is.strictEqual(await read1('123 '), 123, 'single integer'); is.strictEqual(await read1('+9912 '), 9912, 'integer with leading +'); @@ -24,8 +28,7 @@ QUnit.test('Integers', async is => { }); QUnit.test('Symbols', async is => { - const rdr = Reader.of(Tokenizer.of(new BufferedStream())), - read1 = makeRead1(rdr, is); + var [rdr, read1] = freshRdr(is); var sym; sym = await read1('defun '); @@ -56,8 +59,7 @@ QUnit.test('Symbols', async is => { }); QUnit.test('Conses', async is => { - const rdr = Reader.of(Tokenizer.of(new BufferedStream())), - read1 = makeRead1(rdr, is); + var [rdr, read1] = freshRdr(is); var cons; cons = await read1('()'); @@ -71,6 +73,23 @@ QUnit.test('Conses', async is => { is.strictEqual(cons.car, 1, 'car of dot cons'); is.strictEqual(cons.cdr, 2, 'cdr of dot cons'); - // TODO dot syntax parse error tests - + is.rejects( + read1('(1 . )', false), + /Nothing after . in list/, + 'nothing after dot' + ); + + [rdr, read1] = freshRdr(is); + is.rejects( + read1('( . t)', false), + /Nothing before . in list/, + 'nothing before dot' + ); + + [rdr, read1] = freshRdr(is); + is.rejects( + read1('(1 . 2 3)', false), + /More than one object after . in list/, + 'more than one object after dot' + ); }); diff --git a/jacl.js b/jacl.js index e321f27..d581afc 100644 --- a/jacl.js +++ b/jacl.js @@ -183,6 +183,10 @@ class BufferedStream { this.buf = []; this.resolveQueue = []; } + reset() { + this.buf = []; + this.resolveQueue = []; + } write(obj) { if (this.resolveQueue.length) { this.resolveQueue.shift()(obj); @@ -384,6 +388,9 @@ class Tokenizer { constructor(stream) { this.stream = stream; } + reset() { + this.stream.reset(); + } static of(stream) { return new Tokenizer(stream); } @@ -437,6 +444,9 @@ class Reader { constructor(tokenizer) { this.tokenizer = tokenizer; } + reset() { + this.tokenizer.reset(); + } static of(tokenizer) { return new Reader(tokenizer); }