1
1
package tspath
2
2
3
3
import (
4
+ "fmt"
4
5
"regexp"
5
6
"strings"
6
7
"testing"
@@ -377,6 +378,21 @@ func TestGetNormalizedAbsolutePath(t *testing.T) {
377
378
assert .Equal (t , GetNormalizedAbsolutePath ("/base/./a../b" , "" ), "/base/a../b" )
378
379
assert .Equal (t , GetNormalizedAbsolutePath ("/base/../a../b" , "" ), "/a../b" )
379
380
381
+ assert .Equal (t , GetNormalizedAbsolutePath ("a/.." , "" ), "" )
382
+ assert .Equal (t , GetNormalizedAbsolutePath ("/a//" , "" ), "/a" )
383
+ assert .Equal (t , GetNormalizedAbsolutePath ("//a" , "a" ), "//a/" )
384
+ assert .Equal (t , GetNormalizedAbsolutePath ("/\\ " , "" ), "//" )
385
+ assert .Equal (t , GetNormalizedAbsolutePath ("a///" , "a" ), "a/a" )
386
+ assert .Equal (t , GetNormalizedAbsolutePath ("/.//" , "" ), "/" )
387
+ assert .Equal (t , GetNormalizedAbsolutePath ("//\\ \\ " , "" ), "///" )
388
+ assert .Equal (t , GetNormalizedAbsolutePath (".//a" , "." ), "a" )
389
+ assert .Equal (t , GetNormalizedAbsolutePath ("a/../.." , "" ), ".." )
390
+ assert .Equal (t , GetNormalizedAbsolutePath ("../.." , "\\ a" ), "/" )
391
+ assert .Equal (t , GetNormalizedAbsolutePath ("a:" , "b" ), "a:/" )
392
+ assert .Equal (t , GetNormalizedAbsolutePath ("a/../.." , ".." ), "../.." )
393
+ assert .Equal (t , GetNormalizedAbsolutePath ("a/../.." , "b" ), "" )
394
+ assert .Equal (t , GetNormalizedAbsolutePath ("a//../.." , ".." ), "../.." )
395
+
380
396
// Consecutive intermediate slashes are normalized to a single slash.
381
397
assert .Equal (t , GetNormalizedAbsolutePath ("a//b" , "" ), "a/b" )
382
398
assert .Equal (t , GetNormalizedAbsolutePath ("a///b" , "" ), "a/b" )
@@ -401,6 +417,75 @@ func TestGetNormalizedAbsolutePath(t *testing.T) {
401
417
assert .Equal (t , GetNormalizedAbsolutePath ("\\ \\ a\\ b\\ \\ c" , "" ), "//a/b/c" )
402
418
}
403
419
420
+ var getNormalizedAbsolutePathTests = map [string ][][]string {
421
+ "non-normalized inputs" : {
422
+ {"/." , "" },
423
+ {"/./" , "" },
424
+ {"/../" , "" },
425
+ {"/a/" , "" },
426
+ {"/a/." , "" },
427
+ {"/a/foo." , "" },
428
+ {"/a/./" , "" },
429
+ {"/a/./b" , "" },
430
+ {"/a/./b/" , "" },
431
+ {"/a/.." , "" },
432
+ {"/a/../" , "" },
433
+ {"/a/../" , "" },
434
+ {"/a/../b" , "" },
435
+ {"/a/../b/" , "" },
436
+ {"/a/.." , "" },
437
+ {"/a/.." , "/" },
438
+ {"/a/.." , "b/" },
439
+ {"/a/.." , "/b" },
440
+ {"/a/." , "b" },
441
+ {"/a/." , "." },
442
+ },
443
+ "normalized inputs" : {
444
+ {"/a/b" , "" },
445
+ {"/one/two/three" , "" },
446
+ {"/users/root/project/src/foo.ts" , "" },
447
+ },
448
+ "normalized inputs (long)" : {
449
+ {"/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z" , "" },
450
+ {"/one/two/three/four/five/six/seven/eight/nine/ten/eleven/twelve/thirteen/fourteen/fifteen/sixteen/seventeen/eighteen/nineteen/twenty" , "" },
451
+ {"/users/root/project/src/foo/bar/baz/qux/quux/corge/grault/garply/waldo/fred/plugh/xyzzy/thud" , "" },
452
+ {"/lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/sed/do/eiusmod/tempor/incididunt/ut/labore/et/dolore/magna/aliqua/ut/enim/ad/minim/veniam" , "" },
453
+ },
454
+ }
455
+
456
+ func BenchmarkGetNormalizedAbsolutePath (b * testing.B ) {
457
+ funcs := map [string ]func (string , string ) string {
458
+ "GetNormalizedAbsolutePath" : GetNormalizedAbsolutePath ,
459
+ "GetNormalizedAbsolutePath (old)" : getNormalizedAbsolutePath_old ,
460
+ }
461
+ for name , tests := range getNormalizedAbsolutePathTests {
462
+ b .Run (name , func (b * testing.B ) {
463
+ for fnName , fn := range funcs {
464
+ b .Run (fnName , func (b * testing.B ) {
465
+ b .ReportAllocs ()
466
+ for _ , test := range tests {
467
+ for range b .N {
468
+ fn (test [0 ], test [1 ])
469
+ }
470
+ }
471
+ })
472
+ }
473
+ })
474
+ }
475
+ }
476
+
477
+ func FuzzGetNormalizedAbsolutePath (f * testing.F ) {
478
+ for _ , tests := range getNormalizedAbsolutePathTests {
479
+ for _ , test := range tests {
480
+ f .Add (test [0 ], test [1 ])
481
+ }
482
+ }
483
+
484
+ f .Fuzz (func (t * testing.T , p string , dir string ) {
485
+ assert .Equal (t , GetNormalizedAbsolutePath (p , dir ), getNormalizedAbsolutePath_old (p , dir ), fmt .Sprintf ("p=%q, dir=%q" , p , dir ))
486
+ })
487
+ }
488
+
404
489
func TestGetRelativePathToDirectoryOrUrl (t * testing.T ) {
405
490
t .Parallel ()
406
491
// !!!
@@ -594,3 +679,28 @@ func shortenName(name string) string {
594
679
}
595
680
return name
596
681
}
682
+
683
+ func normalizePath_old (path string ) string {
684
+ path = NormalizeSlashes (path )
685
+ // Most paths don't require normalization
686
+ if ! hasRelativePathSegment (path ) {
687
+ return path
688
+ }
689
+ // Some paths only require cleanup of `/./` or leading `./`
690
+ simplified := strings .ReplaceAll (path , "/./" , "/" )
691
+ simplified = strings .TrimPrefix (simplified , "./" )
692
+ if simplified != path && ! hasRelativePathSegment (simplified ) {
693
+ path = simplified
694
+ return path
695
+ }
696
+ // Other paths require full normalization
697
+ normalized := GetPathFromPathComponents (reducePathComponents (GetPathComponents (path , "" )))
698
+ if normalized != "" && HasTrailingDirectorySeparator (path ) {
699
+ normalized = EnsureTrailingDirectorySeparator (normalized )
700
+ }
701
+ return normalized
702
+ }
703
+
704
+ func getNormalizedAbsolutePath_old (fileName string , currentDirectory string ) string {
705
+ return GetPathFromPathComponents (GetNormalizedPathComponents (fileName , currentDirectory ))
706
+ }
0 commit comments