redioactive
Version:
Reactive streams for chaining overlapping promises.
267 lines (266 loc) • 11 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const redio_1 = __importStar(require("../redio"));
const fs_1 = __importDefault(require("fs"));
const events_1 = require("events");
describe('Generate a stream by sync thunk', () => {
const gen = (x) => {
let count = 0;
return () => (count < x ? count++ : redio_1.end);
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([0]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([0, 1, 2, 3]);
});
});
describe('Generate a stream by async thunk', () => {
const gen = (x) => {
let count = 0;
return () => new Promise((resolve) => {
setTimeout(() => {
resolve(count < x ? count++ : redio_1.end);
}, 5);
});
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([0]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([0, 1, 2, 3]);
});
test('Value generate more than buffer size', async () => {
await expect((0, redio_1.default)(gen(20)).toArray()).resolves.toHaveLength(20);
});
});
describe('Generate a stream by sync callback generator', () => {
const gen = (x) => {
let count = 0;
return (push, next) => {
push(count < x ? count++ : redio_1.end);
next();
};
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([0]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([0, 1, 2, 3]);
});
});
describe('Generate a stream by async callback generator', () => {
const gen = (x) => {
let count = 0;
return (push, next) => {
push(count < x ? count++ : redio_1.end);
setTimeout(next, 5);
};
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([0]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([0, 1, 2, 3]);
});
});
describe('Generate a stream of arrays by sync thunk', () => {
const gen = (x) => {
let count = 0;
return () => (count < x ? [0, count++] : redio_1.end);
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([[0, 0]]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([
[0, 0],
[0, 1],
[0, 2],
[0, 3]
]);
});
});
describe.skip('Generate a stream of arrays by sync callback generator', () => {
const gen = (x) => {
let count = 0;
return (push, next) => {
push(count < x ? [0, count++] : redio_1.end);
next();
};
};
test('Value generate zero values', async () => {
await expect((0, redio_1.default)(gen(0)).toArray()).resolves.toEqual([]);
});
test('Value generate one value', async () => {
await expect((0, redio_1.default)(gen(1)).toArray()).resolves.toEqual([[0, 0]]);
});
test('Value generate four values', async () => {
await expect((0, redio_1.default)(gen(4)).toArray()).resolves.toEqual([
[0, 0],
[0, 1],
[0, 2],
[0, 3]
]);
});
});
describe('Generate a stream from an array', () => {
test('Array with no values', async () => {
await expect((0, redio_1.default)([]).toArray()).resolves.toHaveLength(0);
});
test('Array with one value', async () => {
await expect((0, redio_1.default)([42]).toArray()).resolves.toHaveLength(1);
});
test('Array with 5 values', async () => {
await expect((0, redio_1.default)([10, 20, 30, 40, 50]).toArray()).resolves.toHaveLength(5);
});
test('Array with 20 values - greater than buffer', async () => {
await expect((0, redio_1.default)([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]).toArray()).resolves.toHaveLength(20);
});
test('Generate with sparse array', async () => {
const a = new Array(5);
a[0] = 0;
a[2] = 2;
a[4] = 4;
await expect((0, redio_1.default)(a).toArray()).resolves.toEqual([0, 2, 4]);
});
test('Generate with nil values', async () => {
const a = [0, redio_1.nil, 2, redio_1.nil, 4];
await expect((0, redio_1.default)(a).toArray()).resolves.toEqual([0, 2, 4]);
});
});
describe('Generator a stream from an iterable', () => {
test('Set with no values', async () => {
await expect((0, redio_1.default)(new Set()).toArray()).resolves.toHaveLength(0);
});
test('Set with one value', async () => {
await expect((0, redio_1.default)(new Set([1])).toArray()).resolves.toEqual([1]);
});
test('Set with 4 values', async () => {
await expect((0, redio_1.default)(new Set([1, 2, 3, 4])).toArray()).resolves.toHaveLength(4);
});
test('Map with 4 values', async () => {
await expect((0, redio_1.default)(new Map([
[1, 'one'],
[2, 'two']
])).toArray()).resolves.toHaveLength(2);
});
});
describe('Generator from readable', () => {
test('Read this file', async () => {
await expect((0, redio_1.default)(fs_1.default.createReadStream('src/__tests__/generator.spec.ts')).toArray()).resolves.toHaveLength(1);
});
test('Read this file in smaller chunks', async () => {
const stats = fs_1.default.statSync('src/__tests__/generator.spec.ts');
const expectedChunks = (stats.size / 256) | 0;
await expect((0, redio_1.default)(fs_1.default.createReadStream('src/__tests__/generator.spec.ts'), { chunkSize: 256 }).toArray()).resolves.toHaveLength(expectedChunks);
});
test('Read this file as a string', async () => {
await expect((0, redio_1.default)(fs_1.default.createReadStream('src/__tests__/generator.spec.ts'), { encoding: 'utf8' }).toArray()).resolves.toEqual(expect.arrayContaining([expect.stringMatching('imp(o)rt')]));
});
});
class EventMaker extends events_1.EventEmitter {
constructor() {
super();
}
makeOne(name, value) {
this.emit(name, value);
}
makeOneIn(name, value, wait) {
setTimeout(() => {
this.emit(name, value);
}, wait);
}
}
describe('Generator from events', () => {
const emitter = new EventMaker();
emitter.on('change', (x) => console.log('debuggy', x));
test('Catch an event', async () => {
const stream = (0, redio_1.default)(emitter, 'change').toArray();
emitter.makeOneIn('change', 'fred', 1);
emitter.makeOneIn('change', 'ginger', 2);
emitter.makeOneIn('end', '', 3);
await expect(stream).resolves.toEqual(['fred', 'ginger']);
});
});
describe('Generate, then consume later', () => {
test('Make more than we can eat', async () => {
const str = (0, redio_1.default)([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const endStr = str.each((_x) => {
return new Promise((resolve) => {
setTimeout(() => {
// console.log(x)
resolve();
}, 100);
});
});
await expect(endStr.toPromise()).resolves.toBeTruthy();
});
});
describe('Delayed generator start test', () => {
const wait = async (t) => new Promise((resolve) => {
setTimeout(resolve, t);
});
const makeGen = () => {
let counter = 0;
return (0, redio_1.default)(async () => {
return counter < 6 ? counter++ : redio_1.end;
}, { bufferSizeMax: 3, debug: false });
};
test('Start now', async () => {
const gen = makeGen();
await expect(gen.toArray()).resolves.toEqual([0, 1, 2, 3, 4, 5]);
});
test('Start then - direct spout', async () => {
const gen = makeGen();
await wait(20);
await expect(gen.toArray()).resolves.toEqual([0, 1, 2, 3, 4, 5]);
});
test('Start then - via valc', async () => {
const gen = makeGen();
await wait(20);
await expect(gen.map((x) => x).toArray()).resolves.toEqual([0, 1, 2, 3, 4, 5]);
});
});