11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors. 21cb0ef41Sopenharmony_ci// 31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a 41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the 51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including 61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish, 71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit 81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the 91cb0ef41Sopenharmony_ci// following conditions: 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included 121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software. 131cb0ef41Sopenharmony_ci// 141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE. 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci'use strict'; 231cb0ef41Sopenharmony_ciconst common = require('../common'); 241cb0ef41Sopenharmony_ciconst assert = require('assert'); 251cb0ef41Sopenharmony_ciconst path = require('path'); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciconst winPaths = [ 281cb0ef41Sopenharmony_ci // [path, root] 291cb0ef41Sopenharmony_ci ['C:\\path\\dir\\index.html', 'C:\\'], 301cb0ef41Sopenharmony_ci ['C:\\another_path\\DIR\\1\\2\\33\\\\index', 'C:\\'], 311cb0ef41Sopenharmony_ci ['another_path\\DIR with spaces\\1\\2\\33\\index', ''], 321cb0ef41Sopenharmony_ci ['\\', '\\'], 331cb0ef41Sopenharmony_ci ['\\foo\\C:', '\\'], 341cb0ef41Sopenharmony_ci ['file', ''], 351cb0ef41Sopenharmony_ci ['file:stream', ''], 361cb0ef41Sopenharmony_ci ['.\\file', ''], 371cb0ef41Sopenharmony_ci ['C:', 'C:'], 381cb0ef41Sopenharmony_ci ['C:.', 'C:'], 391cb0ef41Sopenharmony_ci ['C:..', 'C:'], 401cb0ef41Sopenharmony_ci ['C:abc', 'C:'], 411cb0ef41Sopenharmony_ci ['C:\\', 'C:\\'], 421cb0ef41Sopenharmony_ci ['C:\\abc', 'C:\\' ], 431cb0ef41Sopenharmony_ci ['', ''], 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // unc 461cb0ef41Sopenharmony_ci ['\\\\server\\share\\file_path', '\\\\server\\share\\'], 471cb0ef41Sopenharmony_ci ['\\\\server two\\shared folder\\file path.zip', 481cb0ef41Sopenharmony_ci '\\\\server two\\shared folder\\'], 491cb0ef41Sopenharmony_ci ['\\\\teela\\admin$\\system32', '\\\\teela\\admin$\\'], 501cb0ef41Sopenharmony_ci ['\\\\?\\UNC\\server\\share', '\\\\?\\UNC\\'], 511cb0ef41Sopenharmony_ci]; 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciconst winSpecialCaseParseTests = [ 541cb0ef41Sopenharmony_ci ['t', { base: 't', name: 't', root: '', dir: '', ext: '' }], 551cb0ef41Sopenharmony_ci ['/foo/bar', { root: '/', dir: '/foo', base: 'bar', ext: '', name: 'bar' }], 561cb0ef41Sopenharmony_ci]; 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ciconst winSpecialCaseFormatTests = [ 591cb0ef41Sopenharmony_ci [{ dir: 'some\\dir' }, 'some\\dir\\'], 601cb0ef41Sopenharmony_ci [{ base: 'index.html' }, 'index.html'], 611cb0ef41Sopenharmony_ci [{ root: 'C:\\' }, 'C:\\'], 621cb0ef41Sopenharmony_ci [{ name: 'index', ext: '.html' }, 'index.html'], 631cb0ef41Sopenharmony_ci [{ dir: 'some\\dir', name: 'index', ext: '.html' }, 'some\\dir\\index.html'], 641cb0ef41Sopenharmony_ci [{ root: 'C:\\', name: 'index', ext: '.html' }, 'C:\\index.html'], 651cb0ef41Sopenharmony_ci [{}, ''], 661cb0ef41Sopenharmony_ci]; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ciconst unixPaths = [ 691cb0ef41Sopenharmony_ci // [path, root] 701cb0ef41Sopenharmony_ci ['/home/user/dir/file.txt', '/'], 711cb0ef41Sopenharmony_ci ['/home/user/a dir/another File.zip', '/'], 721cb0ef41Sopenharmony_ci ['/home/user/a dir//another&File.', '/'], 731cb0ef41Sopenharmony_ci ['/home/user/a$$$dir//another File.zip', '/'], 741cb0ef41Sopenharmony_ci ['user/dir/another File.zip', ''], 751cb0ef41Sopenharmony_ci ['file', ''], 761cb0ef41Sopenharmony_ci ['.\\file', ''], 771cb0ef41Sopenharmony_ci ['./file', ''], 781cb0ef41Sopenharmony_ci ['C:\\foo', ''], 791cb0ef41Sopenharmony_ci ['/', '/'], 801cb0ef41Sopenharmony_ci ['', ''], 811cb0ef41Sopenharmony_ci ['.', ''], 821cb0ef41Sopenharmony_ci ['..', ''], 831cb0ef41Sopenharmony_ci ['/foo', '/'], 841cb0ef41Sopenharmony_ci ['/foo.', '/'], 851cb0ef41Sopenharmony_ci ['/foo.bar', '/'], 861cb0ef41Sopenharmony_ci ['/.', '/'], 871cb0ef41Sopenharmony_ci ['/.foo', '/'], 881cb0ef41Sopenharmony_ci ['/.foo.bar', '/'], 891cb0ef41Sopenharmony_ci ['/foo/bar.baz', '/'], 901cb0ef41Sopenharmony_ci]; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ciconst unixSpecialCaseFormatTests = [ 931cb0ef41Sopenharmony_ci [{ dir: 'some/dir' }, 'some/dir/'], 941cb0ef41Sopenharmony_ci [{ base: 'index.html' }, 'index.html'], 951cb0ef41Sopenharmony_ci [{ root: '/' }, '/'], 961cb0ef41Sopenharmony_ci [{ name: 'index', ext: '.html' }, 'index.html'], 971cb0ef41Sopenharmony_ci [{ dir: 'some/dir', name: 'index', ext: '.html' }, 'some/dir/index.html'], 981cb0ef41Sopenharmony_ci [{ root: '/', name: 'index', ext: '.html' }, '/index.html'], 991cb0ef41Sopenharmony_ci [{}, ''], 1001cb0ef41Sopenharmony_ci]; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ciconst errors = [ 1031cb0ef41Sopenharmony_ci { method: 'parse', input: [null] }, 1041cb0ef41Sopenharmony_ci { method: 'parse', input: [{}] }, 1051cb0ef41Sopenharmony_ci { method: 'parse', input: [true] }, 1061cb0ef41Sopenharmony_ci { method: 'parse', input: [1] }, 1071cb0ef41Sopenharmony_ci { method: 'parse', input: [] }, 1081cb0ef41Sopenharmony_ci { method: 'format', input: [null] }, 1091cb0ef41Sopenharmony_ci { method: 'format', input: [''] }, 1101cb0ef41Sopenharmony_ci { method: 'format', input: [true] }, 1111cb0ef41Sopenharmony_ci { method: 'format', input: [1] }, 1121cb0ef41Sopenharmony_ci]; 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_cicheckParseFormat(path.win32, winPaths); 1151cb0ef41Sopenharmony_cicheckParseFormat(path.posix, unixPaths); 1161cb0ef41Sopenharmony_cicheckSpecialCaseParseFormat(path.win32, winSpecialCaseParseTests); 1171cb0ef41Sopenharmony_cicheckErrors(path.win32); 1181cb0ef41Sopenharmony_cicheckErrors(path.posix); 1191cb0ef41Sopenharmony_cicheckFormat(path.win32, winSpecialCaseFormatTests); 1201cb0ef41Sopenharmony_cicheckFormat(path.posix, unixSpecialCaseFormatTests); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci// Test removal of trailing path separators 1231cb0ef41Sopenharmony_ciconst trailingTests = [ 1241cb0ef41Sopenharmony_ci [ path.win32.parse, 1251cb0ef41Sopenharmony_ci [['.\\', { root: '', dir: '', base: '.', ext: '', name: '.' }], 1261cb0ef41Sopenharmony_ci ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], 1271cb0ef41Sopenharmony_ci ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], 1281cb0ef41Sopenharmony_ci ['c:\\foo\\\\\\', 1291cb0ef41Sopenharmony_ci { root: 'c:\\', dir: 'c:\\', base: 'foo', ext: '', name: 'foo' }], 1301cb0ef41Sopenharmony_ci ['D:\\foo\\\\\\bar.baz', 1311cb0ef41Sopenharmony_ci { root: 'D:\\', 1321cb0ef41Sopenharmony_ci dir: 'D:\\foo\\\\', 1331cb0ef41Sopenharmony_ci base: 'bar.baz', 1341cb0ef41Sopenharmony_ci ext: '.baz', 1351cb0ef41Sopenharmony_ci name: 'bar' }, 1361cb0ef41Sopenharmony_ci ], 1371cb0ef41Sopenharmony_ci ], 1381cb0ef41Sopenharmony_ci ], 1391cb0ef41Sopenharmony_ci [ path.posix.parse, 1401cb0ef41Sopenharmony_ci [['./', { root: '', dir: '', base: '.', ext: '', name: '.' }], 1411cb0ef41Sopenharmony_ci ['//', { root: '/', dir: '/', base: '', ext: '', name: '' }], 1421cb0ef41Sopenharmony_ci ['///', { root: '/', dir: '/', base: '', ext: '', name: '' }], 1431cb0ef41Sopenharmony_ci ['/foo///', { root: '/', dir: '/', base: 'foo', ext: '', name: 'foo' }], 1441cb0ef41Sopenharmony_ci ['/foo///bar.baz', 1451cb0ef41Sopenharmony_ci { root: '/', dir: '/foo//', base: 'bar.baz', ext: '.baz', name: 'bar' }, 1461cb0ef41Sopenharmony_ci ], 1471cb0ef41Sopenharmony_ci ], 1481cb0ef41Sopenharmony_ci ], 1491cb0ef41Sopenharmony_ci]; 1501cb0ef41Sopenharmony_ciconst failures = []; 1511cb0ef41Sopenharmony_citrailingTests.forEach((test) => { 1521cb0ef41Sopenharmony_ci const parse = test[0]; 1531cb0ef41Sopenharmony_ci const os = parse === path.win32.parse ? 'win32' : 'posix'; 1541cb0ef41Sopenharmony_ci test[1].forEach((test) => { 1551cb0ef41Sopenharmony_ci const actual = parse(test[0]); 1561cb0ef41Sopenharmony_ci const expected = test[1]; 1571cb0ef41Sopenharmony_ci const message = `path.${os}.parse(${JSON.stringify(test[0])})\n expect=${ 1581cb0ef41Sopenharmony_ci JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; 1591cb0ef41Sopenharmony_ci const actualKeys = Object.keys(actual); 1601cb0ef41Sopenharmony_ci const expectedKeys = Object.keys(expected); 1611cb0ef41Sopenharmony_ci let failed = (actualKeys.length !== expectedKeys.length); 1621cb0ef41Sopenharmony_ci if (!failed) { 1631cb0ef41Sopenharmony_ci for (let i = 0; i < actualKeys.length; ++i) { 1641cb0ef41Sopenharmony_ci const key = actualKeys[i]; 1651cb0ef41Sopenharmony_ci if (!expectedKeys.includes(key) || actual[key] !== expected[key]) { 1661cb0ef41Sopenharmony_ci failed = true; 1671cb0ef41Sopenharmony_ci break; 1681cb0ef41Sopenharmony_ci } 1691cb0ef41Sopenharmony_ci } 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci if (failed) 1721cb0ef41Sopenharmony_ci failures.push(`\n${message}`); 1731cb0ef41Sopenharmony_ci }); 1741cb0ef41Sopenharmony_ci}); 1751cb0ef41Sopenharmony_ciassert.strictEqual(failures.length, 0, failures.join('')); 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_cifunction checkErrors(path) { 1781cb0ef41Sopenharmony_ci errors.forEach(({ method, input }) => { 1791cb0ef41Sopenharmony_ci assert.throws(() => { 1801cb0ef41Sopenharmony_ci path[method].apply(path, input); 1811cb0ef41Sopenharmony_ci }, { 1821cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1831cb0ef41Sopenharmony_ci name: 'TypeError' 1841cb0ef41Sopenharmony_ci }); 1851cb0ef41Sopenharmony_ci }); 1861cb0ef41Sopenharmony_ci} 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_cifunction checkParseFormat(path, paths) { 1891cb0ef41Sopenharmony_ci paths.forEach(([element, root]) => { 1901cb0ef41Sopenharmony_ci const output = path.parse(element); 1911cb0ef41Sopenharmony_ci assert.strictEqual(typeof output.root, 'string'); 1921cb0ef41Sopenharmony_ci assert.strictEqual(typeof output.dir, 'string'); 1931cb0ef41Sopenharmony_ci assert.strictEqual(typeof output.base, 'string'); 1941cb0ef41Sopenharmony_ci assert.strictEqual(typeof output.ext, 'string'); 1951cb0ef41Sopenharmony_ci assert.strictEqual(typeof output.name, 'string'); 1961cb0ef41Sopenharmony_ci assert.strictEqual(path.format(output), element); 1971cb0ef41Sopenharmony_ci assert.strictEqual(output.root, root); 1981cb0ef41Sopenharmony_ci assert(output.dir.startsWith(output.root)); 1991cb0ef41Sopenharmony_ci assert.strictEqual(output.dir, output.dir ? path.dirname(element) : ''); 2001cb0ef41Sopenharmony_ci assert.strictEqual(output.base, path.basename(element)); 2011cb0ef41Sopenharmony_ci assert.strictEqual(output.ext, path.extname(element)); 2021cb0ef41Sopenharmony_ci }); 2031cb0ef41Sopenharmony_ci} 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_cifunction checkSpecialCaseParseFormat(path, testCases) { 2061cb0ef41Sopenharmony_ci testCases.forEach(([element, expect]) => { 2071cb0ef41Sopenharmony_ci assert.deepStrictEqual(path.parse(element), expect); 2081cb0ef41Sopenharmony_ci }); 2091cb0ef41Sopenharmony_ci} 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_cifunction checkFormat(path, testCases) { 2121cb0ef41Sopenharmony_ci testCases.forEach(([element, expect]) => { 2131cb0ef41Sopenharmony_ci assert.strictEqual(path.format(element), expect); 2141cb0ef41Sopenharmony_ci }); 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci [null, undefined, 1, true, false, 'string'].forEach((pathObject) => { 2171cb0ef41Sopenharmony_ci assert.throws(() => { 2181cb0ef41Sopenharmony_ci path.format(pathObject); 2191cb0ef41Sopenharmony_ci }, { 2201cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 2211cb0ef41Sopenharmony_ci name: 'TypeError', 2221cb0ef41Sopenharmony_ci message: 'The "pathObject" argument must be of type object.' + 2231cb0ef41Sopenharmony_ci common.invalidArgTypeHelper(pathObject) 2241cb0ef41Sopenharmony_ci }); 2251cb0ef41Sopenharmony_ci }); 2261cb0ef41Sopenharmony_ci} 227