Completed
Push — dev ( d30456...4fd03f )
by Fike
33s
created

test/suites/integration/concurrent/Future.spec.js   D

Complexity

Total Complexity 67
Complexity/F 1.46

Size

Lines of Code 211
Function Count 46

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
c 1
b 0
f 0
nc 1
dl 0
loc 211
rs 4.3333
wmc 67
mnd 1
bc 47
fnc 46
bpm 1.0217
cpm 1.4564
noi 4

How to fix   Complexity   

Complexity

Complex classes like test/suites/integration/concurrent/Future.spec.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/* eslint-env mocha */
2
/* eslint-disable no-unused-expressions */
3
4
var Future = require('../../../../lib').Concurrent.Future
5
var Sinon = require('sinon')
6
var Chai = require('chai')
7
var expect = Chai.expect
8
9
Chai.use(require('chai-as-promised'))
10
11
var branchStopper = function () {
12
  throw new Error('Unexpected branch execution')
13
}
14
15
describe('Integration', function () {
16
  describe('/concurrent', function () {
17
    describe('/Future.js', function () {
18
      describe('Future', function () {
19
        describe('< new', function () {
20
          it('does not require arguments', function () {
21
            expect(new Future()).to.be.instanceOf(Future)
22
          })
23
24
          it('accepts resolver function', function () {
25
            var value = 12
26
            var resolver = function (resolve) {
27
              resolve(value)
28
            }
29
            return expect(new Future(resolver)).to.eventually.equal(value)
30
          })
31
        })
32
33
        describe('#resolve', function () {
34
          it('resolves externally', function () {
35
            var future = new Future()
36
            var value = 12
37
            return expect(future.resolve(value)).to.eventually.equal(value)
38
          })
39
40
          it('doesn\'t resolve twice', function () {
41
            var future = new Future()
42
            var value = 12
43
            future.resolve(value)
44
            future.resolve([value])
45
            return expect(future).to.eventually.equal(value)
46
          })
47
        })
48
49
        describe('#reject', function () {
50
          it('rejects externally', function () {
51
            var future = new Future()
52
            var error = new Error()
53
            future.reject(error)
54
            return expect(future).to.eventually.be.rejectedWith(error)
55
          })
56
57
          it('doesn\'t reject twice', function () {
58
            var future = new Future()
59
            var error = new Error()
60
            future.reject(error)
61
            future.reject(new Error())
62
            return expect(future).to.eventually.be.rejectedWith(error)
63
          })
64
        })
65
66
        describe('#then', function () {
67
          it('composes new Future', function () {
68
            var future = new Future()
69
            var nextFuture = future.then()
70
            expect(nextFuture).to.be.instanceOf(Future)
71
            expect(nextFuture).not.to.equal(future)
72
          })
73
74
          it('invokes resolution handler when fulfilled', function () {
75
            var future = new Future()
76
            var handler = Sinon.stub()
77
            var nextFuture = future.then(handler)
78
            var value = {value: 12}
79
            future.resolve(value)
80
            return nextFuture.then(function () {
81
              expect(handler.calledOnce).to.be.true
82
              expect(handler.getCall(0).args[0]).to.equal(value)
83
            })
84
          })
85
86
          it('invokes resolution handler even if set after fulfillment', function () {
87
            var future = new Future()
88
            var value = {value: 12}
89
            future.resolve(value)
90
            var handler = Sinon.stub()
91
            var nextFuture = future.then(handler)
92
            return nextFuture.then(function () {
93
              expect(handler.calledOnce).to.be.true
94
              expect(handler.getCall(0).args[0]).to.equal(value)
95
            })
96
          })
97
98
          it('invokes rejection handler when rejected', function () {
99
            var future = new Future()
100
            var handler = Sinon.stub()
101
            var nextFuture = future.then(null, handler)
102
            var value = {value: 12}
103
            future.reject(value)
104
            return nextFuture.then(function () {
105
              expect(handler.calledOnce).to.be.true
106
              expect(handler.getCall(0).args[0]).to.equal(value)
107
            })
108
          })
109
110
          it('invokes rejection handler even if set after rejection', function () {
111
            var future = new Future()
112
            var value = {value: 12}
113
            future.reject(value)
114
            var handler = Sinon.stub()
115
            var nextFuture = future.then(null, handler)
116
            return nextFuture.then(function () {
117
              expect(handler.calledOnce).to.be.true
118
              expect(handler.getCall(0).args[0]).to.equal(value)
119
            })
120
          })
121
        })
122
123
        describe('.resolve', function () {
124
          it('returns resolved promise', function () {
125
            var value = {x: 12}
126
            return expect(Future.resolve(value)).to.eventually.equal(value)
127
          })
128
        })
129
130
        describe('.reject', function () {
131
          it('returns rejected promise', function () {
132
            var value = {x: 12}
133
            var future = Future.reject(value)
134
            return expect(future).to.eventually.be.rejectedWith(value)
135
          })
136
        })
137
138
        describe('.wrap', function () {
139
          it('wraps Promise with a Future', function () {
140
            var promise = new Promise(function () {})
141
            return expect(Future.wrap(promise)).to.be.instanceOf(Future)
142
          })
143
144
          it('catches resolved Promise value', function () {
145
            var value = {x: 12}
146
            var promise = new Promise(function (resolve) {
147
              resolve(value)
148
            })
149
            var future = Future.wrap(promise)
150
            promise
151
              .then(function () {
152
                future.resolve([value])
153
              })
154
            return expect(future).to.eventually.equal(value)
155
          })
156
157
          it('catches rejected Promise value', function () {
158
            var value = {x: 12}
159
            var promise = new Promise(function (resolve, reject) {
160
              reject(value)
161
            })
162
            var future = Future.wrap(promise)
163
            promise
164
              .then(branchStopper, function () {
165
                future.reject([value])
166
              })
167
            return expect(future).to.eventually.be.rejectedWith(value)
168
          })
169
        })
170
171
        describe('.all', function () {
172
          it('returns resolved promise if nothing is passed', function () {
173
            return expect(Future.all([]))
174
          })
175
176
          it('awaits all promises and returns their results as array', function () {
177
            var promises = [new Future(), new Future(), new Future()]
178
            var target = Future.all(promises)
179
            var expectation = []
180
            for (var i = 0; i < promises.length; i++) {
181
              promises[i].resolve(i)
182
              expectation.push(i)
183
            }
184
            return expect(target).to.eventually.deep.eq(expectation)
185
          })
186
        })
187
188
        describe('.race', function () {
189
          it('doesn\'t resolve if nothing passed', function () {
190
            var value = {x: 12}
191
            var result = new Future()
192
            Future.race([]).then(function () {
193
              result.reject()
194
            })
195
            setTimeout(function () {
196
              result.resolve(value)
197
            }, 1)
198
            return expect(result).to.eventually.equal(value)
199
          })
200
201
          it('resolves with first value of the first resolved promise', function () {
202
            var value = {x: 12}
203
            var first = new Future()
204
            var second = new Future()
205
            var result = Future.race([first, second])
206
            first.resolve(value)
207
            second.reject()
208
            return expect(result).to.eventually.equal(value)
209
          })
210
        })
211
      })
212
    })
213
  })
214
})
215