Skip to content

Commit

Permalink
test: refactor tests and add t.plan for each
Browse files Browse the repository at this point in the history
  • Loading branch information
lance committed Dec 22, 2016
1 parent 2d0387a commit ad2883a
Showing 1 changed file with 104 additions and 83 deletions.
187 changes: 104 additions & 83 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,102 +9,111 @@ browser.enable();

test('api', (t) => {
const breaker = circuitBreaker(passFail);
t.ok(circuitBreaker.promisify);
t.ok(breaker);
t.ok(breaker.fire);
t.notOk(breaker.opened);
t.notOk(breaker.halfOpen);
t.ok(breaker.closed);
t.ok(breaker.status);
t.ok(breaker.options);
t.equals(breaker.action, passFail);
t.ok(breaker, 'CircuitBreaker');
t.ok(circuitBreaker.promisify, 'CircuitBreaker.promisify');
t.ok(breaker.fire, 'CircuitBreaker.fire');
t.notOk(breaker.opened, 'CircuitBreaker.opened');
t.notOk(breaker.halfOpen, 'CircuitBreaker.halfOpen');
t.ok(breaker.closed, 'CircuitBreaker.closed');
t.ok(breaker.status, 'CircuitBreaker.status');
t.ok(breaker.options, 'CircuitBreaker.options');
t.equals(breaker.action, passFail, 'CircuitBreaker.action');
t.end();
});

test('Passes arguments to the circuit function', (t) => {
test('Passes parameters to the circuit function', (t) => {
t.plan(1);
const expected = 34;
const breaker = circuitBreaker(passFail);

breaker.fire(expected)
.then((arg) => t.equals(arg, expected))
.then((arg) => t.equals(arg, expected, 'function parameters provided'))
.then(t.end)
.catch(t.fail);
});

test('Fails when the circuit function fails', (t) => {
t.plan(1);
const breaker = circuitBreaker(passFail);

breaker.fire(-1)
.then(t.fail)
.catch((e) => t.equals(e, 'Error: -1 is < 0'))
.catch((e) => t.equals(e, 'Error: -1 is < 0', 'expected error caught'))
.then(t.end);
});

test('Fails when the circuit function times out', (t) => {
t.plan(1);
const expected = 'Timed out after 10ms';
const breaker = circuitBreaker(slowFunction, { timeout: 10 });

breaker.fire()
.then(t.fail)
.catch((e) => t.equals(e.message, expected))
.catch((e) => t.equals(e.message, expected, 'timeout message received'))
.then(t.end);
});

test('Works with functions that do not return a promise', (t) => {
t.plan(1);
const breaker = circuitBreaker(nonPromise);

breaker.fire()
.then((arg) => t.equals(arg, 'foo'))
.then((arg) => t.equals(arg, 'foo', 'nonPromise function returns expected value'))
.then(t.end)
.catch(t.fail);
});

test('Works with non-functions', (t) => {
t.plan(1);
const breaker = circuitBreaker('foobar');

breaker.fire()
.then((arg) => t.equals(arg, 'foobar'))
.then((arg) => t.equals(arg, 'foobar', 'expected raw value returns'))
.then(t.end)
.catch(t.fail);
});

test('Works with callback functions', (t) => {
t.plan(1);
const promisified = circuitBreaker.promisify(callbackFunction);
const breaker = circuitBreaker(promisified);

breaker.fire(3, 4)
.then((arg) => t.equals(arg, 7))
.then((arg) => t.equals(arg, 7, 'CircuitBreaker.promisify works'))
.then(t.end)
.catch(t.fail);
});

test('Works with callback functions that fail', (t) => {
t.plan(1);
const promisified = circuitBreaker.promisify(failedCallbackFunction);
const breaker = circuitBreaker(promisified);

breaker.fire(3, 4)
.then(t.fail)
.catch((e) => t.equals(e, 'Whoops!'))
.catch((e) => t.equals(e, 'Whoops!', 'caught expected error'))
.then(t.end);
});

test('Breaker opens after a configurable number of failures', (t) => {
t.plan(2);
const breaker = circuitBreaker(passFail, { maxFailures: 1 });

breaker.fire(-1)
.then(t.fail)
.catch((e) => t.equals(e, 'Error: -1 is < 0'))
.catch((e) => t.equals(e, 'Error: -1 is < 0', 'caught expected error'))
.then(() => {
// Now the breaker should be open, and should fast fail even
// with a valid value
breaker.fire(100)
.then(t.fail)
.catch((e) => t.equals(e, 'Breaker is open'))
.catch((e) => t.equals(e, 'Breaker is open', 'breaker opens'))
.then(t.end);
});
});

test('Breaker resets after a configurable amount of time', (t) => {
t.plan(1);
const fails = -1;
const resetTimeout = 100;
const breaker = circuitBreaker(passFail, { maxFailures: 1, resetTimeout });
Expand All @@ -115,13 +124,14 @@ test('Breaker resets after a configurable amount of time', (t) => {
// fire again.
setTimeout(() => {
breaker.fire(100)
.then((arg) => t.equals(arg, 100))
.then((arg) => t.equals(arg, 100, 'breaker has reset'))
.then(t.end);
}, resetTimeout * 1.25);
});
});

test('Breaker resets for circuits with a fallback function', (t) => {
t.plan(2);
const fails = -1;
const resetTimeout = 100;
const breaker = circuitBreaker(passFail, { maxFailures: 1, resetTimeout });
Expand All @@ -134,7 +144,7 @@ test('Breaker resets for circuits with a fallback function', (t) => {
setTimeout(() => {
breaker.fire(100)
.then((arg) => {
t.equals(arg, 100);
t.equals(arg, 100, 'breaker has reset');
})
.then(t.end)
.catch(t.fail);
Expand All @@ -145,12 +155,13 @@ test('Breaker resets for circuits with a fallback function', (t) => {
});

test('Executes fallback action, if one exists, when breaker is open', (t) => {
t.plan(1);
const fails = -1;
const expected = 100;
const breaker = circuitBreaker(passFail, { maxFailures: 1 });
breaker.fallback(() => expected);
breaker.on('fallback', (result) => {
t.equals(result, expected);
t.equals(result, expected, 'fallback action executes');
t.end();
});
breaker.fire(fails)
Expand All @@ -161,54 +172,57 @@ test('Executes fallback action, if one exists, when breaker is open', (t) => {
});

test('Passes arguments to the fallback function', (t) => {
t.plan(1);
const fails = -1;
const breaker = circuitBreaker(passFail, { maxFailures: 1 });
breaker.on('fallback', (result) => {
t.equals(result, fails);
t.equals(result, fails, 'fallback received expected parameters');
t.end();
});
breaker.fallback((x) => x);
breaker.fire(fails).then(t.fail);
});

test('Returns self from fallback()', (t) => {
t.plan(1);
circuitBreaker(passFail, { maxFailures: 1 })
.fallback(() => {})
.fire(1)
.then((result) => {
t.equals(result, 1);
t.equals(result, 1, 'circuitBreaker instance returned from fallback');
})
.then(t.end)
.catch(t.fail);
});

test('CircuitBreaker status', (t) => {
t.plan(11);
const breaker = circuitBreaker(passFail, { maxFailures: 1 });
const deepEqual = (t, expected) => (actual) => t.deepEqual(actual, expected);
const deepEqual = (t, expected) => (actual) => t.deepEqual(actual, expected, 'expected status values');

Fidelity.all([
breaker.fire(10).then(deepEqual(t, 10)),
breaker.fire(20).then(deepEqual(t, 20)),
breaker.fire(30).then(deepEqual(t, 30))
])
.then(() => t.deepEqual(breaker.status.fires, 3))
.then(() => t.deepEqual(breaker.status.fires, 3, 'breaker fired 3 times'))
.catch(t.fail)
.then(() => {
breaker.fire(-10)
.then(t.fail)
.catch((value) => {
t.deepEqual(value, 'Error: -10 is < 0');
t.deepEqual(breaker.status.failures, 1);
t.deepEqual(breaker.status.fires, 4);
t.equal(value, 'Error: -10 is < 0', 'fails with correct error message');
t.equal(breaker.status.failures, 1, 'status reports a single failure');
t.equal(breaker.status.fires, 4, 'status reports 4 fires');
})
.then(() => {
breaker.fallback(() => 'Fallback called');
breaker.fire(-20)
.then((result) => {
t.deepEqual(result, 'Fallback called');
t.deepEqual(breaker.status.failures, 2);
t.deepEqual(breaker.status.fires, 5);
t.deepEqual(breaker.status.fallbacks, 1);
t.equal(result, 'Fallback called', 'fallback is invoked');
t.equal(breaker.status.failures, 2, 'status reports 2 failures');
t.equal(breaker.status.fires, 5, 'status reports 5 fires');
t.equal(breaker.status.fallbacks, 1, 'status reports 1 fallback');
})
.catch(t.fail);
})
Expand All @@ -217,13 +231,18 @@ test('CircuitBreaker status', (t) => {
});

test('CircuitBreaker fallback event', (t) => {
t.plan(1);
const breaker = circuitBreaker(passFail, {maxFailures: 0});
breaker.fallback(() => {});
breaker.on('fallback', t.end); // if no event fires, test times out
breaker.fallback((x) => x);
breaker.on('fallback', (value) => {
t.equal(value, -1, 'fallback value received');
t.end();
});
breaker.fire(-1);
});

test('CircuitBreaker events', (t) => {
t.plan(41);
const options = {
maxFailures: 1,
timeout: 500,
Expand Down Expand Up @@ -253,82 +272,84 @@ test('CircuitBreaker events', (t) => {

breaker.fire(10)
.then(() => {
t.equals(fired, 1);
t.equals(success, 1);
t.equals(failures, 0);
t.equals(reject, 0);
t.equals(open, 0);
t.equals(close, 0);
t.equals(halfOpen, 0);
t.equals(timeout, 0);
t.equals(fired, 1, 'fire event fired');
t.equals(success, 1, 'success event fired');
t.equals(failures, 0, 'failure event did not fire');
t.equals(reject, 0, 'reject event did not fire');
t.equals(open, 0, 'open event did not fire');
t.equals(close, 0, 'close event did not fire');
t.equals(halfOpen, 0, 'halfOpen event did not fire');
t.equals(timeout, 0, 'timeout event did not fire');
})
.then(() => {
breaker.fire(-1)
.then(t.fail)
.catch((e) => {
t.equals(fired, 2);
t.equals(success, 1);
t.equals(failures, 1);
t.equals(reject, 0);
t.equals(open, 1);
t.equals(close, 0);
t.equals(halfOpen, 0);
t.equals(timeout, 0);
t.equals(fired, 2, 'fire event fired');
t.equals(success, 1, 'success event did not fire');
t.equals(failures, 1, 'failure event fired');
t.equals(reject, 0, 'reject event did not fire');
t.equals(open, 1, 'open event fired');
t.equals(close, 0, 'close event did not fire');
t.equals(halfOpen, 0, 'halfOpen event did not fire');
t.equals(timeout, 0, 'timeout event did not fire');
})
.then(() => {
breaker.fire(10)
.then(t.fail)
.catch((e) => {
t.equals(fired, 3);
t.equals(success, 1);
t.equals(failures, 2);
t.equals(reject, 1);
t.equals(open, 1);
t.equals(close, 0);
t.equals(halfOpen, 0);
t.equals(timeout, 0);
t.equals(fired, 3, 'fire event fired');
t.equals(success, 1, 'success event did not fire');
t.equals(failures, 2, 'failure event fired');
t.equals(reject, 1, 'reject event fired');
t.equals(open, 1, 'open event did not fire');
t.equals(close, 0, 'close event did not fire');
t.equals(halfOpen, 0, 'halfOpen event did not fire');
t.equals(timeout, 0, 'timeout event did not fire');
})
.then(() => {
return new Promise((resolve) => {
setTimeout(() => {
t.equals(fired, 3);
t.equals(success, 1);
t.equals(failures, 2);
t.equals(reject, 1);
t.equals(open, 1);
t.equals(close, 0);
t.equals(halfOpen, 1);
t.equals(timeout, 0);
t.equals(fired, 3, 'fire event did not fire');
t.equals(success, 1, 'success event did not fire');
t.equals(failures, 2, 'failure event did not fire');
t.equals(reject, 1, 'reject event did not fire');
t.equals(open, 1, 'open event did not fire');
t.equals(close, 0, 'close event did not fire');
t.equals(halfOpen, 1, 'halfOpen event fired');
t.equals(timeout, 0, 'timeout event did not fire');
resolve();
}, 500);
})
.then(() => {
breaker.fire(10)
.then(() => {
t.equals(fired, 4);
t.equals(success, 2);
t.equals(failures, 2);
t.equals(reject, 1);
t.equals(open, 1);
t.equals(close, 1);
t.equals(halfOpen, 1);
t.equals(timeout, 0);
});
t.equals(fired, 4, 'fire event fired');
t.equals(success, 2, 'success event fired');
t.equals(failures, 2, 'failure event did not fire');
t.equals(reject, 1, 'reject event did not fire');
t.equals(open, 1, 'open event did not fire');
t.equals(close, 1, 'close event fired');
t.equals(halfOpen, 1, 'halfOpen event did not fire');
t.equals(timeout, 0, 'timeout event did not fire');
})
.then(() => {
const timeoutBreaker = circuitBreaker(slowFunction, options);
let timedOut = false;
timeoutBreaker.on('timeout', () => timedOut++);
timeoutBreaker.fire().then(t.fail);
})
.then((e) => t.equals(timeout, 0, 'timeout event fired'))
.then(t.end);
});
});
});
})
.then(() => {
const timeoutBreaker = circuitBreaker(slowFunction, options);
let timedOut = false;
timeoutBreaker.on('timeout', () => timedOut++);
timeoutBreaker.fire().then(t.fail);
})
.then(t.end)
.catch(t.fail);
});

test('circuit halfOpen', (t) => {
t.plan(8);
const options = {
maxFailures: 1,
resetTimeout: 100
Expand Down

0 comments on commit ad2883a

Please sign in to comment.