@@ -21,6 +21,15 @@ var dataset = 'dataset';
21
21
var table = 'table' ;
22
22
var format = 'JSON' ;
23
23
var schema = 'schema' ;
24
+ var jsonArray = [
25
+ { name : 'foo' , age : 27 } ,
26
+ { name : 'bar' , age : 13 }
27
+ ] ;
28
+ var validJsonFile = 'validJsonFile' ;
29
+ var invalidJsonFile = 'invalidJsonFile' ;
30
+ var validJsonString = JSON . stringify ( jsonArray ) ;
31
+ var invalidJsonString = 'INVALID' ;
32
+ var errorList = [ 'error 1' , 'error 2' ] ;
24
33
25
34
function getSample ( ) {
26
35
var tableMocks = [
@@ -44,7 +53,8 @@ function getSample () {
44
53
var tableMock = {
45
54
export : sinon . stub ( ) . yields ( null , jobMock ) ,
46
55
delete : sinon . stub ( ) . yields ( null ) ,
47
- import : sinon . stub ( ) . yields ( null , jobMock )
56
+ import : sinon . stub ( ) . yields ( null , jobMock ) ,
57
+ insert : sinon . stub ( ) . yields ( null , errorList )
48
58
} ;
49
59
var datasetMock = {
50
60
table : sinon . stub ( ) . returns ( tableMock ) ,
@@ -57,11 +67,17 @@ function getSample () {
57
67
} ;
58
68
var BigQueryMock = sinon . stub ( ) . returns ( bigqueryMock ) ;
59
69
var StorageMock = sinon . stub ( ) . returns ( storageMock ) ;
70
+ var fsMock = {
71
+ readFileSync : sinon . stub ( ) . throws ( new Error ( 'Invalid file.' ) )
72
+ } ;
73
+ fsMock . readFileSync . withArgs ( validJsonFile ) . returns ( validJsonString ) ;
74
+ fsMock . readFileSync . withArgs ( invalidJsonFile ) . returns ( invalidJsonString ) ;
60
75
61
76
return {
62
77
program : proxyquire ( '../tables' , {
63
78
'@google-cloud/bigquery' : BigQueryMock ,
64
79
'@google-cloud/storage' : StorageMock ,
80
+ 'fs' : fsMock ,
65
81
yargs : proxyquire ( 'yargs' , { } )
66
82
} ) ,
67
83
mocks : {
@@ -74,6 +90,7 @@ function getSample () {
74
90
table : tableMock ,
75
91
bucket : bucketMock ,
76
92
dataset : datasetMock ,
93
+ fs : fsMock ,
77
94
tables : tableMocks
78
95
}
79
96
} ;
@@ -290,6 +307,45 @@ describe('bigquery:tables', function () {
290
307
} ) ;
291
308
} ) ;
292
309
310
+ describe ( 'insertRowsAsStream' , function ( ) {
311
+ var options = {
312
+ file : file ,
313
+ dataset : dataset ,
314
+ table : table ,
315
+ rows : jsonArray
316
+ } ;
317
+
318
+ it ( 'should stream-insert rows into a table' , function ( ) {
319
+ var program = getSample ( ) . program ;
320
+ var callback = sinon . stub ( ) ;
321
+
322
+ program . insertRowsAsStream ( options , callback ) ;
323
+ assert . equal ( callback . calledOnce , true ) ;
324
+ assert . deepEqual ( callback . firstCall . args , [ null , errorList ] ) ;
325
+ } ) ;
326
+
327
+ it ( 'should handle API errors' , function ( ) {
328
+ var example = getSample ( ) ;
329
+ var callback = sinon . stub ( ) ;
330
+ var error = new Error ( 'error' ) ;
331
+ example . mocks . table . insert = sinon . stub ( ) . yields ( error ) ;
332
+
333
+ example . program . insertRowsAsStream ( options , callback ) ;
334
+ assert . equal ( callback . calledOnce , true ) ;
335
+ assert . deepEqual ( callback . firstCall . args , [ error ] ) ;
336
+ } ) ;
337
+
338
+ it ( 'should handle (per-row) insert errors' , function ( ) {
339
+ var example = getSample ( ) ;
340
+ var callback = sinon . stub ( ) ;
341
+ example . mocks . table . insert = sinon . stub ( ) . yields ( null , errorList ) ;
342
+
343
+ example . program . insertRowsAsStream ( options , callback ) ;
344
+ assert . equal ( callback . calledOnce , true ) ;
345
+ assert . deepEqual ( callback . firstCall . args , [ null , errorList ] ) ;
346
+ } ) ;
347
+ } ) ;
348
+
293
349
describe ( 'main' , function ( ) {
294
350
it ( 'should call createTable' , function ( ) {
295
351
var program = getSample ( ) . program ;
@@ -349,6 +405,19 @@ describe('bigquery:tables', function () {
349
405
} ] ) ;
350
406
} ) ;
351
407
408
+ it ( 'should call insertRowsAsStream' , function ( ) {
409
+ var program = getSample ( ) . program ;
410
+ program . insertRowsAsStream = sinon . stub ( ) ;
411
+
412
+ program . main ( [ 'insert' , dataset , table , validJsonFile ] ) ;
413
+
414
+ assert . equal ( program . insertRowsAsStream . calledOnce , true ) ;
415
+ assert . deepEqual (
416
+ program . insertRowsAsStream . firstCall . args . slice ( 0 , - 1 ) ,
417
+ [ { rows : jsonArray , dataset : dataset , table : table } ]
418
+ ) ;
419
+ } ) ;
420
+
352
421
it ( 'should recognize --gzip flag' , function ( ) {
353
422
var program = getSample ( ) . program ;
354
423
program . exportTableToGCS = sinon . stub ( ) ;
@@ -380,5 +449,65 @@ describe('bigquery:tables', function () {
380
449
gzip : false
381
450
} ] ) ;
382
451
} ) ;
452
+
453
+ describe ( 'insert' , function ( ) {
454
+ var options = {
455
+ dataset : dataset ,
456
+ table : table ,
457
+ rows : jsonArray
458
+ } ;
459
+
460
+ it ( 'should accept valid JSON files' , function ( ) {
461
+ var program = getSample ( ) . program ;
462
+ program . insertRowsAsStream = sinon . stub ( ) ;
463
+
464
+ program . main ( [ 'insert' , dataset , table , validJsonFile ] ) ;
465
+
466
+ assert . equal ( program . insertRowsAsStream . calledOnce , true ) ;
467
+ assert . deepEqual ( program . insertRowsAsStream . firstCall . args . slice ( 0 , - 1 ) , [ options ] ) ;
468
+ } ) ;
469
+
470
+ it ( 'should reject files with invalid JSON' , function ( ) {
471
+ var program = getSample ( ) . program ;
472
+ program . insertRowsAsStream = sinon . stub ( ) ;
473
+
474
+ assert . throws (
475
+ function ( ) { program . main ( [ 'insert' , dataset , table , invalidJsonFile ] ) ; } ,
476
+ / " j s o n _ o r _ f i l e " \( o r t h e f i l e i t p o i n t s t o \) i s n o t a v a l i d J S O N a r r a y \. /
477
+ ) ;
478
+ assert . equal ( program . insertRowsAsStream . called , false ) ;
479
+ } ) ;
480
+
481
+ it ( 'should reject invalid file names' , function ( ) {
482
+ var program = getSample ( ) . program ;
483
+ program . insertRowsAsStream = sinon . stub ( ) ;
484
+
485
+ assert . throws (
486
+ function ( ) { program . main ( [ 'insert' , dataset , table , '' ] ) ; } ,
487
+ / " j s o n _ o r _ f i l e " \( o r t h e f i l e i t p o i n t s t o \) i s n o t a v a l i d J S O N a r r a y \. /
488
+ ) ;
489
+ assert . equal ( program . insertRowsAsStream . called , false ) ;
490
+ } ) ;
491
+
492
+ it ( 'should accept valid JSON strings' , function ( ) {
493
+ var program = getSample ( ) . program ;
494
+ program . insertRowsAsStream = sinon . stub ( ) ;
495
+
496
+ program . main ( [ 'insert' , dataset , table , validJsonString ] ) ;
497
+ assert . equal ( program . insertRowsAsStream . calledOnce , true ) ;
498
+ assert . deepEqual ( program . insertRowsAsStream . firstCall . args . slice ( 0 , - 1 ) , [ options ] ) ;
499
+ } ) ;
500
+
501
+ it ( 'should reject invalid JSON strings' , function ( ) {
502
+ var program = getSample ( ) . program ;
503
+ program . insertRowsAsStream = sinon . stub ( ) ;
504
+
505
+ assert . throws (
506
+ function ( ) { program . main ( [ 'insert' , dataset , table , invalidJsonString ] ) ; } ,
507
+ / " j s o n _ o r _ f i l e " \( o r t h e f i l e i t p o i n t s t o \) i s n o t a v a l i d J S O N a r r a y \. /
508
+ ) ;
509
+ assert . equal ( program . insertRowsAsStream . called , false ) ;
510
+ } ) ;
511
+ } ) ;
383
512
} ) ;
384
513
} ) ;
0 commit comments