UNPKG

asclasit

Version:

ASync CLasses + ASync ITerators

255 lines (217 loc) 8.8 kB
const $ = require('../func'); const AsIt = require('./base'); async function* asIt(iter) { yield* iter; } async function asItArray(iter) { const res = []; for await (const item of iter) res.push(item); return res; } test('new AsIt: bad argument', async () => { expect(await asItArray(new AsIt())).toEqual([]); expect(() => new AsIt({})).toThrow('not iterable'); }); test('new AsIt: wrap to iterator', () => { const wrapped = new AsIt(asIt([])); expect(typeof wrapped[AsIt.wrapped].next).toBe('function'); }); test('AsIt.getGen: is generator', () => { const gen = AsIt.getGen(async function* () {}); expect(typeof gen).toBe('function'); expect(typeof gen().next).toBe('function'); }); test('AsIt.getGen: get bound generator', () => { const gen = AsIt.getGen([]); expect(typeof gen).toBe('function'); expect(typeof gen().next).toBe('function'); }); test('AsIt.getGen: get bound async generator', () => { const gen = AsIt.getGen(asIt([])); expect(typeof gen).toBe('function'); expect(typeof gen().next).toBe('function'); }); test('AsIt.getGen: not iterator object', () => { const gen = AsIt.getGen('123'); expect(gen).toBe(null); }); test('AsIt.getGen: not an iterator', () => { const gen = AsIt.getGen({}); expect(gen).toBe(null); }); test('AsIt.getIter: from generator', () => { const iter = AsIt.getIter(async function* () {}); expect(typeof iter.next).toBe('function'); }); test('AsIt.getIter: bound iterator', () => { const iter = AsIt.getIter([]); expect(typeof iter.next).toBe('function'); }); test('AsIt.getIter: not iterator object', () => { const iter = AsIt.getIter('345'); expect(iter).toBe(null); }); test('AsIt.getIter: not an iterator', () => { const iter = AsIt.getIter({}); expect(iter).toBe(null); }); test('AsIt.chainWrap: wrap generator to chain method', async () => { const gen = async function* (iter) { for await (const x of iter) yield x + 1; }; const chain = AsIt.chainWrap(gen); expect(typeof chain).toBe('function'); const wrapped = new AsIt(asIt([1, 2, 16])); expect(chain.call(wrapped)).toBe(wrapped); expect(await asItArray(wrapped[AsIt.wrapped])).toEqual([2, 3, 17]); }); test('AsIt.make_: define make generator', async () => { AsIt.make_(async function* myMake(a, b) { for (let x = a; x > 0; x -= b) yield x; }); const wrapped = AsIt.myMake(10, 2); expect(wrapped instanceof AsIt).toBe(true); expect(await asItArray(wrapped)).toEqual([10, 8, 6, 4, 2]); }); test('AsIt.chain_: define chain generator', async () => { AsIt.chain_(async function* myChainGen(iter, less) { for await (const x of iter) yield x - less; }); const wrapped = new AsIt([8, 4, 1, 9][Symbol.iterator]()); wrapped.myChainGen(1).myChainGen(2); expect(await asItArray(wrapped)).toEqual([5, 1, -2, 6]); }); test('AsIt.value_: define value function', async () => { AsIt.value_(async function mySquareSum(iter) { let sum = 0; for await (const x of iter) sum += x * x; return sum; }); const wrapped = new AsIt([2, 1, 0, -1][Symbol.iterator]()); const sum = await wrapped.myChainGen(1).mySquareSum(); expect(sum).toEqual(6); }); test('AsIt_[@@iterator]: iterate wrapped', async () => { const src = [1, 2, 5]; const wrapped = new AsIt(src[Symbol.iterator]()); expect(await asItArray(wrapped)).toEqual(src); }); test('AsIt_.next: take values', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.next(true)).toEqual({done: false, value: 6}); expect(await wrapped.next(true)).toEqual({done: false, value: 4}); expect(await asItArray(wrapped)).toEqual([3, 2, 1, 0]); }); test('AsIt_.next: take values from generic iterator', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const iter = myGen(); expect(await AsIt.next(iter, true)).toEqual({done: false, value: 6}); expect(await AsIt.next(iter, true)).toEqual({done: false, value: 4}); expect(await asItArray(iter)).toEqual([3, 2, 1, 0]); }); test('AsIt_.return: break in the middle', async () => { const myGen = async function* () { try { let c = 100; while (c--) yield c; } finally { yield 'end'; } }; const wrapped = new AsIt(myGen()); expect(await wrapped.next()).toEqual({done: false, value: 99}); expect(await wrapped.next()).toEqual({done: false, value: 98}); expect(await wrapped.return()).toEqual({done: false, value: 'end'}); expect(await wrapped.next()).toEqual({done: true}); }); test('AsIt_.throw: break with exception', async () => { const myGen = function* () { let c = 10; try { while (c--) yield c; } catch (err) { yield `broken with ${err.message}`; } finally { yield 'end'; } } const wrapped = new AsIt(myGen()); expect(await wrapped.next()).toEqual({done: false, value: 9}); expect(await wrapped.next()).toEqual({done: false, value: 8}); expect(await wrapped.throw(new Error('enough'))).toEqual({done: false, value: 'broken with enough'}); expect(await asItArray(wrapped)).toEqual(['end']); }); test('AsIt_.read: read value', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.read(true)).toEqual(6); expect(wrapped.cur).toEqual(1); expect(await wrapped.read(true)).toEqual(4); expect(wrapped.cur).toEqual(2); expect(await asItArray(wrapped)).toEqual([3, 2, 1, 0]); }); test('AsIt_.read: read eof', async () => { const empty = new AsIt(); expect(await empty.read()).toBe($.eof); }); test('AsIt_.ffwd: fast forward values', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.ffwd(2, true)).toEqual({done: false, value: 4}); expect(wrapped.cur).toEqual(2); expect(await asItArray(wrapped)).toEqual([3, 2, 1, 0]); }); test('AsIt_.ffwd: fast forward beyond', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.ffwd(10, true)).toEqual({done: true}); expect(wrapped.cur).toEqual(null); expect(await asItArray(wrapped)).toEqual([]); }); test('AsIt_.ffwd: fast forward generic iter beyond', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const iter = myGen(); expect(await AsIt.ffwd(iter, 10, true)).toEqual({done: true}); expect(await asItArray(iter)).toEqual([]); }); test('AsIt_.affwd: async fast forward values', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.affwd(2, true)).toEqual({done: false, value: 4}); expect(wrapped.cur).toEqual(2); expect(await asItArray(wrapped)).toEqual([3, 2, 1, 0]); }); test('AsIt_.affwd: async fast forward beyond', async () => { const myGen = async function* () { let c = 7; while (c-- > 0) if (yield c) c--; }; const wrapped = new AsIt(myGen()); expect(await wrapped.affwd(10, true)).toEqual({done: true}); expect(wrapped.cur).toEqual(null); expect(await asItArray(wrapped)).toEqual([]); }); test('AsIt_.partial: sequential iteration', async () => { const iter = new AsIt([1, 2, 3, 4]); const part = iter.partial(); let n = 2; for await (const item of part) if (!--n) break; expect(await asItArray(iter)).toEqual([3, 4]); }); test('AsIt_.partial: parallel iteration', async () => { const iter = new AsIt(async function*() {for (let i = 0; i < 4; i++) {await $.delayMsec(50); yield i;}} ()); const part = AsIt.partial(iter); let r1 = [], r2 = []; await Promise.all([ (async () => { for await (const item of part) r1.push(item); }) (), (async () => { await $.delayMsec(25); for await (const item of iter) r2.push(item); }) (), ]); expect(r1).toEqual([0, 2]); expect(r2).toEqual([1, 3]); }); test('AsIt_.init: initial set var', async () => { const iter = new AsIt([1, 2, 3, 4]); iter.init('a', 2).init('b', 3); expect(iter.a).toBe(2); expect(iter.b).toBe(3); }); test('AsIt_.get, .set: get/set wrapped iterator', async () => { const iter = new AsIt([1, 2]); expect(iter.get() !== iter).toBe(true); expect(await asItArray(iter.get())).toEqual([1, 2]); try { iter.set({}); expect(true).toBe(false); } catch(err) { expect(err.message).toBe('not iterable'); } iter.set(function*() { yield 3; }); expect(await asItArray(iter)).toEqual([3]); }); test('AsIt_.get, chain: void iterator', async () => { const iter = new AsIt(); expect(await asItArray(iter.get())).toEqual([]); expect(await asItArray(iter.load(1))).toEqual([]); });