Name: js-handler/node_modules/restify/node_modules/backoff/tests/backoff.js 
1:
/*
2:
 * Copyright (c) 2012 Mathieu Turcotte
3:
 * Licensed under the MIT license.
4:
 */
5:
 
6:
var sinon = require('sinon');
7:
 
8:
var Backoff = require('../lib/backoff');
9:
var BackoffStrategy = require('../lib/strategy/strategy');
10:
 
11:
exports["Backoff"] = {
12:
    setUp: function(callback) {
13:
        this.backoffStrategy = sinon.stub(new BackoffStrategy());
14:
        this.backoff = new Backoff(this.backoffStrategy);
15:
        this.clock = sinon.useFakeTimers();
16:
        this.spy = new sinon.spy();
17:
        callback();
18:
    },
19:
 
20:
    tearDown: function(callback) {
21:
        this.clock.restore();
22:
        callback();
23:
    },
24:
 
25:
    "the backoff event should be emitted when backoff starts": function(test) {
26:
        this.backoffStrategy.next.returns(10);
27:
        this.backoff.on('backoff', this.spy);
28:
 
29:
        this.backoff.backoff();
30:
 
31:
        test.ok(this.spy.calledOnce,
32:
            'Backoff event should be emitted when backoff starts.');
33:
        test.done();
34:
    },
35:
 
36:
    "the ready event should be emitted on backoff completion": function(test) {
37:
        this.backoffStrategy.next.returns(10);
38:
        this.backoff.on('ready', this.spy);
39:
 
40:
        this.backoff.backoff();
41:
        this.clock.tick(10);
42:
 
43:
        test.ok(this.spy.calledOnce,
44:
            'Ready event should be emitted when backoff ends.');
45:
        test.done();
46:
    },
47:
 
48:
    "the backoff event should be passed the backoff delay": function(test) {
49:
        this.backoffStrategy.next.returns(989);
50:
        this.backoff.on('backoff', this.spy);
51:
 
52:
        this.backoff.backoff();
53:
 
54:
        test.equal(this.spy.getCall(0).args[1], 989, 'Backoff event should ' +
55:
            'carry the backoff delay as its second argument.');
56:
        test.done();
57:
    },
58:
 
59:
    "the ready event should be passed the backoff delay": function(test) {
60:
        this.backoffStrategy.next.returns(989);
61:
        this.backoff.on('ready', this.spy);
62:
 
63:
        this.backoff.backoff();
64:
        this.clock.tick(989);
65:
 
66:
        test.equal(this.spy.getCall(0).args[1], 989, 'Ready event should ' +
67:
            'carry the backoff delay as its second argument.');
68:
        test.done();
69:
    },
70:
 
71:
    "the fail event should be emitted when backoff limit is reached": function(test) {
72:
        var err = new Error('Fail');
73:
 
74:
        this.backoffStrategy.next.returns(10);
75:
        this.backoff.on('fail', this.spy);
76:
 
77:
        this.backoff.failAfter(2);
78:
 
79:
        // Consume first 2 backoffs.
80:
        for (var i = 0; i < 2; i++) {
81:
            this.backoff.backoff();
82:
            this.clock.tick(10);
83:
        }
84:
 
85:
        // Failure should occur on the third call, and not before.
86:
        test.ok(!this.spy.calledOnce, 'Fail event shouldn\'t have been emitted.');
87:
        this.backoff.backoff(err);
88:
        test.ok(this.spy.calledOnce, 'Fail event should have been emitted.');
89:
        test.equal(this.spy.getCall(0).args[0], err, 'Error should be passed');
90:
 
91:
        test.done();
92:
    },
93:
 
94:
    "calling backoff while a backoff is in progress should throw an error": function(test) {
95:
        this.backoffStrategy.next.returns(10);
96:
        var backoff = this.backoff;
97:
 
98:
        backoff.backoff();
99:
 
100:
        test.throws(function() {
101:
            backoff.backoff();
102:
        }, /in progress/);
103:
 
104:
        test.done();
105:
    },
106:
 
107:
    "backoff limit should be greater than 0": function(test) {
108:
        var backoff = this.backoff;
109:
        test.throws(function() {
110:
            backoff.failAfter(0);
111:
        }, /must be greater than 0/);
112:
        test.done();
113:
    },
114:
 
115:
    "reset should cancel any backoff in progress": function(test) {
116:
        this.backoffStrategy.next.returns(10);
117:
        this.backoff.on('ready', this.spy);
118:
 
119:
        this.backoff.backoff();
120:
 
121:
        this.backoff.reset();
122:
        this.clock.tick(100);   // 'ready' should not be emitted.
123:
 
124:
        test.equals(this.spy.callCount, 0, 'Reset should have aborted the backoff.');
125:
        test.done();
126:
    },
127:
 
128:
    "reset should reset the backoff strategy": function(test) {
129:
        this.backoff.reset();
130:
        test.ok(this.backoffStrategy.reset.calledOnce,
131:
            'The backoff strategy should have been resetted.');
132:
        test.done();
133:
    },
134:
 
135:
    "backoff should be reset after fail": function(test) {
136:
        this.backoffStrategy.next.returns(10);
137:
 
138:
        this.backoff.failAfter(1);
139:
 
140:
        this.backoff.backoff();
141:
        this.clock.tick(10);
142:
        this.backoff.backoff();
143:
 
144:
        test.ok(this.backoffStrategy.reset.calledOnce,
145:
            'Backoff should have been resetted after failure.');
146:
        test.done();
147:
    },
148:
 
149:
    "the backoff number should increase from 0 to N - 1": function(test) {
150:
        this.backoffStrategy.next.returns(10);
151:
        this.backoff.on('backoff', this.spy);
152:
 
153:
        var expectedNumbers = [0, 1, 2, 3, 4];
154:
        var actualNumbers = [];
155:
 
156:
        for (var i = 0; i < expectedNumbers.length; i++) {
157:
            this.backoff.backoff();
158:
            this.clock.tick(10);
159:
            actualNumbers.push(this.spy.getCall(i).args[0]);
160:
        }
161:
 
162:
        test.deepEqual(expectedNumbers, actualNumbers,
163:
            'Backoff number should increase from 0 to N - 1.');
164:
        test.done();
165:
    }
166:
};