@@ -12,6 +12,8 @@ var child_process = require('child_process');
12
12
var assert = require ( 'assert' ) ;
13
13
var fs = require ( 'fs' ) ;
14
14
var util = require ( 'util' ) ;
15
+ var path = require ( 'path' ) ;
16
+ const { pathToFileURL } = require ( 'url' ) ;
15
17
var bufferFrom = Buffer . from ;
16
18
const semver = require ( 'semver' ) ;
17
19
@@ -45,6 +47,17 @@ function stackFrameAtTest(sourceMapSupportInstalled = true) {
45
47
function stackFrameAtTrace ( fileRe ) {
46
48
return extension === 'mjs' ? `${ fileRe } ` : `Object\\.<anonymous> \\(${ fileRe } \\)` ;
47
49
}
50
+ /**
51
+ * Describe how the source path in a stack frame is expected to start.
52
+ * If generated module is ESM, node uses file:// URL, so we expect mapped original path to also be file:// to match
53
+ * On windows, when not doing file:// URIs, expect windows-style paths
54
+ */
55
+ function stackFramePathStartsWith ( ) {
56
+ if ( extension === 'mjs' ) return 'file:/' ;
57
+ // Escape backslashes since we are returning regexp syntax
58
+ return path . parse ( process . cwd ( ) ) . root . replace ( / \\ / g, '\\\\' ) ;
59
+ // this re \((?:.*[/\\])?
60
+ }
48
61
/**
49
62
* Tests were initially written as CJS with require() calls.
50
63
* We can support require() calls in MJS tests, too, as long as we create a require() function.
@@ -177,7 +190,6 @@ function rewriteExpectation(expected, generatedFilenameIn, generatedFilenameOut)
177
190
async function compareStackTrace ( sourceMap , source , expected ) {
178
191
const header = srcPrefix ( ) ;
179
192
// Check once with a separate source map
180
- // fs.writeFileSync(`.generated-${id}-separate.${extension}.map`, JSON.stringify({...JSON.parse(sourceMap.toString()), file: `.generated-${id}-separate.${extension}`}));
181
193
fs . writeFileSync ( `.generated-${ id } -separate.${ extension } .map` , sourceMap . toString ( ) ) ;
182
194
fs . writeFileSync ( `.generated-${ id } -separate.${ extension } ` , `${ header } ${ namedExportDeclaration ( ) } = function() {` +
183
195
source . join ( '\n' ) + `};//@ sourceMappingURL=.generated-${ id } -separate.${ extension } .map` ) ;
@@ -235,15 +247,15 @@ async function normalThrow() {
235
247
'throw new Error("test");'
236
248
] , [
237
249
'Error: test' ,
238
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
250
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
239
251
] ) ;
240
252
}
241
253
async function normalThrowWithoutSourceMapSupportInstalled ( ) {
242
254
await compareStackTrace ( sourceMapConstructors . createMultiLineSourceMap ( ) , [
243
255
'throw new Error("test");'
244
256
] , [
245
257
'Error: test' ,
246
- re `^ at ${ stackFrameAtTest ( false ) } \((?:.*[/\\])?\.generated-${ id } \.${ extension } :1:123\)$`
258
+ re `^ at ${ stackFrameAtTest ( false ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.generated-${ id } \.${ extension } :1:123\)$`
247
259
] ) ;
248
260
}
249
261
}
@@ -335,7 +347,7 @@ it('fs.readFileSync failure', async function() {
335
347
'}'
336
348
] , [
337
349
'Error: test' ,
338
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line7\.js:1007:107\)$`
350
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line7\.js:1007:107\)$`
339
351
] ) ;
340
352
} ) ;
341
353
@@ -348,8 +360,8 @@ it('throw inside function', async function() {
348
360
'foo();'
349
361
] , [
350
362
'Error: test' ,
351
- / ^ a t f o o \( ( ?: .* [ / \\ ] ) ? l i n e 2 \. j s : 1 0 0 2 : 1 0 2 \) $ / ,
352
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line4\.js:1004:104\)$`
363
+ re ` ^ at foo \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line2\.js:1002:102\)$` ,
364
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line4\.js:1004:104\)$`
353
365
] ) ;
354
366
} ) ;
355
367
@@ -364,9 +376,9 @@ it('throw inside function inside function', async function() {
364
376
'foo();'
365
377
] , [
366
378
'Error: test' ,
367
- / ^ a t b a r \( ( ?: .* [ / \\ ] ) ? l i n e 3 \. j s : 1 0 0 3 : 1 0 3 \) $ / ,
368
- / ^ a t f o o \( ( ?: .* [ / \\ ] ) ? l i n e 5 \. j s : 1 0 0 5 : 1 0 5 \) $ / ,
369
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line7\.js:1007:107\)$`
379
+ re ` ^ at bar \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line3\.js:1003:103\)$` ,
380
+ re ` ^ at foo \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line5\.js:1005:105\)$` ,
381
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line7\.js:1007:107\)$`
370
382
] ) ;
371
383
} ) ;
372
384
@@ -377,9 +389,9 @@ it('eval', async function() {
377
389
'Error: test' ,
378
390
379
391
// TODO
380
- / ^ a t e v a l \( e v a l a t ( < a n o n y m o u s > | e x p o r t s \. t e s t | t e s t ) \( ( ?: .* [ / \\ ] ) ? l i n e 1 \. j s : 1 0 0 1 : 1 0 1 \) / ,
392
+ re ` ^ at eval \(eval at (<anonymous>|exports\.test|test) \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line1\.js:1001:101\)` ,
381
393
382
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
394
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
383
395
] ) ;
384
396
} ) ;
385
397
@@ -388,9 +400,9 @@ it('eval inside eval', async function() {
388
400
'eval("eval(\'throw new Error(\\"test\\")\')");'
389
401
] , [
390
402
'Error: test' ,
391
- / ^ a t e v a l \( e v a l a t ( < a n o n y m o u s > | e x p o r t s \. t e s t | t e s t ) \( e v a l a t ( < a n o n y m o u s > | e x p o r t s \. t e s t | t e s t ) \( ( ?: .* [ / \\ ] ) ? l i n e 1 \. j s : 1 0 0 1 : 1 0 1 \) / ,
392
- / ^ a t e v a l \( e v a l a t ( < a n o n y m o u s > | e x p o r t s \. t e s t | t e s t ) \( ( ?: .* [ / \\ ] ) ? l i n e 1 \. j s : 1 0 0 1 : 1 0 1 \) / ,
393
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
403
+ re ` ^ at eval \(eval at (<anonymous>|exports\.test|test) \(eval at (<anonymous>|exports\.test|test) \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line1\.js:1001:101\)` ,
404
+ re ` ^ at eval \(eval at (<anonymous>|exports\.test|test) \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line1\.js:1001:101\)` ,
405
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
394
406
] ) ;
395
407
} ) ;
396
408
@@ -402,9 +414,9 @@ it('eval inside function', async function() {
402
414
'foo();'
403
415
] , [
404
416
'Error: test' ,
405
- / ^ a t e v a l \( e v a l a t f o o \( ( ?: .* [ / \\ ] ) ? l i n e 2 \. j s : 1 0 0 2 : 1 0 2 \) / ,
406
- / ^ a t f o o \( ( ?: .* [ / \\ ] ) ? l i n e 2 \. j s : 1 0 0 2 : 1 0 2 \) / ,
407
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line4\.js:1004:104\)$`
417
+ re ` ^ at eval \(eval at foo \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line2\.js:1002:102\)` ,
418
+ re ` ^ at foo \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line2\.js:1002:102\)` ,
419
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line4\.js:1004:104\)$`
408
420
] ) ;
409
421
} ) ;
410
422
@@ -414,7 +426,7 @@ it('eval with sourceURL', async function() {
414
426
] , [
415
427
'Error: test' ,
416
428
/ ^ a t e v a l \( s o u r c e U R L \. j s : 1 : 7 \) $ / ,
417
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
429
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
418
430
] ) ;
419
431
} ) ;
420
432
@@ -424,8 +436,8 @@ it('eval with sourceURL inside eval', async function() {
424
436
] , [
425
437
'Error: test' ,
426
438
/ ^ a t e v a l \( s o u r c e U R L \. j s : 1 : 7 \) $ / ,
427
- / ^ a t e v a l \( e v a l a t ( < a n o n y m o u s > | e x p o r t s .t e s t | t e s t ) \( ( ?: .* [ / \\ ] ) ? l i n e 1 \. j s : 1 0 0 1 : 1 0 1 \) / ,
428
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
439
+ re ` ^ at eval \(eval at (<anonymous>|exports.test|test) \(${ stackFramePathStartsWith ( ) } ( ?:.*[/\\])?line1\.js:1001:101\)` ,
440
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
429
441
] ) ;
430
442
} ) ;
431
443
@@ -452,7 +464,7 @@ it('throw with empty source map', async function() {
452
464
'throw new Error("test");'
453
465
] , [
454
466
'Error: test' ,
455
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?\.generated-${ id } .${ extension } :1:123\)$`
467
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.generated-${ id } .${ extension } :1:123\)$`
456
468
] ) ;
457
469
} ) ;
458
470
@@ -467,7 +479,7 @@ it('throw in Timeout with empty source map', function(done) {
467
479
' throw new Error("this is the error")' ,
468
480
/ ^ \^ $ / ,
469
481
'Error: this is the error' ,
470
- re `^ at ((null)|(Timeout))\._onTimeout \((?:.*[/\\])?.generated-${ id } \.${ extension } :3:11\)$`
482
+ re `^ at ((null)|(Timeout))\._onTimeout \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.generated-${ id } \.${ extension } :3:11\)$`
471
483
] ) ;
472
484
} ) ;
473
485
@@ -476,7 +488,7 @@ it('throw with source map with gap', async function() {
476
488
'throw new Error("test");'
477
489
] , [
478
490
'Error: test' ,
479
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?\.generated-${ id } \.${ extension } :1:123\)$`
491
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.generated-${ id } \.${ extension } :1:123\)$`
480
492
] ) ;
481
493
} ) ;
482
494
@@ -485,7 +497,7 @@ it('sourcesContent with data URL', async function() {
485
497
'throw new Error("test");'
486
498
] , [
487
499
'Error: test' ,
488
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?original-${ id } \.js:1001:5\)$`
500
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?original-${ id } \.js:1001:5\)$`
489
501
] ) ;
490
502
} ) ;
491
503
@@ -495,7 +507,7 @@ it('finds the last sourceMappingURL', async function() {
495
507
'throw new Error("test");'
496
508
] , [
497
509
'Error: test' ,
498
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?original-${ id } \.js:1002:5\)$`
510
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?original-${ id } \.js:1002:5\)$`
499
511
] ) ;
500
512
} ) ;
501
513
@@ -519,8 +531,8 @@ it('maps original name from source', async function() {
519
531
'foo();'
520
532
] , [
521
533
'Error: test' ,
522
- re `^ at myOriginalName \((?:.*[/\\])?\.original-${ id } .js:1000:11\)$` ,
523
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?\.original-${ id } .js:1002:2\)$`
534
+ re `^ at myOriginalName \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.original-${ id } .js:1000:11\)$` ,
535
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.original-${ id } .js:1002:2\)$`
524
536
] ) ;
525
537
} ) ;
526
538
@@ -536,7 +548,7 @@ it('default options', function(done) {
536
548
'this is the original code' ,
537
549
'^' ,
538
550
'Error: this is the error' ,
539
- re `^ at foo \((?:.*[/\\])?\.original-${ id } \.js:1:1\)$`
551
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.original-${ id } \.js:1:1\)$`
540
552
] ) ;
541
553
} ) ;
542
554
@@ -551,7 +563,7 @@ it('handleUncaughtExceptions is true', function(done) {
551
563
'this is the original code' ,
552
564
'^' ,
553
565
'Error: this is the error' ,
554
- re `^ at foo \((?:.*[/\\])?\.original-${ id } \.js:1:1\)$`
566
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?\.original-${ id } \.js:1:1\)$`
555
567
] ) ;
556
568
} ) ;
557
569
@@ -568,7 +580,7 @@ it('handleUncaughtExceptions is false', function(done) {
568
580
' ^' ,
569
581
570
582
'Error: this is the error' ,
571
- re `^ at foo \((?:.*[/\\])?.original-${ id } \.js:1:1\)$`
583
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.original-${ id } \.js:1:1\)$`
572
584
] ) ;
573
585
} ) ;
574
586
@@ -583,7 +595,7 @@ it('default options with empty source map', function(done) {
583
595
'function foo() { throw new Error("this is the error"); }' ,
584
596
' ^' ,
585
597
'Error: this is the error' ,
586
- re `^ at foo \((?:.*[/\\])?.generated-${ id } .${ extension } :2:24\)$`
598
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.generated-${ id } .${ extension } :2:24\)$`
587
599
] ) ;
588
600
} ) ;
589
601
@@ -598,7 +610,7 @@ it('default options with source map with gap', function(done) {
598
610
'function foo() { throw new Error("this is the error"); }' ,
599
611
' ^' ,
600
612
'Error: this is the error' ,
601
- re `^ at foo \((?:.*[/\\])?.generated-${ id } .${ extension } :2:24\)$`
613
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.generated-${ id } .${ extension } :2:24\)$`
602
614
] ) ;
603
615
} ) ;
604
616
@@ -629,7 +641,7 @@ it('sourcesContent', function(done) {
629
641
' line 2' ,
630
642
' ^' ,
631
643
'Error: this is the error' ,
632
- re `^ at foo \((?:.*[/\\])?original-${ id } \.js:1002:5\)$`
644
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?original-${ id } \.js:1002:5\)$`
633
645
] ) ;
634
646
} ) ;
635
647
@@ -652,14 +664,18 @@ it('missing source maps should also be cached', function(done) {
652
664
'process.nextTick(function() { console.log(count); });' ,
653
665
] , [
654
666
'Error: this is the error' ,
655
- re `^ at foo \((?:.*[/\\])?.generated-${ id } .${ extension } :4:15\)$` ,
667
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.generated-${ id } .${ extension } :4:15\)$` ,
656
668
'Error: this is the error' ,
657
- re `^ at foo \((?:.*[/\\])?.generated-${ id } .${ extension } :4:15\)$` ,
669
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.generated-${ id } .${ extension } :4:15\)$` ,
658
670
'1' , // The retrieval should only be attempted once
659
671
] ) ;
660
672
} ) ;
661
673
662
674
it ( 'should consult all retrieve source map providers' , function ( done ) {
675
+ // TODO are we supposed to be resolving this URL to absolute? Or should we test that non-absolute is supported?
676
+ // Test in vanilla source-map-support
677
+ let originalPath = path . resolve ( `.original-${ id } .js` ) ;
678
+ if ( extension === 'mjs' ) originalPath = pathToFileURL ( originalPath ) . toString ( ) ;
663
679
compareStdout ( done , createSingleLineSourceMap ( ) , [
664
680
'' ,
665
681
'var count = 0;' ,
@@ -676,7 +692,7 @@ it('should consult all retrieve source map providers', function(done) {
676
692
' retrieveSourceMap: function(name) {' ,
677
693
` if (/\\.generated-${ id } \\.${ extension } $/.test(name)) {` ,
678
694
' count++;' ,
679
- ' return ' + JSON . stringify ( { url : `.original- ${ id } .js` , map : createMultiLineSourceMapWithSourcesContent ( ) . toJSON ( ) } ) + ';' ,
695
+ ' return ' + JSON . stringify ( { url : originalPath , map : createMultiLineSourceMapWithSourcesContent ( ) . toJSON ( ) } ) + ';' ,
680
696
' }' ,
681
697
' }' ,
682
698
'});' ,
@@ -685,9 +701,9 @@ it('should consult all retrieve source map providers', function(done) {
685
701
'process.nextTick(function() { console.log(count); });' ,
686
702
] , [
687
703
'Error: this is the error' ,
688
- re `^ at foo \((?:.*[/\\])?original-${ id } \.js:1004:5\)$` ,
704
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?original-${ id } \.js:1004:5\)$` ,
689
705
'Error: this is the error' ,
690
- re `^ at foo \((?:.*[/\\])?original-${ id } \.js:1004:5\)$` ,
706
+ re `^ at foo \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?original-${ id } \.js:1004:5\)$` ,
691
707
'1' , // The retrieval should only be attempted once
692
708
] ) ;
693
709
} ) ;
@@ -728,13 +744,6 @@ it('should allow for runtime inline source maps', function(done) {
728
744
'0' , // The retrieval should only be attempted once
729
745
] ) ;
730
746
} ) ;
731
- // }
732
-
733
- // TODO should this suite also be inside the matrix?
734
- // describe('Other', function() {
735
- // Wrapped in a suite to preserve test execution order
736
- // const {createEmptySourceMap, createSingleLineSourceMap, createMultiLineSourceMap} = sourceMapCreators();
737
- // const extension = 'cjs';
738
747
739
748
/* The following test duplicates some of the code in
740
749
* `compareStackTrace` but appends a charset to the
@@ -745,7 +754,7 @@ it('finds source maps with charset specified', async function() {
745
754
var source = [ 'throw new Error("test");' ] ;
746
755
var expected = [
747
756
'Error: test' ,
748
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
757
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
749
758
] ;
750
759
751
760
fs . writeFileSync ( `.generated-${ id } .${ extension } ` , `${ namedExportDeclaration ( ) } = function() {` +
@@ -767,7 +776,7 @@ it('allows code/comments after sourceMappingURL', async function() {
767
776
var source = [ 'throw new Error("test");' ] ;
768
777
var expected = [
769
778
'Error: test' ,
770
- re `^ at ${ stackFrameAtTest ( ) } \((?:.*[/\\])?line1\.js:1001:101\)$`
779
+ re `^ at ${ stackFrameAtTest ( ) } \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?line1\.js:1001:101\)$`
771
780
] ;
772
781
773
782
fs . writeFileSync ( `.generated-${ id } .${ extension } ` , `${ namedExportDeclaration ( ) } = function() {` +
@@ -846,10 +855,9 @@ it('supports multiple instances', function(done) {
846
855
'this is some other original code' ,
847
856
'^' ,
848
857
'Error: this is the error' ,
849
- re `^ at test \((?:.*[/\\])?.original2-${ id } \.js:1:1\)$`
858
+ re `^ at test \(${ stackFramePathStartsWith ( ) } (?:.*[/\\])?.original2-${ id } \.js:1:1\)$`
850
859
] ) ;
851
860
} ) ;
852
- // });
853
861
}
854
862
855
863
describe ( 'redirects require() of "source-map-support" to this module' , function ( ) {
0 commit comments