@@ -27,6 +27,10 @@ const DEBUG_ID_CODE_SNIPPET =
2727 'var _datadogDebugIds,_datadogDebugIdMeta;void 0===_datadogDebugIds&&(_datadogDebugIds={});try{var stack=(new Error).stack;stack&&(_datadogDebugIds[stack]="__datadog_debug_id_placeholder__",_datadogDebugIdMeta="datadog-debug-id-__datadog_debug_id_placeholder__")}catch(e){}' ;
2828
2929describe ( 'Datadog Metro Plugin' , ( ) => {
30+ afterEach ( ( ) => {
31+ jest . resetModules ( ) ;
32+ } ) ;
33+
3034 describe ( 'Datadog Metro Serializer' , ( ) => {
3135 test ( 'generates bundle and source map with UUID v5 Debug ID' , async ( ) => {
3236 const codeSnippetHash = createHash ( 'md5' ) ;
@@ -404,4 +408,254 @@ describe('Datadog Metro Plugin', () => {
404408 expect ( result . map ) . toBe ( '{"testMap":"test"}' ) ;
405409 } ) ;
406410 } ) ;
411+
412+ describe ( 'Import Utils' , ( ) => {
413+ test ( 'M getDefaultExport extracts the default export if it exists' , ( ) => {
414+ // GIVEN
415+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
416+ const getDefaultExport = require ( '../plugin/utils' )
417+ . getDefaultExport ;
418+
419+ const exampleModuleWithDefault = {
420+ default : 'default export' ,
421+ namedExport : 'named export'
422+ } ;
423+
424+ // WHEN
425+ const result = getDefaultExport ( exampleModuleWithDefault ) ;
426+
427+ // THEN
428+ expect ( result ) . toBe ( 'default export' ) ;
429+ } ) ;
430+
431+ test ( 'M getDefaultExport returns the module as it is if default does not exist' , ( ) => {
432+ // GIVEN
433+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
434+ const getDefaultExport = require ( '../plugin/utils' )
435+ . getDefaultExport ;
436+
437+ const exampleModule1 = {
438+ namedExport : 'named export'
439+ } ;
440+
441+ const exampleModule2 = 'just a string' ;
442+
443+ // WHEN
444+ const result1 = getDefaultExport ( exampleModule1 ) ;
445+ const result2 = getDefaultExport ( exampleModule2 ) ;
446+
447+ // THEN
448+ expect ( result1 ) . toEqual ( { namedExport : 'named export' } ) ;
449+ expect ( result2 ) . toBe ( 'just a string' ) ;
450+ } ) ;
451+
452+ test ( 'M getDefaultExport returns undefined if the module is null or undefined' , ( ) => {
453+ // GIVEN
454+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
455+ const getDefaultExport = require ( '../plugin/utils' )
456+ . getDefaultExport ;
457+
458+ const exampleModule1 = null ;
459+ const exampleModule2 = undefined ;
460+
461+ // WHEN
462+ const result1 = getDefaultExport ( exampleModule1 ) ;
463+ const result2 = getDefaultExport ( exampleModule2 ) ;
464+
465+ // THEN
466+ expect ( result1 ) . toBeUndefined ( ) ;
467+ expect ( result2 ) . toBeUndefined ( ) ;
468+ } ) ;
469+
470+ test ( 'M createCountingSet correctly imports function from metro/src when metro/private is not available' , ( ) => {
471+ // GIVEN
472+ jest . isolateModules ( ( ) => {
473+ // GIVEN
474+ jest . doMock ( 'metro/private/lib/CountingSet' , ( ) => {
475+ throw new Error ( 'Module not found' ) ;
476+ } ) ;
477+
478+ jest . doMock (
479+ 'metro/src/lib/CountingSet' ,
480+ ( ) => ( {
481+ default : class CountingSetMock {
482+ test : string = 'constructor_not_called' ;
483+ constructor ( ) {
484+ this . test = 'constructor_called' ;
485+ }
486+ }
487+ } ) ,
488+ { virtual : true }
489+ ) ;
490+
491+ // WHEN
492+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
493+ const utils = require ( '../plugin/utils' ) ;
494+ const createCountingSet = utils . getCreateCountingSetFunction ( ) ;
495+ const result = createCountingSet ( ) ;
496+
497+ // THEN
498+ expect ( result ) . toHaveProperty ( 'test' ) ;
499+ expect ( result . test ) . toBe ( 'constructor_called' ) ;
500+ } ) ;
501+ } ) ;
502+
503+ test ( 'M sourcemapString correctly imports function from metro/src when metro/private is not available' , ( ) => {
504+ // GIVEN
505+ jest . isolateModules ( ( ) => {
506+ // GIVEN
507+ jest . doMock (
508+ 'metro/private/DeltaBundler/Serializers/sourceMapString' ,
509+ ( ) => {
510+ throw new Error ( 'Module not found' ) ;
511+ }
512+ ) ;
513+
514+ jest . doMock (
515+ 'metro/src/DeltaBundler/Serializers/sourceMapString' ,
516+ ( ) => ( {
517+ default : (
518+ modules : unknown [ ] ,
519+ options : object
520+ ) : string =>
521+ `test-modules_length:${
522+ modules . length
523+ } ,options_keys:${ Object . keys ( options ) . length } `
524+ } ) ,
525+ { virtual : true }
526+ ) ;
527+
528+ // WHEN
529+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
530+ const utils = require ( '../plugin/utils' ) ;
531+ const metroSourceMapString = utils . getSourceMapStringFunction ( ) ;
532+ const result = metroSourceMapString ( [ { } , { } , { } ] , {
533+ excludeSource : true ,
534+ shouldAddToIgnoreList : ( ) => true
535+ } ) ;
536+
537+ // THEN
538+ expect ( result ) . toBe ( 'test-modules_length:3,options_keys:2' ) ;
539+ } ) ;
540+ } ) ;
541+
542+ test ( 'M sourcemapString returns the correct function when retrieved as named export' , ( ) => {
543+ // GIVEN
544+ jest . isolateModules ( ( ) => {
545+ // GIVEN
546+ jest . doMock (
547+ 'metro/private/DeltaBundler/Serializers/sourceMapString' ,
548+ ( ) => ( {
549+ sourceMapString : (
550+ modules : unknown [ ] ,
551+ options : object
552+ ) : string =>
553+ `test-modules_length:${
554+ modules . length
555+ } ,options_keys:${ Object . keys ( options ) . length } `
556+ } )
557+ ) ;
558+
559+ // WHEN
560+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
561+ const utils = require ( '../plugin/utils' ) ;
562+ const metroSourceMapString = utils . getSourceMapStringFunction ( ) ;
563+ const result = metroSourceMapString ( [ { } , { } , { } ] , {
564+ excludeSource : true ,
565+ shouldAddToIgnoreList : ( ) => true
566+ } ) ;
567+ // THEN
568+ expect ( result ) . toBe ( 'test-modules_length:3,options_keys:2' ) ;
569+ } ) ;
570+ } ) ;
571+
572+ test ( 'M sourcemapString returns the correct function when retrieved as default export' , ( ) => {
573+ // GIVEN
574+ jest . isolateModules ( ( ) => {
575+ // GIVEN
576+ jest . doMock (
577+ 'metro/private/DeltaBundler/Serializers/sourceMapString' ,
578+ ( ) => ( {
579+ default : (
580+ modules : unknown [ ] ,
581+ options : object
582+ ) : string =>
583+ `test-modules_length:${
584+ modules . length
585+ } ,options_keys:${ Object . keys ( options ) . length } `
586+ } )
587+ ) ;
588+
589+ // WHEN
590+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
591+ const utils = require ( '../plugin/utils' ) ;
592+ const metroSourceMapString = utils . getSourceMapStringFunction ( ) ;
593+ const result = metroSourceMapString ( [ { } , { } , { } ] , {
594+ excludeSource : true ,
595+ shouldAddToIgnoreList : ( ) => true
596+ } ) ;
597+ // THEN
598+ expect ( result ) . toBe ( 'test-modules_length:3,options_keys:2' ) ;
599+ } ) ;
600+ } ) ;
601+
602+ test ( 'M getBaseJSBundle correctly imports function from metro/src when metro/private is not available' , ( ) => {
603+ // GIVEN
604+ jest . isolateModules ( ( ) => {
605+ // GIVEN
606+ jest . doMock (
607+ 'metro/private/DeltaBundler/Serializers/baseJSBundle' ,
608+ ( ) => {
609+ throw new Error ( 'Module not found' ) ;
610+ }
611+ ) ;
612+
613+ jest . doMock (
614+ 'metro/src/DeltaBundler/Serializers/baseJSBundle' ,
615+ ( ) => ( ) => ( {
616+ test : 'ok'
617+ } ) ,
618+ { virtual : true }
619+ ) ;
620+
621+ // WHEN
622+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
623+ const utils = require ( '../plugin/utils' ) ;
624+ const baseJSBundle = utils . getBaseJSBundleFunction ( ) ;
625+ const result = baseJSBundle ( ) ;
626+
627+ // THEN
628+ expect ( result ) . toHaveProperty ( 'test' ) ;
629+ expect ( result . test ) . toBe ( 'ok' ) ;
630+ } ) ;
631+ } ) ;
632+
633+ test ( 'M getCountLines correctly imports function from metro/src when metro/private is not available' , ( ) => {
634+ // GIVEN
635+ jest . isolateModules ( ( ) => {
636+ // GIVEN
637+ jest . doMock ( 'metro/private/lib/countLines' , ( ) => {
638+ throw new Error ( 'Module not found' ) ;
639+ } ) ;
640+
641+ // Random int between 10 and 100 to ensure the mock is used
642+ const randomInt = Math . floor ( Math . random ( ) * 90 ) + 10 ;
643+
644+ jest . doMock (
645+ 'metro/src/lib/countLines' ,
646+ ( ) => ( str : string ) : number => str . length + randomInt ,
647+ { virtual : true }
648+ ) ;
649+
650+ // WHEN
651+ // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
652+ const utils = require ( '../plugin/utils' ) ;
653+ const getCountLines = utils . getCountLinesFunction ( ) ;
654+ const result = getCountLines ( 'test-string' ) ;
655+
656+ // THEN
657+ expect ( result ) . toBe ( 'test-string' . length + randomInt ) ;
658+ } ) ;
659+ } ) ;
660+ } ) ;
407661} ) ;
0 commit comments