1'use strict'; 2require('../common'); 3const assert = require('assert'); 4const path = require('path'); 5 6const failures = []; 7const backslashRE = /\\/g; 8 9const joinTests = [ 10 [ [path.posix.join, path.win32.join], 11 // Arguments result 12 [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], 13 [[], '.'], 14 [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], 15 [['/foo', '../../../bar'], '/bar'], 16 [['foo', '../../../bar'], '../../bar'], 17 [['foo/', '../../../bar'], '../../bar'], 18 [['foo/x', '../../../bar'], '../bar'], 19 [['foo/x', './bar'], 'foo/x/bar'], 20 [['foo/x/', './bar'], 'foo/x/bar'], 21 [['foo/x/', '.', 'bar'], 'foo/x/bar'], 22 [['./'], './'], 23 [['.', './'], './'], 24 [['.', '.', '.'], '.'], 25 [['.', './', '.'], '.'], 26 [['.', '/./', '.'], '.'], 27 [['.', '/////./', '.'], '.'], 28 [['.'], '.'], 29 [['', '.'], '.'], 30 [['', 'foo'], 'foo'], 31 [['foo', '/bar'], 'foo/bar'], 32 [['', '/foo'], '/foo'], 33 [['', '', '/foo'], '/foo'], 34 [['', '', 'foo'], 'foo'], 35 [['foo', ''], 'foo'], 36 [['foo/', ''], 'foo/'], 37 [['foo', '', '/bar'], 'foo/bar'], 38 [['./', '..', '/foo'], '../foo'], 39 [['./', '..', '..', '/foo'], '../../foo'], 40 [['.', '..', '..', '/foo'], '../../foo'], 41 [['', '..', '..', '/foo'], '../../foo'], 42 [['/'], '/'], 43 [['/', '.'], '/'], 44 [['/', '..'], '/'], 45 [['/', '..', '..'], '/'], 46 [[''], '.'], 47 [['', ''], '.'], 48 [[' /foo'], ' /foo'], 49 [[' ', 'foo'], ' /foo'], 50 [[' ', '.'], ' '], 51 [[' ', '/'], ' /'], 52 [[' ', ''], ' '], 53 [['/', 'foo'], '/foo'], 54 [['/', '/foo'], '/foo'], 55 [['/', '//foo'], '/foo'], 56 [['/', '', '/foo'], '/foo'], 57 [['', '/', 'foo'], '/foo'], 58 [['', '/', '/foo'], '/foo'], 59 ], 60 ], 61]; 62 63// Windows-specific join tests 64joinTests.push([ 65 path.win32.join, 66 joinTests[0][1].slice(0).concat( 67 [// Arguments result 68 // UNC path expected 69 [['//foo/bar'], '\\\\foo\\bar\\'], 70 [['\\/foo/bar'], '\\\\foo\\bar\\'], 71 [['\\\\foo/bar'], '\\\\foo\\bar\\'], 72 // UNC path expected - server and share separate 73 [['//foo', 'bar'], '\\\\foo\\bar\\'], 74 [['//foo/', 'bar'], '\\\\foo\\bar\\'], 75 [['//foo', '/bar'], '\\\\foo\\bar\\'], 76 // UNC path expected - questionable 77 [['//foo', '', 'bar'], '\\\\foo\\bar\\'], 78 [['//foo/', '', 'bar'], '\\\\foo\\bar\\'], 79 [['//foo/', '', '/bar'], '\\\\foo\\bar\\'], 80 // UNC path expected - even more questionable 81 [['', '//foo', 'bar'], '\\\\foo\\bar\\'], 82 [['', '//foo/', 'bar'], '\\\\foo\\bar\\'], 83 [['', '//foo/', '/bar'], '\\\\foo\\bar\\'], 84 // No UNC path expected (no double slash in first component) 85 [['\\', 'foo/bar'], '\\foo\\bar'], 86 [['\\', '/foo/bar'], '\\foo\\bar'], 87 [['', '/', '/foo/bar'], '\\foo\\bar'], 88 // No UNC path expected (no non-slashes in first component - 89 // questionable) 90 [['//', 'foo/bar'], '\\foo\\bar'], 91 [['//', '/foo/bar'], '\\foo\\bar'], 92 [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], 93 [['//'], '\\'], 94 // No UNC path expected (share name missing - questionable). 95 [['//foo'], '\\foo'], 96 [['//foo/'], '\\foo\\'], 97 [['//foo', '/'], '\\foo\\'], 98 [['//foo', '', '/'], '\\foo\\'], 99 // No UNC path expected (too many leading slashes - questionable) 100 [['///foo/bar'], '\\foo\\bar'], 101 [['////foo', 'bar'], '\\foo\\bar'], 102 [['\\\\\\/foo/bar'], '\\foo\\bar'], 103 // Drive-relative vs drive-absolute paths. This merely describes the 104 // status quo, rather than being obviously right 105 [['c:'], 'c:.'], 106 [['c:.'], 'c:.'], 107 [['c:', ''], 'c:.'], 108 [['', 'c:'], 'c:.'], 109 [['c:.', '/'], 'c:.\\'], 110 [['c:.', 'file'], 'c:file'], 111 [['c:', '/'], 'c:\\'], 112 [['c:', 'file'], 'c:\\file'], 113 ] 114 ), 115]); 116joinTests.forEach((test) => { 117 if (!Array.isArray(test[0])) 118 test[0] = [test[0]]; 119 test[0].forEach((join) => { 120 test[1].forEach((test) => { 121 const actual = join.apply(null, test[0]); 122 const expected = test[1]; 123 // For non-Windows specific tests with the Windows join(), we need to try 124 // replacing the slashes since the non-Windows specific tests' `expected` 125 // use forward slashes 126 let actualAlt; 127 let os; 128 if (join === path.win32.join) { 129 actualAlt = actual.replace(backslashRE, '/'); 130 os = 'win32'; 131 } else { 132 os = 'posix'; 133 } 134 if (actual !== expected && actualAlt !== expected) { 135 const delimiter = test[0].map(JSON.stringify).join(','); 136 const message = `path.${os}.join(${delimiter})\n expect=${ 137 JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; 138 failures.push(`\n${message}`); 139 } 140 }); 141 }); 142}); 143assert.strictEqual(failures.length, 0, failures.join('')); 144