From a8f4db236cf4719c9c7446efe03afa136215ace6 Mon Sep 17 00:00:00 2001 From: Brian White Date: Fri, 5 Feb 2016 22:28:01 -0500 Subject: [PATCH] test: improve path tests This commit adds new tests, executes tests for other platforms instead of limiting platform-specific tests to those platforms, and fixes a few style/formatting inconsistencies. PR-URL: https://github.com/nodejs/node/pull/5123 Reviewed-By: Roman Reiss Reviewed-By: James M Snell --- test/parallel/test-path-parse-format.js | 73 ++- .../parallel/test-path-zero-length-strings.js | 12 +- test/parallel/test-path.js | 454 +++++++++++------- 3 files changed, 356 insertions(+), 183 deletions(-) diff --git a/test/parallel/test-path-parse-format.js b/test/parallel/test-path-parse-format.js index f635f7f010..c19573108e 100644 --- a/test/parallel/test-path-parse-format.js +++ b/test/parallel/test-path-parse-format.js @@ -35,7 +35,17 @@ var unixPaths = [ '.\\file', './file', 'C:\\foo', - '' + '/', + '', + '.', + '..', + '/foo', + '/foo.', + '/foo.bar', + '/.', + '/.foo', + '/.foo.bar', + '/foo/bar.baz', ]; var unixSpecialCaseFormatTests = [ @@ -76,6 +86,67 @@ checkErrors(path.posix); checkFormat(path.win32, winSpecialCaseFormatTests); checkFormat(path.posix, unixSpecialCaseFormatTests); +// Test removal of trailing path separators +const trailingTests = [ + [ path.win32.parse, + [['.\\', { root: '', dir: '', base: '.', ext: '', name: '.' }], + ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], + ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], + ['c:\\foo\\\\\\', + { root: 'c:\\', dir: 'c:\\', base: 'foo', ext: '', name: 'foo' }], + ['D:\\foo\\\\\\bar.baz', + { root: 'D:\\', + dir: 'D:\\foo\\\\', + base: 'bar.baz', + ext: '.baz', + name: 'bar' + } + ] + ] + ], + [ path.posix.parse, + [['./', { root: '', dir: '', base: '.', ext: '', name: '.' }], + ['//', { root: '/', dir: '/', base: '', ext: '', name: '' }], + ['///', { root: '/', dir: '/', base: '', ext: '', name: '' }], + ['/foo///', { root: '/', dir: '/', base: 'foo', ext: '', name: 'foo' }], + ['/foo///bar.baz', + { root: '/', dir: '/foo//', base: 'bar.baz', ext: '.baz', name: 'bar' } + ] + ] + ] +]; +const failures = []; +trailingTests.forEach(function(test) { + const parse = test[0]; + test[1].forEach(function(test) { + const actual = parse(test[0]); + const expected = test[1]; + const fn = 'path.' + + (parse === path.win32.parse ? 'win32' : 'posix') + + '.parse('; + const message = fn + + JSON.stringify(test[0]) + + ')' + + '\n expect=' + JSON.stringify(expected) + + '\n actual=' + JSON.stringify(actual); + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + let failed = (actualKeys.length !== expectedKeys.length); + if (!failed) { + for (let i = 0; i < actualKeys.length; ++i) { + const key = actualKeys[i]; + if (expectedKeys.indexOf(key) === -1 || actual[key] !== expected[key]) { + failed = true; + break; + } + } + } + if (failed) + failures.push('\n' + message); + }); +}); +assert.equal(failures.length, 0, failures.join('')); + function checkErrors(path) { errors.forEach(function(errorCase) { try { diff --git a/test/parallel/test-path-zero-length-strings.js b/test/parallel/test-path-zero-length-strings.js index 07de030aa0..b08ef48092 100644 --- a/test/parallel/test-path-zero-length-strings.js +++ b/test/parallel/test-path-zero-length-strings.js @@ -12,17 +12,21 @@ const pwd = process.cwd(); // join will internally ignore all the zero-length strings and it will return // '.' if the joined string is a zero-length string. -assert.equal(path.join(''), '.'); -assert.equal(path.join('', ''), '.'); +assert.equal(path.posix.join(''), '.'); +assert.equal(path.posix.join('', ''), '.'); +assert.equal(path.win32.join(''), '.'); +assert.equal(path.win32.join('', ''), '.'); assert.equal(path.join(pwd), pwd); assert.equal(path.join(pwd, ''), pwd); // normalize will return '.' if the input is a zero-length string -assert.equal(path.normalize(''), '.'); +assert.equal(path.posix.normalize(''), '.'); +assert.equal(path.win32.normalize(''), '.'); assert.equal(path.normalize(pwd), pwd); // Since '' is not a valid path in any of the common environments, return false -assert.equal(path.isAbsolute(''), false); +assert.equal(path.posix.isAbsolute(''), false); +assert.equal(path.win32.isAbsolute(''), false); // resolve, internally ignores all the zero-length strings and returns the // current working directory diff --git a/test/parallel/test-path.js b/test/parallel/test-path.js index e8c2820535..d9029a5d7c 100644 --- a/test/parallel/test-path.js +++ b/test/parallel/test-path.js @@ -1,11 +1,12 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); -var path = require('path'); - -var f = __filename; +const f = __filename; +const failures = []; +// path.basename tests assert.equal(path.basename(f), 'test-path.js'); assert.equal(path.basename(f, '.js'), 'test-path'); assert.equal(path.basename(''), ''); @@ -31,22 +32,21 @@ assert.equal(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\'); // POSIX filenames may include control characters // c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html -if (!common.isWindows) { - var controlCharFilename = 'Icon' + String.fromCharCode(13); - assert.equal(path.basename('/a/b/' + controlCharFilename), - controlCharFilename); -} +const controlCharFilename = 'Icon' + String.fromCharCode(13); +assert.equal(path.posix.basename('/a/b/' + controlCharFilename), + controlCharFilename); -assert.equal(path.extname(f), '.js'); +// path.dirname tests assert.equal(path.dirname(f).substr(-13), common.isWindows ? 'test\\parallel' : 'test/parallel'); -assert.equal(path.dirname('/a/b/'), '/a'); -assert.equal(path.dirname('/a/b'), '/a'); -assert.equal(path.dirname('/a'), '/'); -assert.equal(path.dirname(''), '.'); -assert.equal(path.dirname('/'), '/'); -assert.equal(path.dirname('////'), '/'); + +assert.equal(path.posix.dirname('/a/b/'), '/a'); +assert.equal(path.posix.dirname('/a/b'), '/a'); +assert.equal(path.posix.dirname('/a'), '/'); +assert.equal(path.posix.dirname(''), '.'); +assert.equal(path.posix.dirname('/'), '/'); +assert.equal(path.posix.dirname('////'), '/'); assert.equal(path.win32.dirname('c:\\'), 'c:\\'); assert.equal(path.win32.dirname('c:\\foo'), 'c:\\'); @@ -75,51 +75,79 @@ assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'), '\\\\unc\\share\\foo'); assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'), '\\\\unc\\share\\foo\\bar'); +assert.equal(path.win32.dirname('/a/b/'), '/a'); +assert.equal(path.win32.dirname('/a/b'), '/a'); +assert.equal(path.win32.dirname('/a'), '/'); +assert.equal(path.win32.dirname(''), '.'); +assert.equal(path.win32.dirname('/'), '/'); +assert.equal(path.win32.dirname('////'), '/'); + + +// path.extname tests +[ + [f, '.js'], + ['', ''], + ['/path/to/file', ''], + ['/path/to/file.ext', '.ext'], + ['/path.to/file.ext', '.ext'], + ['/path.to/file', ''], + ['/path.to/.file', ''], + ['/path.to/.file.ext', '.ext'], + ['/path/to/f.ext', '.ext'], + ['/path/to/..ext', '.ext'], + ['/path/to/..', ''], + ['file', ''], + ['file.ext', '.ext'], + ['.file', ''], + ['.file.ext', '.ext'], + ['/file', ''], + ['/file.ext', '.ext'], + ['/.file', ''], + ['/.file.ext', '.ext'], + ['.path/file.ext', '.ext'], + ['file.ext.ext', '.ext'], + ['file.', '.'], + ['.', ''], + ['./', ''], + ['.file.ext', '.ext'], + ['.file', ''], + ['.file.', '.'], + ['.file..', '.'], + ['..', ''], + ['../', ''], + ['..file.ext', '.ext'], + ['..file', '.file'], + ['..file.', '.'], + ['..file..', '.'], + ['...', '.'], + ['...ext', '.ext'], + ['....', '.'], + ['file.ext/', '.ext'], + ['file.ext//', '.ext'], + ['file/', ''], + ['file//', ''], + ['file./', '.'], + ['file.//', '.'], +].forEach(function(test) { + [path.posix.extname, path.win32.extname].forEach(function(extname) { + let input = test[0]; + if (extname === path.win32.extname) + input = input.replace(/\//g, '\\'); + const actual = extname(input); + const expected = test[1]; + const fn = 'path.' + + (extname === path.win32.extname ? 'win32' : 'posix') + + '.extname('; + const message = fn + JSON.stringify(input) + ')' + + '\n expect=' + JSON.stringify(expected) + + '\n actual=' + JSON.stringify(actual); + if (actual !== expected) + failures.push('\n' + message); + }); +}); +assert.equal(failures.length, 0, failures.join('')); - -assert.equal(path.extname(''), ''); -assert.equal(path.extname('/path/to/file'), ''); -assert.equal(path.extname('/path/to/file.ext'), '.ext'); -assert.equal(path.extname('/path.to/file.ext'), '.ext'); -assert.equal(path.extname('/path.to/file'), ''); -assert.equal(path.extname('/path.to/.file'), ''); -assert.equal(path.extname('/path.to/.file.ext'), '.ext'); -assert.equal(path.extname('/path/to/f.ext'), '.ext'); -assert.equal(path.extname('/path/to/..ext'), '.ext'); -assert.equal(path.extname('file'), ''); -assert.equal(path.extname('file.ext'), '.ext'); -assert.equal(path.extname('.file'), ''); -assert.equal(path.extname('.file.ext'), '.ext'); -assert.equal(path.extname('/file'), ''); -assert.equal(path.extname('/file.ext'), '.ext'); -assert.equal(path.extname('/.file'), ''); -assert.equal(path.extname('/.file.ext'), '.ext'); -assert.equal(path.extname('.path/file.ext'), '.ext'); -assert.equal(path.extname('file.ext.ext'), '.ext'); -assert.equal(path.extname('file.'), '.'); -assert.equal(path.extname('.'), ''); -assert.equal(path.extname('./'), ''); -assert.equal(path.extname('.file.ext'), '.ext'); -assert.equal(path.extname('.file'), ''); -assert.equal(path.extname('.file.'), '.'); -assert.equal(path.extname('.file..'), '.'); -assert.equal(path.extname('..'), ''); -assert.equal(path.extname('../'), ''); -assert.equal(path.extname('..file.ext'), '.ext'); -assert.equal(path.extname('..file'), '.file'); -assert.equal(path.extname('..file.'), '.'); -assert.equal(path.extname('..file..'), '.'); -assert.equal(path.extname('...'), '.'); -assert.equal(path.extname('...ext'), '.ext'); -assert.equal(path.extname('....'), '.'); -assert.equal(path.extname('file.ext/'), '.ext'); -assert.equal(path.extname('file.ext//'), '.ext'); -assert.equal(path.extname('file/'), ''); -assert.equal(path.extname('file//'), ''); -assert.equal(path.extname('file./'), '.'); -assert.equal(path.extname('file.//'), '.'); - -// On windows, backspace is a path separator. +// On Windows, backslash is a path separator. assert.equal(path.win32.extname('.\\'), ''); assert.equal(path.win32.extname('..\\'), ''); assert.equal(path.win32.extname('file.ext\\'), '.ext'); @@ -129,7 +157,7 @@ assert.equal(path.win32.extname('file\\\\'), ''); assert.equal(path.win32.extname('file.\\'), '.'); assert.equal(path.win32.extname('file.\\\\'), '.'); -// On unix, backspace is a valid name component like any other character. +// On *nix, backslash is a valid name component like any other character. assert.equal(path.posix.extname('.\\'), ''); assert.equal(path.posix.extname('..\\'), '.\\'); assert.equal(path.posix.extname('file.ext\\'), '.ext\\'); @@ -139,9 +167,10 @@ assert.equal(path.posix.extname('file\\\\'), ''); assert.equal(path.posix.extname('file.\\'), '.\\'); assert.equal(path.posix.extname('file.\\\\'), '.\\\\'); + // path.join tests -var failures = []; -var joinTests = +const joinTests = [ + [ [path.posix.join, path.win32.join], // arguments result [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], @@ -189,70 +218,90 @@ var joinTests = [['/', '', '/foo'], '/foo'], [['', '/', 'foo'], '/foo'], [['', '/', '/foo'], '/foo'] - ]; + ] + ] +]; // Windows-specific join tests -if (common.isWindows) { - joinTests = joinTests.concat( - [// UNC path expected - [['//foo/bar'], '//foo/bar/'], - [['\\/foo/bar'], '//foo/bar/'], - [['\\\\foo/bar'], '//foo/bar/'], +joinTests.push([ + path.win32.join, + joinTests[0][1].slice(0).concat( + [// arguments result + // UNC path expected + [['//foo/bar'], '\\\\foo\\bar\\'], + [['\\/foo/bar'], '\\\\foo\\bar\\'], + [['\\\\foo/bar'], '\\\\foo\\bar\\'], // UNC path expected - server and share separate - [['//foo', 'bar'], '//foo/bar/'], - [['//foo/', 'bar'], '//foo/bar/'], - [['//foo', '/bar'], '//foo/bar/'], + [['//foo', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', 'bar'], '\\\\foo\\bar\\'], + [['//foo', '/bar'], '\\\\foo\\bar\\'], // UNC path expected - questionable - [['//foo', '', 'bar'], '//foo/bar/'], - [['//foo/', '', 'bar'], '//foo/bar/'], - [['//foo/', '', '/bar'], '//foo/bar/'], + [['//foo', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', '/bar'], '\\\\foo\\bar\\'], // UNC path expected - even more questionable - [['', '//foo', 'bar'], '//foo/bar/'], - [['', '//foo/', 'bar'], '//foo/bar/'], - [['', '//foo/', '/bar'], '//foo/bar/'], + [['', '//foo', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', '/bar'], '\\\\foo\\bar\\'], // No UNC path expected (no double slash in first component) - [['\\', 'foo/bar'], '/foo/bar'], - [['\\', '/foo/bar'], '/foo/bar'], - [['', '/', '/foo/bar'], '/foo/bar'], - // No UNC path expected (no non-slashes in first component - questionable) - [['//', 'foo/bar'], '/foo/bar'], - [['//', '/foo/bar'], '/foo/bar'], - [['\\\\', '/', '/foo/bar'], '/foo/bar'], + [['\\', 'foo/bar'], '\\foo\\bar'], + [['\\', '/foo/bar'], '\\foo\\bar'], + [['', '/', '/foo/bar'], '\\foo\\bar'], + // No UNC path expected (no non-slashes in first component - + // questionable) + [['//', 'foo/bar'], '\\foo\\bar'], + [['//', '/foo/bar'], '\\foo\\bar'], + [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], [['//'], '/'], // No UNC path expected (share name missing - questionable). - [['//foo'], '/foo'], - [['//foo/'], '/foo/'], - [['//foo', '/'], '/foo/'], - [['//foo', '', '/'], '/foo/'], + [['//foo'], '\\foo'], + [['//foo/'], '\\foo\\'], + [['//foo', '/'], '\\foo\\'], + [['//foo', '', '/'], '\\foo\\'], // No UNC path expected (too many leading slashes - questionable) - [['///foo/bar'], '/foo/bar'], - [['////foo', 'bar'], '/foo/bar'], - [['\\\\\\/foo/bar'], '/foo/bar'], + [['///foo/bar'], '\\foo\\bar'], + [['////foo', 'bar'], '\\foo\\bar'], + [['\\\\\\/foo/bar'], '\\foo\\bar'], // Drive-relative vs drive-absolute paths. This merely describes the // status quo, rather than being obviously right [['c:'], 'c:.'], [['c:.'], 'c:.'], [['c:', ''], 'c:.'], [['', 'c:'], 'c:.'], - [['c:.', '/'], 'c:./'], + [['c:.', '/'], 'c:.\\'], [['c:.', 'file'], 'c:file'], - [['c:', '/'], 'c:/'], - [['c:', 'file'], 'c:/file'] - ]); -} - -// Run the join tests. + [['c:', '/'], 'c:\\'], + [['c:', 'file'], 'c:\\file'] + ] + ) +]); joinTests.forEach(function(test) { - var actual = path.join.apply(path, test[0]); - var expected = common.isWindows ? test[1].replace(/\//g, '\\') : test[1]; - var message = 'path.join(' + test[0].map(JSON.stringify).join(',') + ')' + - '\n expect=' + JSON.stringify(expected) + - '\n actual=' + JSON.stringify(actual); - if (actual !== expected) failures.push('\n' + message); - // assert.equal(actual, expected, message); + if (!Array.isArray(test[0])) + test[0] = [test[0]]; + test[0].forEach(function(join) { + test[1].forEach(function(test) { + const actual = join.apply(null, test[0]); + const expected = test[1]; + let actualAlt; + // For non-Windows specific tests with the Windows join(), we need to try + // replacing the slashes since the non-Windows specific tests' `expected` + // use forward slashes + if (join === path.win32.join) + actualAlt = actual.replace(/\\/g, '/'); + const fn = 'path.' + + (join === path.win32.join ? 'win32' : 'posix') + + '.join('; + const message = fn + test[0].map(JSON.stringify).join(',') + ')' + + '\n expect=' + JSON.stringify(expected) + + '\n actual=' + JSON.stringify(actual); + if (actual !== expected && actualAlt !== expected) + failures.push('\n' + message); + }); + }); }); assert.equal(failures.length, 0, failures.join('')); + // Test thrown TypeErrors var typeErrorTests = [true, false, 7, null, {}, undefined, [], NaN]; @@ -286,7 +335,7 @@ typeErrorTests.forEach(function(test) { }); -// path normalize tests +// path.normalize tests assert.equal(path.win32.normalize('./fixtures///b/../b/c.js'), 'fixtures\\b\\c.js'); assert.equal(path.win32.normalize('/foo/../../../bar'), '\\bar'); @@ -303,46 +352,60 @@ assert.equal(path.posix.normalize('a//b//../b'), 'a/b'); assert.equal(path.posix.normalize('a//b//./c'), 'a/b/c'); assert.equal(path.posix.normalize('a//b//.'), 'a/b'); + // path.resolve tests -var resolveTests; -if (common.isWindows) { - // windows - resolveTests = - // arguments result - [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], - [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], - [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], - [['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'], - [['.'], process.cwd()], - [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'], - [['c:/', '//'], 'c:\\'], - [['c:/', '//dir'], 'c:\\dir'], - [['c:/', '//server/share'], '\\\\server\\share\\'], - [['c:/', '//server//share'], '\\\\server\\share\\'], - [['c:/', '///some//dir'], 'c:\\some\\dir'] - ]; -} else { - // Posix - resolveTests = - // arguments result - [[['/var/lib', '../', 'file/'], '/var/file'], - [['/var/lib', '/../', 'file/'], '/file'], - [['a/b/c/', '../../..'], process.cwd()], - [['.'], process.cwd()], - [['/some/dir', '.', '/absolute/'], '/absolute']]; -} -failures = []; +const resolveTests = [ + [ path.win32.resolve, + // arguments result + [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], + [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], + [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], + [['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'], + [['.'], process.cwd()], + [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'], + [['c:/', '//'], 'c:\\'], + [['c:/', '//dir'], 'c:\\dir'], + [['c:/', '//server/share'], '\\\\server\\share\\'], + [['c:/', '//server//share'], '\\\\server\\share\\'], + [['c:/', '///some//dir'], 'c:\\some\\dir'], + [['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'], + 'C:\\foo\\tmp.3\\cycles\\root.js'] + ] + ], + [ path.posix.resolve, + // arguments result + [[['/var/lib', '../', 'file/'], '/var/file'], + [['/var/lib', '/../', 'file/'], '/file'], + [['a/b/c/', '../../..'], process.cwd()], + [['.'], process.cwd()], + [['/some/dir', '.', '/absolute/'], '/absolute'], + [['/foo/tmp.3/', '../tmp.3/cycles/root.js'], '/foo/tmp.3/cycles/root.js'] + ] + ] +]; resolveTests.forEach(function(test) { - var actual = path.resolve.apply(path, test[0]); - var expected = test[1]; - var message = 'path.resolve(' + test[0].map(JSON.stringify).join(',') + ')' + - '\n expect=' + JSON.stringify(expected) + - '\n actual=' + JSON.stringify(actual); - if (actual !== expected) failures.push('\n' + message); - // assert.equal(actual, expected, message); + const resolve = test[0]; + test[1].forEach(function(test) { + const actual = resolve.apply(null, test[0]); + let actualAlt; + if (resolve === path.win32.resolve && !common.isWindows) + actualAlt = actual.replace(/\\/g, '/'); + else if (resolve !== path.win32.resolve && common.isWindows) + actualAlt = actual.replace(/\//g, '\\'); + const expected = test[1]; + const fn = 'path.' + + (resolve === path.win32.resolve ? 'win32' : 'posix') + + '.resolve('; + const message = fn + test[0].map(JSON.stringify).join(',') + ')' + + '\n expect=' + JSON.stringify(expected) + + '\n actual=' + JSON.stringify(actual); + if (actual !== expected && actualAlt !== expected) + failures.push('\n' + message); + }); }); assert.equal(failures.length, 0, failures.join('')); + // path.isAbsolute tests assert.equal(path.win32.isAbsolute('//server/file'), true); assert.equal(path.win32.isAbsolute('\\\\server\\file'), true); @@ -358,44 +421,58 @@ assert.equal(path.posix.isAbsolute('/home/foo/..'), true); assert.equal(path.posix.isAbsolute('bar/'), false); assert.equal(path.posix.isAbsolute('./baz'), false); + // path.relative tests -var relativeTests; -if (common.isWindows) { - // windows - relativeTests = - // arguments result - [['c:/blah\\blah', 'd:/games', 'd:\\games'], - ['c:/aaaa/bbbb', 'c:/aaaa', '..'], - ['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'], - ['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''], - ['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'], - ['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'], - ['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'], - ['c:/aaaa/bbbb', 'd:\\', 'd:\\']]; -} else { - // posix - relativeTests = - // arguments result - [['/var/lib', '/var', '..'], - ['/var/lib', '/bin', '../../bin'], - ['/var/lib', '/var/lib', ''], - ['/var/lib', '/var/apache', '../apache'], - ['/var/', '/var/lib', 'lib'], - ['/', '/var/lib', 'var/lib']]; -} -failures = []; +const relativeTests = [ + [ path.win32.relative, + // arguments result + [['c:/blah\\blah', 'd:/games', 'd:\\games'], + ['c:/aaaa/bbbb', 'c:/aaaa', '..'], + ['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'], + ['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'], + ['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'], + ['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'], + ['c:/aaaa/bbbb', 'd:\\', 'd:\\'], + ['c:/AaAa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaaa/', 'c:/aaaa/cccc', '..\\aaaa\\cccc'], + ['C:\\foo\\bar\\baz\\quux', 'C:\\', '..\\..\\..\\..'], + ['C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json', 'bar\\package.json'] + ] + ], + [ path.posix.relative, + // arguments result + [['/var/lib', '/var', '..'], + ['/var/lib', '/bin', '../../bin'], + ['/var/lib', '/var/lib', ''], + ['/var/lib', '/var/apache', '../apache'], + ['/var/', '/var/lib', 'lib'], + ['/', '/var/lib', 'var/lib'], + ['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'] + ] + ] +]; relativeTests.forEach(function(test) { - var actual = path.relative(test[0], test[1]); - var expected = test[2]; - var message = 'path.relative(' + - test.slice(0, 2).map(JSON.stringify).join(',') + - ')' + - '\n expect=' + JSON.stringify(expected) + - '\n actual=' + JSON.stringify(actual); - if (actual !== expected) failures.push('\n' + message); + const relative = test[0]; + test[1].forEach(function(test) { + const actual = relative(test[0], test[1]); + const expected = test[2]; + const fn = 'path.' + + (relative === path.win32.relative ? 'win32' : 'posix') + + '.relative('; + const message = fn + + test.slice(0, 2).map(JSON.stringify).join(',') + + ')' + + '\n expect=' + JSON.stringify(expected) + + '\n actual=' + JSON.stringify(actual); + if (actual !== expected) + failures.push('\n' + message); + }); }); assert.equal(failures.length, 0, failures.join('')); + +// path.sep tests // windows assert.equal(path.win32.sep, '\\'); // posix @@ -404,11 +481,32 @@ assert.equal(path.posix.sep, '/'); // path.delimiter tests // windows assert.equal(path.win32.delimiter, ';'); - // posix assert.equal(path.posix.delimiter, ':'); +// path._makeLong tests +assert.equal(path.posix._makeLong('/foo/bar'), '/foo/bar'); +assert.equal(path.posix._makeLong('foo/bar'), 'foo/bar'); +if (common.isWindows) { + // These tests cause resolve() to insert the cwd, so we cannot test them from + // non-Windows platforms (easily) + assert.equal(path.win32._makeLong('foo\\bar').toLowerCase(), + '\\\\?\\' + process.cwd().toLowerCase() + '\\foo\\bar'); + assert.equal(path.win32._makeLong('foo/bar').toLowerCase(), + '\\\\?\\' + process.cwd().toLowerCase() + '\\foo\\bar'); + assert.equal(path.win32._makeLong('C:').toLowerCase(), + '\\\\?\\' + process.cwd().toLowerCase()); + assert.equal(path.win32._makeLong('C').toLowerCase(), + '\\\\?\\' + process.cwd().toLowerCase() + '\\c'); +} +assert.equal(path.win32._makeLong('C:\\foo'), '\\\\?\\C:\\foo'); +assert.equal(path.win32._makeLong('C:/foo'), '\\\\?\\C:\\foo'); +assert.equal(path.win32._makeLong('\\\\foo\\bar'), '\\\\?\\UNC\\foo\\bar\\'); +assert.equal(path.win32._makeLong('//foo//bar'), '\\\\?\\UNC\\foo\\bar\\'); +assert.equal(path.win32._makeLong('\\\\?\\foo'), '\\\\?\\foo'); + + if (common.isWindows) assert.deepEqual(path, path.win32, 'should be win32 path module'); else