@@ -468,6 +468,35 @@ function resolveOperationArgs(operationName, operationArgs, context) {
468
468
const CURSOR_COMMANDS = new Set ( [ 'find' , 'aggregate' , 'listIndexes' , 'listCollections' ] ) ;
469
469
const ADMIN_COMMANDS = new Set ( [ 'listDatabases' ] ) ;
470
470
471
+ const kOperations = new Map ( [
472
+ [
473
+ 'createIndex' ,
474
+ ( operation , collection /*, context, options */ ) => {
475
+ const fieldOrSpec = operation . arguments . keys ;
476
+ return collection . createIndex ( fieldOrSpec ) ;
477
+ }
478
+ ] ,
479
+ [
480
+ 'dropIndex' ,
481
+ ( operation , collection /*, context, options */ ) => {
482
+ const indexName = operation . arguments . name ;
483
+ return collection . dropIndex ( indexName ) ;
484
+ }
485
+ ] ,
486
+ [
487
+ 'mapReduce' ,
488
+ ( operation , collection /*, context, options */ ) => {
489
+ const args = operation . arguments ;
490
+ const map = args . map ;
491
+ const reduce = args . reduce ;
492
+ const options = { } ;
493
+ if ( args . out ) options . out = args . out ;
494
+
495
+ return collection . mapReduce ( map , reduce , options ) ;
496
+ }
497
+ ]
498
+ ] ) ;
499
+
471
500
/**
472
501
*
473
502
* @param {Object } operation the operation definition from the spec test
@@ -482,95 +511,101 @@ function testOperation(operation, obj, context, options) {
482
511
let args = [ ] ;
483
512
const operationName = translateOperationName ( operation . name ) ;
484
513
485
- if ( operation . arguments ) {
486
- args = resolveOperationArgs ( operationName , operation . arguments , context ) ;
487
-
488
- if ( args == null ) {
489
- args = [ ] ;
490
- Object . keys ( operation . arguments ) . forEach ( key => {
491
- if ( key === 'callback' ) {
492
- args . push ( ( ) =>
493
- testOperations ( operation . arguments . callback , context , { swallowOperationErrors : false } )
494
- ) ;
495
- return ;
496
- }
497
-
498
- if ( [ 'filter' , 'fieldName' , 'document' , 'documents' , 'pipeline' ] . indexOf ( key ) !== - 1 ) {
499
- return args . unshift ( operation . arguments [ key ] ) ;
500
- }
514
+ let opPromise ;
515
+ if ( kOperations . has ( operationName ) ) {
516
+ opPromise = kOperations . get ( operationName ) ( operation , obj , context , options ) ;
517
+ } else {
518
+ if ( operation . arguments ) {
519
+ args = resolveOperationArgs ( operationName , operation . arguments , context ) ;
520
+
521
+ if ( args == null ) {
522
+ args = [ ] ;
523
+ Object . keys ( operation . arguments ) . forEach ( key => {
524
+ if ( key === 'callback' ) {
525
+ args . push ( ( ) =>
526
+ testOperations ( operation . arguments . callback , context , {
527
+ swallowOperationErrors : false
528
+ } )
529
+ ) ;
530
+ return ;
531
+ }
501
532
502
- if ( ( key === 'map' || key === 'reduce' ) && operationName === 'mapReduce' ) {
503
- return args . unshift ( operation . arguments [ key ] ) ;
504
- }
533
+ if ( [ 'filter' , 'fieldName' , 'document' , 'documents' , 'pipeline' ] . indexOf ( key ) !== - 1 ) {
534
+ return args . unshift ( operation . arguments [ key ] ) ;
535
+ }
505
536
506
- if ( key === 'command' ) return args . unshift ( operation . arguments [ key ] ) ;
507
- if ( key === 'requests' ) return args . unshift ( extractBulkRequests ( operation . arguments [ key ] ) ) ;
508
- if ( key === 'update' || key === 'replacement' ) return args . push ( operation . arguments [ key ] ) ;
509
- if ( key === 'session' ) {
510
- if ( isTransactionCommand ( operationName ) ) return ;
511
- opOptions . session = context [ operation . arguments . session ] ;
512
- return ;
513
- }
537
+ if ( ( key === 'map' || key === 'reduce' ) && operationName === 'mapReduce' ) {
538
+ return args . unshift ( operation . arguments [ key ] ) ;
539
+ }
514
540
515
- if ( key === 'returnDocument' ) {
516
- opOptions . returnOriginal = operation . arguments [ key ] === 'Before' ? true : false ;
517
- return ;
518
- }
541
+ if ( key === 'command' ) return args . unshift ( operation . arguments [ key ] ) ;
542
+ if ( key === 'requests' )
543
+ return args . unshift ( extractBulkRequests ( operation . arguments [ key ] ) ) ;
544
+ if ( key === 'update' || key === 'replacement' ) return args . push ( operation . arguments [ key ] ) ;
545
+ if ( key === 'session' ) {
546
+ if ( isTransactionCommand ( operationName ) ) return ;
547
+ opOptions . session = context [ operation . arguments . session ] ;
548
+ return ;
549
+ }
519
550
520
- if ( key === 'options' ) {
521
- Object . assign ( opOptions , operation . arguments [ key ] ) ;
522
- if ( opOptions . readPreference ) {
523
- opOptions . readPreference = normalizeReadPreference ( opOptions . readPreference . mode ) ;
551
+ if ( key === 'returnDocument' ) {
552
+ opOptions . returnOriginal = operation . arguments [ key ] === 'Before' ? true : false ;
553
+ return ;
524
554
}
525
555
526
- return ;
527
- }
556
+ if ( key === 'options' ) {
557
+ Object . assign ( opOptions , operation . arguments [ key ] ) ;
558
+ if ( opOptions . readPreference ) {
559
+ opOptions . readPreference = normalizeReadPreference ( opOptions . readPreference . mode ) ;
560
+ }
528
561
529
- if ( key === 'readPreference' ) {
530
- opOptions [ key ] = normalizeReadPreference ( operation . arguments [ key ] . mode ) ;
531
- return ;
532
- }
562
+ return ;
563
+ }
533
564
534
- opOptions [ key ] = operation . arguments [ key ] ;
535
- } ) ;
536
- }
537
- }
565
+ if ( key === 'readPreference' ) {
566
+ opOptions [ key ] = normalizeReadPreference ( operation . arguments [ key ] . mode ) ;
567
+ return ;
568
+ }
538
569
539
- if (
540
- args . length === 0 &&
541
- ! isTransactionCommand ( operationName ) &&
542
- ! isTestRunnerCommand ( context , operationName )
543
- ) {
544
- args . push ( { } ) ;
545
- }
570
+ opOptions [ key ] = operation . arguments [ key ] ;
571
+ } ) ;
572
+ }
573
+ }
546
574
547
- if ( Object . keys ( opOptions ) . length > 0 ) {
548
- // NOTE: this is awful, but in order to provide options for some methods we need to add empty
549
- // query objects.
550
- if ( operationName === 'distinct' ) {
575
+ if (
576
+ args . length === 0 &&
577
+ ! isTransactionCommand ( operationName ) &&
578
+ ! isTestRunnerCommand ( context , operationName )
579
+ ) {
551
580
args . push ( { } ) ;
552
581
}
553
582
554
- args . push ( opOptions ) ;
555
- }
583
+ if ( Object . keys ( opOptions ) . length > 0 ) {
584
+ // NOTE: this is awful, but in order to provide options for some methods we need to add empty
585
+ // query objects.
586
+ if ( operationName === 'distinct' ) {
587
+ args . push ( { } ) ;
588
+ }
556
589
557
- if ( ADMIN_COMMANDS . has ( operationName ) ) {
558
- obj = obj . db ( ) . admin ( ) ;
559
- }
590
+ args . push ( opOptions ) ;
591
+ }
560
592
561
- if ( operation . name === 'listDatabaseNames' || operation . name === 'listCollectionNames' ) {
562
- opOptions . nameOnly = true ;
563
- }
593
+ if ( ADMIN_COMMANDS . has ( operationName ) ) {
594
+ obj = obj . db ( ) . admin ( ) ;
595
+ }
564
596
565
- let opPromise ;
597
+ if ( operation . name === 'listDatabaseNames' || operation . name === 'listCollectionNames' ) {
598
+ opOptions . nameOnly = true ;
599
+ }
566
600
567
- if ( CURSOR_COMMANDS . has ( operationName ) ) {
568
- // `find` creates a cursor, so we need to call `toArray` on it
569
- const cursor = obj [ operationName ] . apply ( obj , args ) ;
570
- opPromise = cursor . toArray ( ) ;
571
- } else {
572
- // wrap this in a `Promise.try` because some operations might throw
573
- opPromise = Promise . try ( ( ) => obj [ operationName ] . apply ( obj , args ) ) ;
601
+ if ( CURSOR_COMMANDS . has ( operationName ) ) {
602
+ // `find` creates a cursor, so we need to call `toArray` on it
603
+ const cursor = obj [ operationName ] . apply ( obj , args ) ;
604
+ opPromise = cursor . toArray ( ) ;
605
+ } else {
606
+ // wrap this in a `Promise.try` because some operations might throw
607
+ opPromise = Promise . try ( ( ) => obj [ operationName ] . apply ( obj , args ) ) ;
608
+ }
574
609
}
575
610
576
611
if ( operation . error ) {
0 commit comments