js/walk: allow callback to return boolean in addition to Promise (#1511)

This commit is contained in:
Ben Kalman
2016-05-16 10:52:31 -07:00
parent 49cfe3ddc3
commit 5caad77f81
2 changed files with 30 additions and 14 deletions
+20 -8
View File
@@ -132,14 +132,26 @@ suite('walk', () => {
assert.equal(0, expected.size);
});
test('cb-default', async () => {
const rv = ds.writeValue(42);
const expected = new Set([rv, 42]);
await walk(rv, ds, async v => {
assert.isOk(expected.delete(v));
// return nothing -- default should be to recurse.
});
assert.equal(0, expected.size);
test('cb-should-recurse', async () => {
const testShouldRecurse = async (cb, expectRecurse) => {
const rv = ds.writeValue(42);
const expected = new Set([rv, 42]);
await walk(rv, ds, v => {
assert.isOk(expected.delete(v));
return cb();
});
assert.equal(expectRecurse ? 0 : 1, expected.size);
};
// Return void, Promise<void>, true, or Promise<true> -- should recurse.
await testShouldRecurse(() => { return; }, true); // eslint-disable-line
await testShouldRecurse(() => Promise.resolve(), true);
await testShouldRecurse(() => true, true);
await testShouldRecurse(() => Promise.resolve(true), true);
// Return true or Promise<true> -- should stop
await testShouldRecurse(() => false, false);
await testShouldRecurse(() => Promise.resolve(false), false);
});
});
+10 -6
View File
@@ -10,16 +10,20 @@ import Struct, {StructMirror} from './struct.js';
import type Database from './database.js';
import type {valueOrPrimitive} from './value.js';
type walkCb = (v: valueOrPrimitive) => ?bool | Promise<?bool>;
// Invokes |cb| once for |v| and each of its descendants. The returned promise is resolved when all
// invocations to |cb| have been resolved.
//
// The return value of |cb| indicates whether to recurse further into the tree. Return false to
// skip a node's children.
// The return value of |cb| indicates whether to recurse further into the tree. Return |false| or a
// Promise which resolves to |false| to skip a node's children.
//
// For convenience, if |cb| returns |undefined|, the default is |true|.
export default async function walk(v: valueOrPrimitive, ds: Database,
cb: (v: valueOrPrimitive) => Promise<?bool>): Promise<void> {
let cont = await cb(v);
// For convenience, if |cb| returns |undefined| or a Promise to |undefined|, the default is |true|.
export default async function walk(v: valueOrPrimitive, ds: Database, cb: walkCb): Promise<void> {
let cont = cb(v);
if (cont instanceof Promise) {
cont = await cont;
}
if (cont === undefined) {
cont = true;
}