Skip to content

Commit 348dc72

Browse files
add tests
1 parent d853f6c commit 348dc72

1 file changed

Lines changed: 225 additions & 0 deletions

File tree

test/bigquery/job.js

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ function FakeServiceObject() {
3131

3232
nodeutil.inherits(FakeServiceObject, ServiceObject);
3333

34+
var utilOverrides = {};
35+
var fakeUtil = Object.keys(util).reduce(function(fakeUtil, methodName) {
36+
fakeUtil[methodName] = function() {
37+
var method = utilOverrides[methodName] || util[methodName];
38+
return method.apply(this, arguments);
39+
};
40+
return fakeUtil;
41+
}, {});
42+
3443
describe('BigQuery/Job', function() {
3544
var BIGQUERY = {
3645
projectId: 'my-project'
@@ -44,6 +53,8 @@ describe('BigQuery/Job', function() {
4453
'../../lib/common/service-object.js',
4554
FakeServiceObject
4655
);
56+
mockery.registerMock('../../lib/common/util.js', fakeUtil);
57+
4758
mockery.enable({
4859
useCleanCache: true,
4960
warnOnUnregistered: false
@@ -58,6 +69,7 @@ describe('BigQuery/Job', function() {
5869
});
5970

6071
beforeEach(function() {
72+
utilOverrides = {};
6173
job = new Job(BIGQUERY, JOB_ID);
6274
});
6375

@@ -81,6 +93,11 @@ describe('BigQuery/Job', function() {
8193
});
8294
});
8395

96+
it('should correctly initialize variables', function() {
97+
assert.strictEqual(job.completeListeners, 0);
98+
assert.strictEqual(job.hasActiveListeners, false);
99+
});
100+
84101
describe('request interceptor', function() {
85102
it('should assign a request interceptor for /cancel', function() {
86103
var requestInterceptor = job.interceptors.pop().request;
@@ -219,4 +236,212 @@ describe('BigQuery/Job', function() {
219236
job.getQueryResults().done();
220237
});
221238
});
239+
240+
describe('listenForEvents_', function() {
241+
beforeEach(function() {
242+
job.startPolling_ = util.noop;
243+
});
244+
245+
it('should start polling when complete listener is bound', function(done) {
246+
job.startPolling_ = function() {
247+
done();
248+
};
249+
250+
job.on('complete', util.noop);
251+
});
252+
253+
it('should track the number of listeners', function() {
254+
assert.strictEqual(job.completeListeners, 0);
255+
256+
job.on('complete', util.noop);
257+
assert.strictEqual(job.completeListeners, 1);
258+
259+
job.removeListener('complete', util.noop);
260+
assert.strictEqual(job.completeListeners, 0);
261+
});
262+
263+
it('should only run a single pulling loop', function() {
264+
var startPollingCallCount = 0;
265+
266+
job.startPolling_ = function() {
267+
startPollingCallCount++;
268+
};
269+
270+
job.on('complete', util.noop);
271+
job.on('complete', util.noop);
272+
273+
assert.strictEqual(startPollingCallCount, 1);
274+
});
275+
276+
it('should close when no more message listeners are bound', function() {
277+
job.on('complete', util.noop);
278+
job.on('complete', util.noop);
279+
assert.strictEqual(job.hasActiveListeners, true);
280+
281+
job.removeListener('complete', util.noop);
282+
assert.strictEqual(job.hasActiveListeners, true);
283+
284+
job.removeListener('complete', util.noop);
285+
assert.strictEqual(job.hasActiveListeners, false);
286+
});
287+
});
288+
289+
describe('startPolling_', function() {
290+
var listenForEvents_;
291+
var job;
292+
293+
before(function() {
294+
listenForEvents_ = Job.prototype.listenForEvents_;
295+
});
296+
297+
after(function() {
298+
Job.prototype.listenForEvents_ = listenForEvents_;
299+
});
300+
301+
beforeEach(function() {
302+
Job.prototype.listenForEvents_ = util.noop;
303+
job = new Job(BIGQUERY, JOB_ID);
304+
job.hasActiveListeners = true;
305+
});
306+
307+
afterEach(function() {
308+
job.hasActiveListeners = false;
309+
});
310+
311+
it('should not call getMetadata if no listeners', function(done) {
312+
job.hasActiveListeners = false;
313+
314+
job.getMetadata = done; // if called, test will fail.
315+
316+
job.startPolling_();
317+
done();
318+
});
319+
320+
it('should call getMetadata if listeners are registered', function(done) {
321+
job.hasActiveListeners = true;
322+
323+
job.getMetadata = function() {
324+
done();
325+
};
326+
327+
job.startPolling_();
328+
});
329+
330+
describe('API error', function() {
331+
var error = new Error('Error.');
332+
var apiResponse = {};
333+
334+
beforeEach(function() {
335+
job.getMetadata = function(callback) {
336+
callback(error, null, apiResponse);
337+
};
338+
});
339+
340+
it('should emit the error', function(done) {
341+
job.on('error', function(err) {
342+
assert.strictEqual(err, error);
343+
done();
344+
});
345+
346+
job.startPolling_();
347+
});
348+
});
349+
350+
describe('job failure', function() {
351+
var error = new Error('Error.');
352+
var apiResponse = {
353+
status: {
354+
errors: error
355+
}
356+
};
357+
358+
beforeEach(function() {
359+
job.getMetadata = function(callback) {
360+
callback(null, apiResponse, apiResponse);
361+
};
362+
});
363+
364+
it('should detect and emit an error from the response', function(done) {
365+
utilOverrides.ApiError = function(body) {
366+
assert.strictEqual(body, apiResponse.status);
367+
368+
return error;
369+
};
370+
371+
job.on('error', function(err) {
372+
assert.strictEqual(err, error);
373+
done();
374+
});
375+
376+
job.startPolling_();
377+
});
378+
});
379+
380+
describe('job pending', function() {
381+
var apiResponse = {
382+
status: {
383+
state: 'PENDING'
384+
}
385+
};
386+
var setTimeoutCached = global.setTimeout;
387+
388+
beforeEach(function() {
389+
job.getMetadata = function(callback) {
390+
callback(null, apiResponse, apiResponse);
391+
};
392+
});
393+
394+
after(function() {
395+
global.setTimeout = setTimeoutCached;
396+
});
397+
398+
it('should call startPolling_ after 500 ms', function(done) {
399+
var startPolling_ = job.startPolling_;
400+
var startPollingCalled = false;
401+
402+
global.setTimeout = function(fn, timeoutMs) {
403+
fn(); // should call startPolling_
404+
assert.strictEqual(timeoutMs, 500);
405+
};
406+
407+
job.startPolling_ = function() {
408+
if (!startPollingCalled) {
409+
// Call #1.
410+
startPollingCalled = true;
411+
startPolling_.apply(this, arguments);
412+
return;
413+
}
414+
415+
// This is from the setTimeout call.
416+
assert.strictEqual(this, job);
417+
done();
418+
};
419+
420+
job.startPolling_();
421+
});
422+
});
423+
424+
describe('job complete', function() {
425+
var apiResponse = {
426+
status: {
427+
state: 'DONE'
428+
}
429+
};
430+
431+
beforeEach(function() {
432+
job.getMetadata = function(callback) {
433+
callback(null, apiResponse, apiResponse);
434+
};
435+
});
436+
437+
it('should emit complete with metadata', function(done) {
438+
job.on('complete', function(metadata) {
439+
assert.strictEqual(metadata, apiResponse);
440+
done();
441+
});
442+
443+
job.startPolling_();
444+
});
445+
});
446+
});
222447
});

0 commit comments

Comments
 (0)