3 var expect = require('expect.js');
4 var EventEmitter = require('events').EventEmitter;
5 var progress = require('../');
7 function normalizeStates(states) {
8 states.forEach(function (state) {
9 state.time.elapsed = Math.round(state.time.elapsed),
10 state.time.remaining = state.time.remaining != null ? Math.round(state.time.remaining) : null;
11 state.speed = state.speed != null ? Math.round(state.speed) : null;
15 describe('request-progress', function () {
19 beforeEach(function () {
21 request = new EventEmitter();
23 request.on('progress', function (state) {
24 states.push(JSON.parse(JSON.stringify(state)));
28 it('should emit the progress event with the correct state information', function (done) {
29 progress(request, { throttle: 0 })
30 .on('end', function () {
31 normalizeStates(states);
33 expect(states).to.eql([{
36 size: { total: 10, transferred: 5, },
37 time: { elapsed: 0, remaining: null }
41 size: { total: 10, transferred: 8 },
42 time: { elapsed: 1, remaining: 0 }
46 size: { total: 10, transferred: 10 },
47 time: { elapsed: 1, remaining: 0 }
53 request.emit('request');
54 request.emit('response', { headers: { 'content-length': 10 } });
56 setTimeout(function () {
57 request.emit('data', new Buffer('aaaaa'));
60 setTimeout(function () {
61 request.emit('data', new Buffer('bbb'));
64 setTimeout(function () {
65 request.emit('data', new Buffer('cc'));
70 it('should provide request.progressState (and request.progressContext)', function (done) {
71 progress(request, { throttle: 0 })
72 .on('end', function () {
73 expect(request.progressState).to.be(null);
74 expect(request.progressContext).to.be(null);
78 expect(request.progressContext).to.be.an('object');
79 expect(request.progressState).to.be(undefined);
81 request.emit('request');
82 request.emit('response', { headers: { 'content-length': 2 } });
84 expect(request.progressContext).to.be.an('object');
85 expect(request.progressState).to.be.an('object');
87 setTimeout(function () {
88 request.emit('data', new Buffer('a'));
89 expect(request.progressContext).to.be.an('object');
90 expect(request.progressState).to.be.an('object');
91 expect(request.progressState.percentage).to.be(0.5);
94 setTimeout(function () {
95 request.emit('data', new Buffer('b'));
96 expect(request.progressContext).to.be.an('object');
97 expect(request.progressState).to.be.an('object');
98 expect(request.progressState.percentage).to.be(1);
103 it('should have a option.delay default of 0', function () {
105 expect(request.progressContext.options.delay).to.be(0);
108 it('should respect the passed option.delay', function (done) {
109 progress(request, { throttle: 0, delay: 250 })
110 .on('end', function () {
111 expect(states).to.have.length(2);
112 expect(states[0].percentage).to.be(0.6);
113 expect(states[1].percentage).to.be(1);
118 request.emit('request');
119 request.emit('response', { headers: { 'content-length': 10 } });
121 setTimeout(function () {
122 request.emit('data', new Buffer('aa'));
125 setTimeout(function () {
126 request.emit('data', new Buffer('bb'));
129 setTimeout(function () {
130 request.emit('data', new Buffer('cc'));
133 setTimeout(function () {
134 request.emit('data', new Buffer('dddd'));
139 it('should have a option.throttle default of 1000', function () {
141 expect(request.progressContext.options.throttle).to.be(1000);
144 it('should respect the passed option.throttle', function (done) {
145 progress(request, { throttle: 300, delay: 0 })
146 .on('end', function () {
147 expect(states).to.have.length(3);
148 expect(states[0].percentage).to.be(0.2);
149 expect(states[1].percentage).to.be(0.6);
150 expect(states[2].percentage).to.be(0.9);
155 request.emit('request');
156 request.emit('response', { headers: { 'content-length': 10 } });
158 setTimeout(function () {
159 request.emit('data', new Buffer('aa'));
162 setTimeout(function () {
163 request.emit('data', new Buffer('bb'));
166 setTimeout(function () {
167 request.emit('data', new Buffer('cc'));
170 setTimeout(function () {
171 request.emit('data', new Buffer('dd'));
174 setTimeout(function () {
175 request.emit('data', new Buffer('e'));
178 setTimeout(function () {
179 request.emit('data', new Buffer('bf'));
184 it('should have a option.lengthHeader default of "content-length"', function () {
186 expect(request.progressContext.options.lengthHeader).to.be('content-length');
189 it('should use option.lengthHeader', function (done) {
192 lengthHeader: 'x-transfer-length'
194 .on('end', function () {
195 expect(states).to.have.length(2);
196 expect(states[0].percentage).to.be(0.5);
197 expect(states[0].size.total).to.be(10);
198 expect(states[1].percentage).to.be(1);
199 expect(states[1].size.total).to.be(10);
204 request.emit('request');
205 request.emit('response', {
206 headers: { 'x-transfer-length': 10, 'content-length': 5 }
209 setTimeout(function () {
210 request.emit('data', new Buffer('aaaaa'));
213 setTimeout(function () {
214 request.emit('data', new Buffer('bbbbb'));
219 it('should fail if response is already set', function () {
220 request.response = { headers: { 'content-length': 10 } };
224 }).to.throwException(/too late/);
227 it('should deal with unknown content length', function (done) {
228 progress(request, { throttle: 0 })
229 .on('end', function () {
230 normalizeStates(states);
232 expect(states).to.eql([{
235 size: { total: null, transferred: 5, },
236 time: { elapsed: 0, remaining: null }
240 size: { total: null, transferred: 12, },
241 time: { elapsed: 1, remaining: null }
247 request.emit('request');
248 request.emit('response', { headers: {} });
250 setTimeout(function () {
251 request.emit('data', new Buffer('aaaaa'));
254 setTimeout(function () {
255 request.emit('data', new Buffer('bbbbbbb'));
260 it('should deal with payloads higher than the content length', function (done) {
261 progress(request, { throttle: 0 })
262 .on('end', function () {
263 normalizeStates(states);
265 expect(states).to.eql([{
268 size: { total: 10, transferred: 5, },
269 time: { elapsed: 0, remaining: null }
273 size: { total: 10, transferred: 12 },
274 time: { elapsed: 1, remaining: 0 }
280 request.emit('request');
281 request.emit('response', { headers: { 'content-length': 10 } });
283 setTimeout(function () {
284 request.emit('data', new Buffer('aaaaa'));
287 setTimeout(function () {
288 request.emit('data', new Buffer('bbbbbbb'));
293 it('should not report after the request ends', function (done) {
294 progress(request, { throttle: 100 });
296 request.emit('request');
297 request.emit('response', { headers: { 'content-length': 10 } });
299 setTimeout(function () {
300 request.emit('data', new Buffer('aa'));
303 setTimeout(function () {
304 request.emit('data', new Buffer('bbbbbbbb'));
308 setTimeout(function () {
309 normalizeStates(states);
311 expect(states).to.have.length(1);
312 expect(states[0].percentage).to.be(0.2);
318 it('should not generate duplicate progress events if called twice', function (done) {
319 progress(request, { throttle: 0 });
320 progress(request, { throttle: 0 })
321 .on('end', function () {
322 expect(states).to.have.length(1);
323 expect(states[0].percentage).to.be(1);
328 request.emit('request');
329 request.emit('response', { headers: { 'content-length': 2 } });
331 setTimeout(function () {
332 request.emit('data', new Buffer('aa'));
337 it('should reset stuff on "request" event', function () {
338 progress(request, { throttle: 0 });
340 expect(request.progressContext).to.be.an('object');
341 expect(request.progressState).to.be(undefined);
343 request.emit('request');
344 request.emit('response', { headers: { 'content-length': 2 } });
346 expect(request.progressContext).to.be.an('object');
347 expect(request.progressState).to.be.an('object');
349 request.emit('request');
351 expect(request.progressContext).to.be.an('object');
352 expect(request.progressState).to.be(null);