Prechádzať zdrojové kódy

New test harness: tape-six.

Eugene Lazutkin 3 rokov pred
rodič
commit
3788f41dbb

+ 21 - 44
package-lock.json

@@ -8,61 +8,38 @@
       "name": "stream-chain",
       "version": "3.0.0",
       "license": "BSD-3-Clause",
+      "dependencies": {
+        "tape-six": "^0.9.1"
+      },
       "devDependencies": {
-        "heya-unit": "^0.3.0"
+        "tape6": "file:../tape6"
       }
     },
-    "node_modules/heya-ice": {
-      "version": "0.1.11",
-      "resolved": "https://registry.npmjs.org/heya-ice/-/heya-ice-0.1.11.tgz",
-      "integrity": "sha1-XW2lnGC1nHAjqDRw+26XcddwWEk=",
+    "../tape6": {
       "dev": true
     },
-    "node_modules/heya-unify": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/heya-unify/-/heya-unify-0.2.7.tgz",
-      "integrity": "sha512-d/4NacYl52tt4ofbP7gz+YmbjLrI2jkrRxSSd1a26yXfRS1vQxmZkZ6L+O1xUsgDSwx4HCDWR5U+ZFykdoHVig==",
-      "dev": true,
-      "dependencies": {
-        "heya-ice": "^0.1.11"
+    "node_modules/tape-six": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/tape-six/-/tape-six-0.9.1.tgz",
+      "integrity": "sha512-G0bK1UL+wBeXeZPb5v2KLTqthjo1P2DKvJ+ONnXRg1Z1jU/6WCtuhGdZMDIFe8tXtKFislDQWY5C0t6oNffavg==",
+      "bin": {
+        "tape6": "bin/tape6.js",
+        "tape6-server": "bin/tape6-server.js"
       }
     },
-    "node_modules/heya-unit": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/heya-unit/-/heya-unit-0.3.0.tgz",
-      "integrity": "sha1-eXR4IIyBnUxbf+NWrEwbhO67ubc=",
-      "dev": true,
-      "dependencies": {
-        "heya-ice": ">=0.1",
-        "heya-unify": ">=0.2"
-      }
+    "node_modules/tape6": {
+      "resolved": "../tape6",
+      "link": true
     }
   },
   "dependencies": {
-    "heya-ice": {
-      "version": "0.1.11",
-      "resolved": "https://registry.npmjs.org/heya-ice/-/heya-ice-0.1.11.tgz",
-      "integrity": "sha1-XW2lnGC1nHAjqDRw+26XcddwWEk=",
-      "dev": true
-    },
-    "heya-unify": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/heya-unify/-/heya-unify-0.2.7.tgz",
-      "integrity": "sha512-d/4NacYl52tt4ofbP7gz+YmbjLrI2jkrRxSSd1a26yXfRS1vQxmZkZ6L+O1xUsgDSwx4HCDWR5U+ZFykdoHVig==",
-      "dev": true,
-      "requires": {
-        "heya-ice": "^0.1.11"
-      }
+    "tape-six": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/tape-six/-/tape-six-0.9.1.tgz",
+      "integrity": "sha512-G0bK1UL+wBeXeZPb5v2KLTqthjo1P2DKvJ+ONnXRg1Z1jU/6WCtuhGdZMDIFe8tXtKFislDQWY5C0t6oNffavg=="
     },
-    "heya-unit": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/heya-unit/-/heya-unit-0.3.0.tgz",
-      "integrity": "sha1-eXR4IIyBnUxbf+NWrEwbhO67ubc=",
-      "dev": true,
-      "requires": {
-        "heya-ice": ">=0.1",
-        "heya-unify": ">=0.2"
-      }
+    "tape6": {
+      "version": "file:../tape6"
     }
   }
 }

+ 14 - 3
package.json

@@ -25,7 +25,7 @@
   },
   "scripts": {
     "debug": "node --inspect-brk tests/tests.js",
-    "test": "node tests/tests.js"
+    "test": "tape6 --flags DO"
   },
   "repository": {
     "type": "git",
@@ -42,7 +42,18 @@
   },
   "homepage": "https://github.com/uhop/stream-chain#readme",
   "devDependencies": {
-    "heya-unit": "^0.3.0"
+    "tape6": "file:../tape6"
   },
-  "files": ["src/*.js", "src/utils/*.js"]
+  "files": [
+    "src/*.js",
+    "src/utils/*.js"
+  ],
+  "tape6": {
+    "tests": [
+      "/tests/test_*.mjs"
+    ]
+  },
+  "dependencies": {
+    "tape-six": "^0.9.1"
+  }
 }

+ 4 - 6
tests/helpers.js

@@ -1,17 +1,17 @@
 'use strict';
 
-const {Writable} = require('stream');
+import {Writable} from 'stream';
 
-const streamToArray = array =>
+export const streamToArray = array =>
   new Writable({
     objectMode: true,
-    write(chunk, encoding, callback) {
+    write(chunk, _, callback) {
       array.push(chunk);
       callback(null);
     }
   });
 
-const delay = (fn, ms = 20) => async (...args) =>
+export const delay = (fn, ms = 20) => async (...args) =>
   new Promise((resolve, reject) => {
     setTimeout(() => {
       try {
@@ -21,5 +21,3 @@ const delay = (fn, ms = 20) => async (...args) =>
       }
     }, ms);
   });
-
-module.exports = {streamToArray, delay};

+ 0 - 90
tests/test_demo.js

@@ -1,90 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {Transform} = require('stream');
-
-const chain = require('../src/index');
-const fromIterable = require('../src/utils/fromIterable');
-
-const getTotalFromDatabaseByKey = async x =>
-new Promise(resolve => {
-  setTimeout(() => {
-    resolve(Math.min(x % 10, 3));
-  }, 20);
-});
-
-unit.add(module, [
-  function test_demo(t) {
-    const async = t.startAsync('test_demo');
-
-    const c = chain([
-        // transforms a value
-        x => x * x,
-        // returns several values
-        x => chain.many([x - 1, x, x + 1]),
-        // waits for an asynchronous operation
-        async x => await getTotalFromDatabaseByKey(x),
-        // returns multiple values with a generator
-        function* (x) {
-          for (let i = x; i > 0; --i) {
-            yield i;
-          }
-          return 0;
-        },
-        // filters out even values
-        x => (x % 2 ? x : null),
-        // uses an arbitrary transform stream
-        new Transform({
-          objectMode: true,
-          transform(x, _, callback) {
-            callback(null, x + 1);
-          }
-        })
-      ]),
-      output = [];
-    c.on('data', data => output.push(data));
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [2, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2])'));
-      async.done();
-    });
-
-    fromIterable([1, 2, 3]).pipe(c);
-  },
-  function test_demoNoGrouping(t) {
-    const async = t.startAsync('test_demoNoGrouping');
-
-    const c = chain([
-        // transforms a value
-        x => x * x,
-        // returns several values
-        x => chain.many([x - 1, x, x + 1]),
-        // waits for an asynchronous operation
-        async x => await getTotalFromDatabaseByKey(x),
-        // returns multiple values with a generator
-        function* (x) {
-          for (let i = x; i > 0; --i) {
-            yield i;
-          }
-          return 0;
-        },
-        // filters out even values
-        x => (x % 2 ? x : null),
-        // uses an arbitrary transform stream
-        new Transform({
-          objectMode: true,
-          transform(x, _, callback) {
-            callback(null, x + 1);
-          }
-        })
-      ], {noGrouping: true}),
-      output = [];
-    c.on('data', data => output.push(data));
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [2, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2])'));
-      async.done();
-    });
-
-    fromIterable([1, 2, 3]).pipe(c);
-  }
-]);

+ 87 - 0
tests/test_demo.mjs

@@ -0,0 +1,87 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {Transform} from 'stream';
+import chain from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+const getTotalFromDatabaseByKey = async x =>
+  new Promise(resolve => {
+    setTimeout(() => {
+      resolve(Math.min(x % 10, 3));
+    }, 20);
+  });
+
+test.asPromise('demo: default', (t, resolve) => {
+  const c = chain([
+      // transforms a value
+      x => x * x,
+      // returns several values
+      x => chain.many([x - 1, x, x + 1]),
+      // waits for an asynchronous operation
+      async x => await getTotalFromDatabaseByKey(x),
+      // returns multiple values with a generator
+      function* (x) {
+        for (let i = x; i > 0; --i) {
+          yield i;
+        }
+        return 0;
+      },
+      // filters out even values
+      x => (x % 2 ? x : null),
+      // uses an arbitrary transform stream
+      new Transform({
+        objectMode: true,
+        transform(x, _, callback) {
+          callback(null, x + 1);
+        }
+      })
+    ]),
+    output = [];
+  c.on('data', data => output.push(data));
+  c.on('end', () => {
+    t.deepEqual(output, [2, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]);
+    resolve();
+  });
+
+  fromIterable([1, 2, 3]).pipe(c);
+});
+
+test.asPromise('demo: no grouping', (t, resolve) => {
+  const c = chain(
+      [
+        // transforms a value
+        x => x * x,
+        // returns several values
+        x => chain.many([x - 1, x, x + 1]),
+        // waits for an asynchronous operation
+        async x => await getTotalFromDatabaseByKey(x),
+        // returns multiple values with a generator
+        function* (x) {
+          for (let i = x; i > 0; --i) {
+            yield i;
+          }
+          return 0;
+        },
+        // filters out even values
+        x => (x % 2 ? x : null),
+        // uses an arbitrary transform stream
+        new Transform({
+          objectMode: true,
+          transform(x, _, callback) {
+            callback(null, x + 1);
+          }
+        })
+      ],
+      {noGrouping: true}
+    ),
+    output = [];
+  c.on('data', data => output.push(data));
+  c.on('end', () => {
+    t.deepEqual(output, [2, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]);
+    resolve();
+  });
+
+  fromIterable([1, 2, 3]).pipe(c);
+});

+ 0 - 24
tests/test_errors.js

@@ -1,24 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const chain = require('../src/index');
-
-unit.add(module, [
-  function test_errorsNoStreams(t) {
-    try {
-      const c = chain([]);
-      t.test(false); // shouldn't be here
-    } catch (e) {
-      eval(t.TEST('e instanceof Error'));
-    }
-  },
-  function test_errorsWrongStreams(t) {
-    try {
-      const c = chain([1]);
-      t.test(false); // shouldn't be here
-    } catch (e) {
-      eval(t.TEST('e instanceof Error'));
-    }
-  }
-]);

+ 19 - 0
tests/test_errors.mjs

@@ -0,0 +1,19 @@
+'use strict';
+
+import test from 'tape-six';
+
+import chain from '../src/index.js';
+
+test('errors: no streams', t => {
+  t.throws(() => {
+    chain([]);
+    t.fail("shouldn't be here");
+  });
+});
+
+test('errors: wrong stream', t => {
+  t.throws(() => {
+    chain([1]);
+    t.fail("shouldn't be here");
+  });
+});

+ 0 - 140
tests/test_fold.js

@@ -1,140 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-
-const fromIterable = require('../src/utils/fromIterable');
-const fold = require('../src/utils/fold');
-const scan = require('../src/utils/scan');
-const reduce = require('../src/utils/reduce');
-const reduceStream = require('../src/utils/reduceStream');
-
-const {asStream} = chain;
-
-unit.add(module, [
-  function test_fold(t) {
-    const async = t.startAsync('test_fold');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fold((acc, x) => acc + x, 0),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [6])'));
-      async.done();
-    });
-  },
-  function test_foldAsync(t) {
-    const async = t.startAsync('test_foldAsync');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fold(
-          delay((acc, x) => acc + x),
-          0
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [6])'));
-      async.done();
-    });
-  },
-  function test_foldScan(t) {
-    const async = t.startAsync('test_foldScan');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        scan((acc, x) => acc + x, 0),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 3, 6])'));
-      async.done();
-    });
-  },
-  function test_foldScanAsync(t) {
-    const async = t.startAsync('test_foldScanAsync');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        scan(
-          delay((acc, x) => acc + x),
-          0
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 3, 6])'));
-      async.done();
-    });
-  },
-  function test_foldReduce(t) {
-    const async = t.startAsync('test_foldReduce');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fold((acc, x) => acc + x, 0),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [6])'));
-      async.done();
-    });
-  },
-  function test_foldReduceAsync(t) {
-    const async = t.startAsync('test_foldReduceAsync');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        reduce(
-          delay((acc, x) => acc + x),
-          0
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [6])'));
-      async.done();
-    });
-  },
-  function test_foldReduceStream(t) {
-    const async = t.startAsync('test_foldReduceStream');
-
-    const r = reduceStream((acc, x) => acc + x, 0);
-
-    fromIterable([1, 2, 3]).pipe(r);
-
-    r.on('finish', () => {
-      eval(t.TEST('t.unify(r.accumulator, 6)'));
-      async.done();
-    });
-  },
-  function test_foldReduceStreamAsync(t) {
-    const async = t.startAsync('test_foldReduceStreamAsync');
-
-    const r = reduceStream({reducer: delay((acc, x) => acc + x), initial: 0});
-
-    fromIterable([1, 2, 3]).pipe(r);
-
-    r.on('finish', () => {
-      eval(t.TEST('t.unify(r.accumulator, 6)'));
-      async.done();
-    });
-  }
-]);

+ 115 - 0
tests/test_fold.mjs

@@ -0,0 +1,115 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+import fold from '../src/utils/fold.js';
+import scan from '../src/utils/scan.js';
+import reduce from '../src/utils/reduce.js';
+import reduceStream from '../src/utils/reduceStream.js';
+
+test.asPromise('fold: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), fold((acc, x) => acc + x, 0), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fold(
+        delay((acc, x) => acc + x),
+        0
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: scan', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), scan((acc, x) => acc + x, 0), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 3, 6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: scan async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      scan(
+        delay((acc, x) => acc + x),
+        0
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 3, 6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: reduce', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), fold((acc, x) => acc + x, 0), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: reduce async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      reduce(
+        delay((acc, x) => acc + x),
+        0
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [6]);
+    resolve();
+  });
+});
+
+test.asPromise('fold: reduce stream', (t, resolve) => {
+  const r = reduceStream((acc, x) => acc + x, 0);
+
+  fromIterable([1, 2, 3]).pipe(r);
+
+  r.on('finish', () => {
+    t.deepEqual(r.accumulator, 6);
+    resolve();
+  });
+});
+
+test.asPromise('fold: reduce stream async', (t, resolve) => {
+  const r = reduceStream({reducer: delay((acc, x) => acc + x), initial: 0});
+
+  fromIterable([1, 2, 3]).pipe(r);
+
+  r.on('finish', () => {
+    t.deepEqual(r.accumulator, 6);
+    resolve();
+  });
+});

+ 0 - 97
tests/test_fromIterable.js

@@ -1,97 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const chain = require('../src/index');
-const {streamToArray, delay} = require('./helpers');
-
-const fromIterable = require('../src/utils/fromIterable');
-
-unit.add(module, [
-  function test_fromIterable(t) {
-    const async = t.startAsync('test_fromIterable');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2, 3])'));
-      async.done();
-    });
-  },
-  function test_fromIterableFun(t) {
-    const async = t.startAsync('test_fromIterableFun');
-
-    const output = [],
-      c = chain([fromIterable(() => 0), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [0])'));
-      async.done();
-    });
-  },
-  function test_fromIterableAsyncFun(t) {
-    const async = t.startAsync('test_fromIterableAsyncFun');
-
-    const output = [],
-      c = chain([fromIterable(delay(() => 0)), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [0])'));
-      async.done();
-    });
-  },
-  function test_fromIterableGen(t) {
-    const async = t.startAsync('test_fromIterableGen');
-
-    const output = [],
-      c = chain([
-        fromIterable(function* () {
-          yield 0;
-          yield 1;
-        }),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [0, 1])'));
-      async.done();
-    });
-  },
-  function test_fromIterableAsyncGen(t) {
-    const async = t.startAsync('test_fromIterableAsyncGen');
-
-    const output = [],
-      c = chain([
-        fromIterable(async function* () {
-          yield delay(() => 0)();
-          yield delay(() => 1)();
-        }),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [0, 1])'));
-      async.done();
-    });
-  },
-  function test_fromIterableNextable(t) {
-    const async = t.startAsync('test_fromIterableNextable');
-
-    const output = [],
-      c = chain([
-        fromIterable(
-          (function* () {
-            yield 0;
-            yield 1;
-          })()
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [0, 1])'));
-      async.done();
-    });
-  }
-]);

+ 88 - 0
tests/test_fromIterable.mjs

@@ -0,0 +1,88 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain from '../src/index.js';
+
+import fromIterable from '../src/utils/fromIterable.js';
+
+test.asPromise('fromIterable: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2, 3]);
+    resolve();
+  });
+});
+
+test.asPromise('fromIterable: function', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable(() => 0), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [0]);
+    resolve();
+  });
+});
+
+test.asPromise('fromIterable: async function', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable(delay(() => 0)), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [0]);
+    resolve();
+  });
+});
+
+test.asPromise('fromIterable: generator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable(function* () {
+        yield 0;
+        yield 1;
+      }),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [0, 1]);
+    resolve();
+  });
+});
+
+test.asPromise('fromIterable: async generator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable(async function* () {
+        yield delay(() => 0)();
+        yield delay(() => 1)();
+      }),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [0, 1]);
+    resolve();
+  });
+});
+
+test.asPromise('fromIterable: nextable', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable(
+        (function* () {
+          yield 0;
+          yield 1;
+        })()
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [0, 1]);
+    resolve();
+  });
+});

+ 0 - 180
tests/test_fun.js

@@ -1,180 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-
-const fromIterable = require('../src/utils/fromIterable');
-const fun = require('../src/fun');
-
-const {none, finalValue, many} = chain;
-
-unit.add(module, [
-  function test_fun(t) {
-    const async = t.startAsync('test_fun');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), fun(x => x * x, x => 2 * x + 1), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_funFinal(t) {
-    const async = t.startAsync('test_funFinal');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fun(x => x * x, x => finalValue(x), x => 2 * x + 1),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_funNothing(t) {
-    const async = t.startAsync('test_funNothing');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), fun(x => x * x, () => none, x => 2 * x + 1), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [])'));
-      async.done();
-    });
-  },
-  function test_funEmpty(t) {
-    const async = t.startAsync('test_funEmpty');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), x => x * x, fun(), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_funAsync(t) {
-    const async = t.startAsync('test_funAsync');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), fun(delay(x => x * x), x => 2 * x + 1), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_funGenerator(t) {
-    const async = t.startAsync('test_funGenerator');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fun(
-          x => x * x,
-          function*(x) {
-            yield x;
-            yield x + 1;
-            yield x + 2;
-          },
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 5, 7, 9, 11, 13, 19, 21, 23])'));
-      async.done();
-    });
-  },
-  function test_funMany(t) {
-    const async = t.startAsync('test_funMany');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        fun(x => x * x, x => many([x, x + 1, x + 2]), x => 2 * x + 1),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 5, 7, 9, 11, 13, 19, 21, 23])'));
-      async.done();
-    });
-  },
-  function test_funCombined(t) {
-    const async = t.startAsync('test_funCombined');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        fun(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function*(x) {
-            yield x;
-            yield x - 1;
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2, 10, 11, 2, 3, 20, 21])'));
-      async.done();
-    });
-  },
-  function test_funCombinedFinal(t) {
-    const async = t.startAsync('test_funCombinedFinal');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        fun(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function*(x) {
-            yield x;
-            yield finalValue(x - 1);
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, -2, 10, -11, 2, -3, 20, -21])'));
-      async.done();
-    });
-  },
-  function test_funAsFun(t) {
-    const async = t.startAsync('test_funAsFun');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        fun(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function*(x) {
-            yield x;
-            yield finalValue(x - 1);
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, -2, 10, -11, 2, -3, 20, -21])'));
-      async.done();
-    });
-  }
-]);

+ 195 - 0
tests/test_fun.mjs

@@ -0,0 +1,195 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain, {none, finalValue, many} from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+import fun from '../src/fun.js';
+
+test.asPromise('fun: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        x => x * x,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: final', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        x => x * x,
+        x => finalValue(x),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: nothing', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        x => x * x,
+        () => none,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, []);
+    resolve();
+  });
+});
+
+test.asPromise('fun: empty', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, fun(), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        delay(x => x * x),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: generator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        x => x * x,
+        function* (x) {
+          yield x;
+          yield x + 1;
+          yield x + 2;
+        },
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 5, 7, 9, 11, 13, 19, 21, 23]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: many', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      fun(
+        x => x * x,
+        x => many([x, x + 1, x + 2]),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 5, 7, 9, 11, 13, 19, 21, 23]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: combined', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      fun(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield x - 1;
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2, 10, 11, 2, 3, 20, 21]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: combined final', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      fun(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield finalValue(x - 1);
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, -2, 10, -11, 2, -3, 20, -21]);
+    resolve();
+  });
+});
+
+test.asPromise('fun: as fun', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      fun(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield finalValue(x - 1);
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, -2, 10, -11, 2, -3, 20, -21]);
+    resolve();
+  });
+});

+ 0 - 231
tests/test_gen.js

@@ -1,231 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-const fromIterable = require('../src/utils/fromIterable');
-
-const {none, finalValue, many, gen} = chain;
-
-unit.add(module, [
-  function test_gen(t) {
-    const async = t.startAsync('test_gen');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_genFinal(t) {
-    const async = t.startAsync('test_genFinal');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          x => finalValue(x),
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_compNothing(t) {
-    const async = t.startAsync('test_compNothing');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          () => none,
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [])'));
-      async.done();
-    });
-  },
-  function test_genEmpty(t) {
-    const async = t.startAsync('test_genEmpty');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), x => x * x, gen(), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_genAsync(t) {
-    const async = t.startAsync('test_genAsync');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          delay(x => x * x),
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_genGenerator(t) {
-    const async = t.startAsync('test_genGenerator');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          function* (x) {
-            yield x;
-            yield x + 1;
-            yield x + 2;
-          },
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 5, 7, 9, 11, 13, 19, 21, 23])'));
-      async.done();
-    });
-  },
-  function test_genMany(t) {
-    const async = t.startAsync('test_genMany');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          x => many([x, x + 1, x + 2]),
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 5, 7, 9, 11, 13, 19, 21, 23])'));
-      async.done();
-    });
-  },
-  function test_genCombined(t) {
-    const async = t.startAsync('test_genCombined');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        gen(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function* (x) {
-            yield x;
-            yield x - 1;
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2, 10, 11, 2, 3, 20, 21])'));
-      async.done();
-    });
-  },
-  function test_genCombinedFinal(t) {
-    const async = t.startAsync('test_genCombinedFinal');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        gen(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function* (x) {
-            yield x;
-            yield finalValue(x - 1);
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, -2, 10, -11, 2, -3, 20, -21])'));
-      async.done();
-    });
-  },
-  function test_genSyncIterator(t) {
-    const async = t.startAsync('test_genSyncIterator');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        gen(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          function* (x) {
-            yield x;
-            yield finalValue(x - 1);
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, -2, 10, -11, 2, -3, 20, -21])'));
-      async.done();
-    });
-  },
-  function test_genAsyncIterator(t) {
-    const async = t.startAsync('test_genAsyncIterator');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2]),
-        gen(
-          delay(x => -x),
-          x => many([x, x * 10]),
-          async function* (x) {
-            yield delay(x => x)(x);
-            yield delay(x => finalValue(x - 1))(x);
-          },
-          x => -x
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, -2, 10, -11, 2, -3, 20, -21])'));
-      async.done();
-    });
-  }
-]);

+ 215 - 0
tests/test_gen.mjs

@@ -0,0 +1,215 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain, {none, finalValue, many, gen} from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+test.asPromise('gen: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: final', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        x => finalValue(x),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: nothing', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        () => none,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, []);
+    resolve();
+  });
+});
+
+test.asPromise('gen: empty', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, gen(), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        delay(x => x * x),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: generator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        function* (x) {
+          yield x;
+          yield x + 1;
+          yield x + 2;
+        },
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 5, 7, 9, 11, 13, 19, 21, 23]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: many', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        x => many([x, x + 1, x + 2]),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 5, 7, 9, 11, 13, 19, 21, 23]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: combined', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      gen(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield x - 1;
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2, 10, 11, 2, 3, 20, 21]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: combined final', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      gen(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield finalValue(x - 1);
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, -2, 10, -11, 2, -3, 20, -21]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: iterator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      gen(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        function* (x) {
+          yield x;
+          yield finalValue(x - 1);
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, -2, 10, -11, 2, -3, 20, -21]);
+    resolve();
+  });
+});
+
+test.asPromise('gen: async iterator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2]),
+      gen(
+        delay(x => -x),
+        x => many([x, x * 10]),
+        async function* (x) {
+          yield delay(x => x)(x);
+          yield delay(x => finalValue(x - 1))(x);
+        },
+        x => -x
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, -2, 10, -11, 2, -3, 20, -21]);
+    resolve();
+  });
+});

+ 0 - 96
tests/test_readWrite.js

@@ -1,96 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray} = require('./helpers');
-const chain = require('../src/index');
-const fromIterable = require('../src/utils/fromIterable');
-
-unit.add(module, [
-  function test_readWriteReadable(t) {
-    const async = t.startAsync('test_readWriteReadable');
-
-    const output1 = [],
-      output2 = [],
-      c = chain([fromIterable([1, 2, 3]), x => x * x]);
-
-    c.pipe(streamToArray(output1));
-
-    c.on('data', value => output2.push(value));
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output1, [1, 4, 9])'));
-      eval(t.TEST('t.unify(output2, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_readWriteWritable(t) {
-    const async = t.startAsync('test_readWriteWritable');
-
-    const output = [],
-      c = chain([x => x * x, streamToArray(output)]);
-
-    fromIterable([1, 2, 3]).pipe(c);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_readWriteReadableWritable(t) {
-    const async = t.startAsync('test_readWriteReadableWritable');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), x => x * x, streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_readWriteSingleReadable(t) {
-    const async = t.startAsync('test_readWriteSingleReadable');
-
-    const output1 = [],
-      output2 = [],
-      c = chain([fromIterable([1, 2, 3])]);
-
-    c.pipe(streamToArray(output1));
-
-    c.on('data', value => output2.push(value));
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output1, [1, 2, 3])'));
-      eval(t.TEST('t.unify(output2, [1, 2, 3])'));
-      async.done();
-    });
-  },
-  function test_readWriteSingleWritable(t) {
-    const async = t.startAsync('test_readWriteSingleWritable');
-
-    const output = [],
-      c = chain([streamToArray(output)]);
-
-    fromIterable([1, 2, 3]).pipe(c);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2, 3])'));
-      async.done();
-    });
-  },
-  function test_readWritePipeable(t) {
-    const async = t.startAsync('test_readWritePipeable');
-
-    const output1 = [],
-      output2 = [],
-      c = chain([fromIterable([1, 2, 3]), streamToArray(output1)]);
-
-    fromIterable([4, 5, 6])
-      .pipe(c)
-      .pipe(streamToArray(output2));
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output1, [1, 2, 3])'));
-      eval(t.TEST('t.unify(output2, [])'));
-      async.done();
-    });
-  }
-]);

+ 85 - 0
tests/test_readWrite.mjs

@@ -0,0 +1,85 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray} from './helpers.mjs';
+import chain from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+test.asPromise('readWrite: readable', (t, resolve) => {
+  const output1 = [],
+    output2 = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x]);
+
+  c.pipe(streamToArray(output1));
+
+  c.on('data', value => output2.push(value));
+  c.on('end', () => {
+    t.deepEqual(output1, [1, 4, 9]);
+    t.deepEqual(output2, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('readWrite: writable', (t, resolve) => {
+  const output = [],
+    c = chain([x => x * x, streamToArray(output)]);
+
+  fromIterable([1, 2, 3]).pipe(c);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('readWrite: readable and writable', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('readWrite: single readable', (t, resolve) => {
+  const output1 = [],
+    output2 = [],
+    c = chain([fromIterable([1, 2, 3])]);
+
+  c.pipe(streamToArray(output1));
+
+  c.on('data', value => output2.push(value));
+  c.on('end', () => {
+    t.deepEqual(output1, [1, 2, 3]);
+    t.deepEqual(output2, [1, 2, 3]);
+    resolve();
+  });
+});
+
+test.asPromise('readWrite: single writable', (t, resolve) => {
+  const output = [],
+    c = chain([streamToArray(output)]);
+
+  fromIterable([1, 2, 3]).pipe(c);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2, 3]);
+    resolve();
+  });
+});
+
+test.asPromise('readWrite: pipeable', (t, resolve) => {
+  const output1 = [],
+    output2 = [],
+    c = chain([fromIterable([1, 2, 3]), streamToArray(output1)]);
+
+  fromIterable([4, 5, 6]).pipe(c).pipe(streamToArray(output2));
+
+  c.on('end', () => {
+    t.deepEqual(output1, [1, 2, 3]);
+    t.deepEqual(output2, []);
+    resolve();
+  });
+});

+ 0 - 146
tests/test_simple.js

@@ -1,146 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {Transform} = require('stream');
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-const fromIterable = require('../src/utils/fromIterable');
-
-unit.add(module, [
-  function test_simpleGeneric(t) {
-    const async = t.startAsync('test_simpleGeneric');
-
-    const c = chain([x => x * x]),
-      output1 = [],
-      output2 = [];
-
-    fromIterable([1, 2, 3]).pipe(c).pipe(streamToArray(output1));
-
-    c.on('data', value => output2.push(value));
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output1, [1, 4, 9])'));
-      eval(t.TEST('t.unify(output2, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_simpleGenerator(t) {
-    const async = t.startAsync('test_simpleGenerator');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        function* (x) {
-          yield x * x;
-          yield x * x * x;
-          yield 2 * x;
-        },
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 1, 2, 4, 8, 4, 9, 27, 6])'));
-      async.done();
-    });
-  },
-  function test_simpleAsync(t) {
-    const async = t.startAsync('test_simpleAsync');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), delay(x => x + 1), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [2, 3, 4])'));
-      async.done();
-    });
-  },
-  function test_simpleMany(t) {
-    const async = t.startAsync('test_simpleMany');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        x => chain.many([x * x, x * x * x, 2 * x]),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 1, 2, 4, 8, 4, 9, 27, 6])'));
-      async.done();
-    });
-  },
-  function test_simpleChain(t) {
-    const async = t.startAsync('test_simpleChain');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        x => x * x,
-        x => 2 * x + 1,
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_simpleStream(t) {
-    const async = t.startAsync('test_simpleStream');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        new Transform({
-          objectMode: true,
-          transform(x, _, callback) {
-            callback(null, x * x);
-          }
-        }),
-        x => 2 * x + 1,
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_simpleFactory(t) {
-    const async = t.startAsync('test_simpleChain');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        x => x * x,
-        x => 2 * x + 1,
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_simpleIterable(t) {
-    const async = t.startAsync('test_simpleIterable');
-
-    const output = [],
-      c = chain([
-        [1, 2, 3],
-        function* (x) {
-          yield x * x;
-          yield x * x * x;
-          yield 2 * x;
-        },
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 1, 2, 4, 8, 4, 9, 27, 6])'));
-      async.done();
-    });
-
-    c.end(0); // start the chain
-  }
-]);

+ 115 - 0
tests/test_simple.mjs

@@ -0,0 +1,115 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {Transform} from 'stream';
+import {streamToArray, delay} from './helpers.mjs';
+import chain from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+test.asPromise('simple: smoke test', (t, resolve) => {
+  const c = chain([x => x * x]),
+    output1 = [],
+    output2 = [];
+
+  fromIterable([1, 2, 3]).pipe(c).pipe(streamToArray(output1));
+
+  c.on('data', value => output2.push(value));
+  c.on('end', () => {
+    t.deepEqual(output1, [1, 4, 9]);
+    t.deepEqual(output2, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: generator', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      function* (x) {
+        yield x * x;
+        yield x * x * x;
+        yield 2 * x;
+      },
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 1, 2, 4, 8, 4, 9, 27, 6]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: async function', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), delay(x => x + 1), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [2, 3, 4]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: async function', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      x => chain.many([x * x, x * x * x, 2 * x]),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 1, 2, 4, 8, 4, 9, 27, 6]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: chain', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, x => 2 * x + 1, streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: stream', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      new Transform({
+        objectMode: true,
+        transform(x, _, callback) {
+          callback(null, x * x);
+        }
+      }),
+      x => 2 * x + 1,
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: factory', (t, resolve) => {
+  const output = [],
+    c = chain([
+      [1, 2, 3],
+      function* (x) {
+        yield x * x;
+        yield x * x * x;
+        yield 2 * x;
+      },
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 1, 2, 4, 8, 4, 9, 27, 6]);
+    resolve();
+  });
+
+  c.end(0); // start the chain
+});

+ 0 - 46
tests/test_skip.js

@@ -1,46 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-
-const fromIterable = require('../src/utils/fromIterable');
-const skip = require('../src/utils/skip');
-const skipWhile = require('../src/utils/skipWhile');
-
-unit.add(module, [
-  function test_skip(t) {
-    const async = t.startAsync('test_skip');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), skip(2), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 4, 5])'));
-      async.done();
-    });
-  },
-  function test_skipWhile(t) {
-    const async = t.startAsync('test_skipWhile');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), skipWhile(x => x != 3), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 4, 5])'));
-      async.done();
-    });
-  },
-  function test_skipWhileAsync(t) {
-    const async = t.startAsync('test_skipWhileAsync');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), skipWhile(delay(x => x != 3)), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 4, 5])'));
-      async.done();
-    });
-  }
-]);

+ 44 - 0
tests/test_skip.mjs

@@ -0,0 +1,44 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+import skip from '../src/utils/skip.js';
+import skipWhile from '../src/utils/skipWhile.js';
+
+test.asPromise('skip: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), skip(2), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 4, 5]);
+    resolve();
+  });
+});
+
+test.asPromise('skip: while', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), skipWhile(x => x != 3), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 4, 5]);
+    resolve();
+  });
+});
+
+test.asPromise('skip: while async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3, 4, 5]),
+      skipWhile(delay(x => x != 3)),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 4, 5]);
+    resolve();
+  });
+});

+ 0 - 82
tests/test_take.js

@@ -1,82 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray, delay} = require('./helpers');
-const chain = require('../src/index');
-
-const fromIterable = require('../src/utils/fromIterable');
-const take = require('../src/utils/take');
-const takeWhile = require('../src/utils/takeWhile');
-const takeWithSkip = require('../src/utils/takeWithSkip');
-
-const {stop} = chain;
-
-unit.add(module, [
-  function test_take(t) {
-    const async = t.startAsync('test_take');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), take(2), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2])'));
-      async.done();
-    });
-  },
-  function test_takeWithSkip(t) {
-    const async = t.startAsync('test_takeWithSkip');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), takeWithSkip(2, 2), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 4])'));
-      async.done();
-    });
-  },
-  function test_takeWhile(t) {
-    const async = t.startAsync('test_takeWhile');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), takeWhile(x => x != 3), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2])'));
-      async.done();
-    });
-  },
-  function test_takeWhileAsync(t) {
-    const async = t.startAsync('test_takeWhileAsync');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), takeWhile(delay(x => x != 3)), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2])'));
-      async.done();
-    });
-  },
-  function test_takeStop(t) {
-    const async = t.startAsync('test_takeStop');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), take(2, stop), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 2])'));
-      async.done();
-    });
-  },
-  function test_takeStopWithSkip(t) {
-    const async = t.startAsync('test_takeStopWithSkip');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3, 4, 5]), takeWithSkip(2, 2, stop), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 4])'));
-      async.done();
-    });
-  }
-]);

+ 75 - 0
tests/test_take.mjs

@@ -0,0 +1,75 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray, delay} from './helpers.mjs';
+import chain, {stop} from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+import take from '../src/utils/take.js';
+import takeWhile from '../src/utils/takeWhile.js';
+import takeWithSkip from '../src/utils/takeWithSkip.js';
+
+test.asPromise('take: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), take(2), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: with skip', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), takeWithSkip(2, 2), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 4]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: while', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), takeWhile(x => x != 3), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: while async', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3, 4, 5]),
+      takeWhile(delay(x => x != 3)),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: stop', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), take(2, stop), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 2]);
+    resolve();
+  });
+});
+
+test.asPromise('simple: stop with skip', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3, 4, 5]), takeWithSkip(2, 2, stop), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 4]);
+    resolve();
+  });
+});

+ 0 - 95
tests/test_transducers.js

@@ -1,95 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-const {streamToArray} = require('./helpers');
-const chain = require('../src/index');
-const fromIterable = require('../src/utils/fromIterable');
-
-const {gen} = chain;
-
-unit.add(module, [
-  function test_transducers(t) {
-    const async = t.startAsync('test_transducers');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  },
-  function test_transducersFinal(t) {
-    const async = t.startAsync('test_transducersFinal');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          x => chain.finalValue(x),
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_transducersNothing(t) {
-    const async = t.startAsync('test_transducersNothing');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        gen(
-          x => x * x,
-          () => chain.none,
-          x => 2 * x + 1
-        ),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [])'));
-      async.done();
-    });
-  },
-  function test_transducersEmpty(t) {
-    const async = t.startAsync('test_transducersEmpty');
-
-    const output = [],
-      c = chain([fromIterable([1, 2, 3]), x => x * x, gen(), streamToArray(output)]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [1, 4, 9])'));
-      async.done();
-    });
-  },
-  function test_transducersOne(t) {
-    const async = t.startAsync('test_transducersOne');
-
-    const output = [],
-      c = chain([
-        fromIterable([1, 2, 3]),
-        x => x * x,
-        gen(x => 2 * x + 1),
-        streamToArray(output)
-      ]);
-
-    c.on('end', () => {
-      eval(t.TEST('t.unify(output, [3, 9, 19])'));
-      async.done();
-    });
-  }
-]);

+ 80 - 0
tests/test_transducers.mjs

@@ -0,0 +1,80 @@
+'use strict';
+
+import test from 'tape-six';
+
+import {streamToArray} from './helpers.mjs';
+import chain, {gen} from '../src/index.js';
+import fromIterable from '../src/utils/fromIterable.js';
+
+test.asPromise('transducers: smoke test', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});
+
+test.asPromise('transducers: final', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        x => chain.finalValue(x),
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('transducers: nothing', (t, resolve) => {
+  const output = [],
+    c = chain([
+      fromIterable([1, 2, 3]),
+      gen(
+        x => x * x,
+        () => chain.none,
+        x => 2 * x + 1
+      ),
+      streamToArray(output)
+    ]);
+
+  c.on('end', () => {
+    t.deepEqual(output, []);
+    resolve();
+  });
+});
+
+test.asPromise('transducers: empty', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, gen(), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [1, 4, 9]);
+    resolve();
+  });
+});
+
+test.asPromise('transducers: one', (t, resolve) => {
+  const output = [],
+    c = chain([fromIterable([1, 2, 3]), x => x * x, gen(x => 2 * x + 1), streamToArray(output)]);
+
+  c.on('end', () => {
+    t.deepEqual(output, [3, 9, 19]);
+    resolve();
+  });
+});

+ 0 - 21
tests/tests.js

@@ -1,21 +0,0 @@
-'use strict';
-
-const unit = require('heya-unit');
-
-require('./test_fromIterable');
-
-require('./test_simple');
-require('./test_readWrite');
-require('./test_errors');
-
-require('./test_transducers');
-require('./test_fun');
-require('./test_gen');
-
-require('./test_take');
-require('./test_skip');
-require('./test_fold');
-
-require('./test_demo');
-
-unit.run();