From 2a7b9b9126536a337a56dabde4853979895b4050 Mon Sep 17 00:00:00 2001 From: Danil Vakhrushev <17022974+davakh@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:41:19 +0400 Subject: [PATCH] fix: corrects resolve for win32 paths --- .cspell.json | 4 +- lib/DescriptionFileUtils.js | 2 + lib/PnpPlugin.js | 10 + lib/Resolver.js | 9 +- lib/ResolverFactory.js | 7 +- lib/RestrictionsPlugin.js | 3 +- lib/getPaths.js | 2 +- lib/util/path.js | 20 +- lib/util/win32-normalize-options.js | 108 +++++ test/CachedInputFileSystem.test.js | 44 +- test/__snapshots__/alias.test.js.snap | 64 +++ test/__snapshots__/fallback.test.js.snap | 70 +++ test/alias.test.js | 236 ++++++--- test/browserField.test.js | 59 ++- test/dependencies.test.js | 95 ++-- test/exportsField.test.js | 582 ++++++++++++++++------- test/extension-alias.test.js | 88 +++- test/extensions.test.js | 79 ++- test/fallback.test.js | 201 +++++--- test/fullSpecified.test.js | 160 ++++--- test/getPaths.test.js | 36 +- test/identifier.test.js | 45 +- test/importsField.test.js | 262 ++++++---- test/incorrect-description-file.test.js | 61 ++- test/missing.test.js | 15 +- test/plugins.test.js | 27 +- test/pnp.test.js | 171 ++++--- test/resolve.test.js | Bin 7884 -> 8557 bytes test/restrictions.test.js | 29 +- test/roots.test.js | 82 +++- test/scoped-packages.test.js | 46 +- test/simple.test.js | 15 +- test/symlink.test.js | 61 ++- test/unsafe-cache.test.js | 21 +- test/util/path-separator.js | 35 ++ test/yield.test.js | 449 +++++++++-------- 36 files changed, 2216 insertions(+), 982 deletions(-) create mode 100644 lib/util/win32-normalize-options.js create mode 100644 test/util/path-separator.js diff --git a/.cspell.json b/.cspell.json index 423d93a7..e8f27fa1 100644 --- a/.cspell.json +++ b/.cspell.json @@ -33,7 +33,9 @@ "zipp", "zippi", "zizizi", - "codecov" + "codecov", + "obps", + "posix" ], "ignorePaths": ["package.json", "yarn.lock", "coverage", "*.log"] } diff --git a/lib/DescriptionFileUtils.js b/lib/DescriptionFileUtils.js index ff53ad5f..d9c0f031 100644 --- a/lib/DescriptionFileUtils.js +++ b/lib/DescriptionFileUtils.js @@ -189,6 +189,8 @@ function getField(content, field) { */ function cdUp(directory) { if (directory === "/") return null; + if (directory.match(/^[a-zA-Z]:$/)) return null; + const i = directory.lastIndexOf("/"), j = directory.lastIndexOf("\\"); const p = i < 0 ? j : j < 0 ? i : i < j ? j : i; diff --git a/lib/PnpPlugin.js b/lib/PnpPlugin.js index d3d98bad..46d71609 100644 --- a/lib/PnpPlugin.js +++ b/lib/PnpPlugin.js @@ -5,6 +5,8 @@ "use strict"; +const { transformPathToPosix } = require("./util/path"); + /** @typedef {import("./Resolver")} Resolver */ /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */ @@ -77,10 +79,18 @@ module.exports = class PnpPlugin { return; } + if (typeof resolution === "string") { + resolution = transformPathToPosix(resolution); + } + if (resolveContext.fileDependencies) { apiResolution = this.pnpApi.resolveToUnqualified("pnpapi", issuer, { considerBuiltins: false }); + + if (typeof apiResolution === "string") { + apiResolution = transformPathToPosix(apiResolution); + } } } catch (/** @type {unknown} */ error) { if ( diff --git a/lib/Resolver.js b/lib/Resolver.js index fdb73dc1..9bc05fd6 100644 --- a/lib/Resolver.js +++ b/lib/Resolver.js @@ -12,7 +12,8 @@ const { normalize, cachedJoin: join, getType, - PathType + PathType, + transformPathToPosix } = require("./util/path"); /** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */ @@ -505,8 +506,8 @@ class Resolver { /** @type {ResolveRequest} */ const obj = { context: context, - path: path, - request: request + path: transformPathToPosix(path), + request: transformPathToPosix(request) }; /** @type {ResolveContextYield | undefined} */ @@ -535,7 +536,7 @@ class Resolver { }; } - const message = `resolve '${request}' in '${path}'`; + const message = `resolve '${obj.request}' in '${obj.path}'`; /** * @param {ResolveRequest} result result diff --git a/lib/ResolverFactory.js b/lib/ResolverFactory.js index 59558c7f..94157474 100644 --- a/lib/ResolverFactory.js +++ b/lib/ResolverFactory.js @@ -8,6 +8,9 @@ const versions = require("process").versions; const Resolver = require("./Resolver"); const { getType, PathType } = require("./util/path"); +const { + normalizeOptionsForWindows +} = require("./util/win32-normalize-options"); const SyncAsyncFileSystemDecorator = require("./SyncAsyncFileSystemDecorator"); @@ -199,7 +202,7 @@ function createOptions(options) { } } - return { + return normalizeOptionsForWindows({ alias: normalizeAlias(options.alias), fallback: normalizeAlias(options.fallback), aliasFields: new Set(options.aliasFields), @@ -267,7 +270,7 @@ function createOptions(options) { preferRelative: options.preferRelative || false, preferAbsolute: options.preferAbsolute || false, restrictions: new Set(options.restrictions) - }; + }); } /** diff --git a/lib/RestrictionsPlugin.js b/lib/RestrictionsPlugin.js index e52ca9d5..5cb1652b 100644 --- a/lib/RestrictionsPlugin.js +++ b/lib/RestrictionsPlugin.js @@ -9,7 +9,6 @@ /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ const slashCode = "/".charCodeAt(0); -const backslashCode = "\\".charCodeAt(0); /** * @param {string} path path @@ -20,7 +19,7 @@ const isInside = (path, parent) => { if (!path.startsWith(parent)) return false; if (path.length === parent.length) return true; const charCode = path.charCodeAt(parent.length); - return charCode === slashCode || charCode === backslashCode; + return charCode === slashCode; }; module.exports = class RestrictionsPlugin { diff --git a/lib/getPaths.js b/lib/getPaths.js index d5835b0d..723fbb13 100644 --- a/lib/getPaths.js +++ b/lib/getPaths.js @@ -11,7 +11,7 @@ */ module.exports = function getPaths(path) { if (path === "/") return { paths: ["/"], segments: [""] }; - const parts = path.split(/(.*?[\\/]+)/); + const parts = path.split(/(.*?[/]+)/); const paths = [path]; const segments = [parts[parts.length - 1]]; let part = parts[parts.length - 1]; diff --git a/lib/util/path.js b/lib/util/path.js index bbb0e4d4..56a3c723 100644 --- a/lib/util/path.js +++ b/lib/util/path.js @@ -18,7 +18,6 @@ const CHAR_DOT = ".".charCodeAt(0); const CHAR_COLON = ":".charCodeAt(0); const posixNormalize = path.posix.normalize; -const winNormalize = path.win32.normalize; /** * @enum {number} @@ -134,7 +133,7 @@ const normalize = p => { case PathType.Empty: return p; case PathType.AbsoluteWin: - return winNormalize(p); + return posixNormalize(p); case PathType.Relative: { const r = posixNormalize(p); return getType(r) === PathType.Relative ? r : `./${r}`; @@ -156,7 +155,7 @@ const join = (rootPath, request) => { case PathType.AbsolutePosix: return posixNormalize(request); case PathType.AbsoluteWin: - return winNormalize(request); + return posixNormalize(request); } switch (getType(rootPath)) { case PathType.Normal: @@ -164,7 +163,7 @@ const join = (rootPath, request) => { case PathType.AbsolutePosix: return posixNormalize(`${rootPath}/${request}`); case PathType.AbsoluteWin: - return winNormalize(`${rootPath}\\${request}`); + return posixNormalize(`${rootPath}/${request}`); } switch (requestType) { case PathType.Empty: @@ -201,3 +200,16 @@ const cachedJoin = (rootPath, request) => { return cacheEntry; }; exports.cachedJoin = cachedJoin; + +/** + * @param {string} rawPath node.js path + * @returns {string} normalized for windows, same for posix paths + */ +const transformPathToPosix = rawPath => { + if (!rawPath) return rawPath; + + if (path.sep === "/") + return rawPath; // Don't even transform if path.sep is posix + else return rawPath.split("\\").join("/"); +}; +exports.transformPathToPosix = transformPathToPosix; diff --git a/lib/util/win32-normalize-options.js b/lib/util/win32-normalize-options.js new file mode 100644 index 00000000..b6d90e6b --- /dev/null +++ b/lib/util/win32-normalize-options.js @@ -0,0 +1,108 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const { transformPathToPosix } = require("./path"); + +/** @typedef {import("../AliasPlugin").AliasOption} AliasOptionEntry */ +/** @typedef {import("../Resolver").ResolveOptions} ResolveOptions */ + +/** + * @param {AliasOptionEntry[]} aliasOptions alias options + * @returns {AliasOptionEntry[]} normalized for win32 aliases + */ +function normalizeWindowsAliasOption(aliasOptions) { + return aliasOptions.map(aliasOption => { + let newAliasOption = aliasOption.alias; + + if (typeof newAliasOption !== "boolean") { + newAliasOption = normalizeStringOrArrayOfStrings(newAliasOption); + } + + return { + ...aliasOption, + name: normalizeStringOrArrayOfStrings(aliasOption.name), + alias: newAliasOption + }; + }); +} + +/** + * @param {Set | Set | Set} rawSet alias + * @returns {*} normalized fon win32 sets of string or string[] + */ +function normalizeStringifiedSets(rawSet) { + const normalizedSet = new Set(); + rawSet.forEach(item => { + normalizedSet.add(normalizeStringOrArrayOfStrings(item)); + }); + return normalizedSet; +} + +/** + * @param {string | string[]} str str + * @returns {*} normalized str + */ +function normalizeStringOrArrayOfStrings(str) { + return Array.isArray(str) + ? str.map(transformPathToPosix) + : transformPathToPosix(str); +} + +/** + * @param {ResolveOptions} resolveOptions input options + * @returns {ResolveOptions} output options + */ +function normalizeOptionsForWindows(resolveOptions) { + // List of all options that can be passed with win32 path separator + resolveOptions.alias = normalizeWindowsAliasOption(resolveOptions.alias); + resolveOptions.fallback = normalizeWindowsAliasOption( + resolveOptions.fallback + ); + resolveOptions.aliasFields = normalizeStringifiedSets( + resolveOptions.aliasFields + ); + resolveOptions.extensionAlias = resolveOptions.extensionAlias.map( + aliasOption => ({ + ...aliasOption, + alias: normalizeStringOrArrayOfStrings(aliasOption.alias) + }) + ); + resolveOptions.conditionNames = normalizeStringifiedSets( + resolveOptions.conditionNames + ); + resolveOptions.descriptionFiles = normalizeStringOrArrayOfStrings( + resolveOptions.descriptionFiles + ); + resolveOptions.exportsFields = normalizeStringifiedSets( + resolveOptions.exportsFields + ); + resolveOptions.importsFields = normalizeStringifiedSets( + resolveOptions.importsFields + ); + resolveOptions.extensions = normalizeStringifiedSets( + resolveOptions.extensions + ); + resolveOptions.modules = Array.isArray(resolveOptions.modules) + ? resolveOptions.modules.map(item => normalizeStringOrArrayOfStrings(item)) + : resolveOptions.modules; + resolveOptions.mainFiles = normalizeStringifiedSets(resolveOptions.mainFiles); + resolveOptions.roots = normalizeStringifiedSets(resolveOptions.roots); + + const newRestrictions = new Set(); + resolveOptions.restrictions.forEach(restrict => { + if (typeof restrict === "string") { + newRestrictions.add(normalizeStringOrArrayOfStrings(restrict)); + } else { + // regexp + newRestrictions.add(restrict); + } + }); + resolveOptions.restrictions = newRestrictions; + + return resolveOptions; +} + +exports.normalizeOptionsForWindows = normalizeOptionsForWindows; diff --git a/test/CachedInputFileSystem.test.js b/test/CachedInputFileSystem.test.js index c3a70e18..c45ec219 100644 --- a/test/CachedInputFileSystem.test.js +++ b/test/CachedInputFileSystem.test.js @@ -1,6 +1,7 @@ const { CachedInputFileSystem } = require("../"); const path = require("path"); const url = require("url"); +const { obps, absoluteOsBasedPath } = require("./util/path-separator"); describe("CachedInputFileSystem OperationMergerBackend ('stat' and 'statSync')", () => { let fs; @@ -423,28 +424,35 @@ describe("CachedInputFileSystem CacheBackend", () => { }); it("should purge readdir correctly", function (done) { - fs.readdir("/test/path", (err, r) => { + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("0"); - fs.purge(["/test/path/sub/path"]); - fs.readdir("/test/path", (err, r) => { + fs.purge([`${absoluteOsBasedPath}test${obps}path${obps}sub${obps}path`]); + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("0"); - fs.purge(["/test/path/sub"]); - fs.readdir("/test/path", (err, r) => { + fs.purge([`${absoluteOsBasedPath}test${obps}path${obps}sub`]); + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("1"); - fs.purge(["/test/path"]); - fs.readdir("/test/path", (err, r) => { + fs.purge([`${absoluteOsBasedPath}test${obps}path`]); + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("2"); - fs.purge([url.pathToFileURL("/test/path")]); - fs.readdir("/test/path", (err, r) => { + fs.purge([ + url.pathToFileURL(`${absoluteOsBasedPath}test${obps}path`) + ]); + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("2"); - fs.purge(Buffer.from("/test/path")); - fs.readdir("/test/path", (err, r) => { + fs.purge(Buffer.from(`${absoluteOsBasedPath}test${obps}path`)); + fs.readdir(`${absoluteOsBasedPath}test${obps}path`, (err, r) => { expect(r[0]).toEqual("3"); - fs.purge([Buffer.from("/test/path")]); - fs.readdir("/test/path", (err, r) => { - expect(r[0]).toEqual("4"); - done(); - }); + fs.purge([ + Buffer.from(`${absoluteOsBasedPath}test${obps}path`) + ]); + fs.readdir( + `${absoluteOsBasedPath}test${obps}path`, + (err, r) => { + expect(r[0]).toEqual("4"); + done(); + } + ); }); }); }); @@ -475,7 +483,7 @@ describe("CachedInputFileSystem CacheBackend and Node.JS filesystem", () => { fs = new CachedInputFileSystem(require("fs"), 1); }); - const file = path.resolve(__dirname, "./fixtures/abc.txt"); + const file = path.resolve(__dirname, `.${obps}fixtures${obps}abc.txt`); it("should work with string async", function (done) { fs.readFile(file, (err, r) => { @@ -533,7 +541,7 @@ describe("CachedInputFileSystem OperationMergerBackend and Node.JS filesystem", fs = new CachedInputFileSystem(require("fs"), 0); }); - const file = path.resolve(__dirname, "./fixtures/abc.txt"); + const file = path.resolve(__dirname, `.${obps}fixtures${obps}abc.txt`); it("should work with string async", function (done) { fs.readFile(file, (err, r) => { diff --git a/test/__snapshots__/alias.test.js.snap b/test/__snapshots__/alias.test.js.snap index 33a02827..5c673676 100644 --- a/test/__snapshots__/alias.test.js.snap +++ b/test/__snapshots__/alias.test.js.snap @@ -31,3 +31,67 @@ Array [ " reporting result /a/dir/index", ] `; + +exports[`alias should log the correct info: posix 1`] = ` +Array [ + "resolve 'aliasA/dir' in '/'", + " Parsed request is a module", + " No description file found in / or above", + " aliased with mapping 'aliasA': 'a' to 'a/dir'", + " Parsed request is a module", + " No description file found in / or above", + " resolve as module", + " looking for modules in /", + " existing directory /a", + " No description file found in /a or above", + " No description file found in /a or above", + " no extension", + " /a/dir is not a file", + " .js", + " /a/dir.js doesn't exist", + " .json", + " /a/dir.json doesn't exist", + " .node", + " /a/dir.node doesn't exist", + " as directory", + " existing directory /a/dir", + " No description file found in /a/dir or above", + " using path: /a/dir/index", + " No description file found in /a/dir or above", + " no extension", + " existing file: /a/dir/index", + " reporting result /a/dir/index", +] +`; + +exports[`alias should log the correct info: win32 1`] = ` +Array [ + "resolve 'aliasA/dir' in 'X:/'", + " Parsed request is a module", + " No description file found in X:/ or above", + " aliased with mapping 'aliasA': 'a' to 'a/dir'", + " Parsed request is a module", + " No description file found in X:/ or above", + " resolve as module", + " looking for modules in X:/", + " existing directory X:/a", + " No description file found in X:/a or above", + " No description file found in X:/a or above", + " no extension", + " X:/a/dir is not a file", + " .js", + " X:/a/dir.js doesn't exist", + " .json", + " X:/a/dir.json doesn't exist", + " .node", + " X:/a/dir.node doesn't exist", + " as directory", + " existing directory X:/a/dir", + " No description file found in X:/a/dir or above", + " using path: X:/a/dir/index", + " No description file found in X:/a/dir or above", + " no extension", + " existing file: X:/a/dir/index", + " reporting result X:/a/dir/index", +] +`; diff --git a/test/__snapshots__/fallback.test.js.snap b/test/__snapshots__/fallback.test.js.snap index a804810e..3da89796 100644 --- a/test/__snapshots__/fallback.test.js.snap +++ b/test/__snapshots__/fallback.test.js.snap @@ -34,3 +34,73 @@ Array [ " reporting result /a/dir/index", ] `; + +exports[`fallback should log the correct info: posix 1`] = ` +Array [ + "resolve 'aliasA/dir' in '/'", + " Parsed request is a module", + " No description file found in / or above", + " resolve as module", + " looking for modules in /", + " /aliasA doesn't exist", + " aliased with mapping 'aliasA': 'a' to 'a/dir'", + " Parsed request is a module", + " No description file found in / or above", + " resolve as module", + " looking for modules in /", + " existing directory /a", + " No description file found in /a or above", + " No description file found in /a or above", + " no extension", + " /a/dir is not a file", + " .js", + " /a/dir.js doesn't exist", + " .json", + " /a/dir.json doesn't exist", + " .node", + " /a/dir.node doesn't exist", + " as directory", + " existing directory /a/dir", + " No description file found in /a/dir or above", + " using path: /a/dir/index", + " No description file found in /a/dir or above", + " no extension", + " existing file: /a/dir/index", + " reporting result /a/dir/index", +] +`; + +exports[`fallback should log the correct info: win32 1`] = ` +Array [ + "resolve 'aliasA/dir' in 'X:/'", + " Parsed request is a module", + " No description file found in X:/ or above", + " resolve as module", + " looking for modules in X:/", + " X:/aliasA doesn't exist", + " aliased with mapping 'aliasA': 'a' to 'a/dir'", + " Parsed request is a module", + " No description file found in X:/ or above", + " resolve as module", + " looking for modules in X:/", + " existing directory X:/a", + " No description file found in X:/a or above", + " No description file found in X:/a or above", + " no extension", + " X:/a/dir is not a file", + " .js", + " X:/a/dir.js doesn't exist", + " .json", + " X:/a/dir.json doesn't exist", + " .node", + " X:/a/dir.node doesn't exist", + " as directory", + " existing directory X:/a/dir", + " No description file found in X:/a/dir or above", + " using path: X:/a/dir/index", + " No description file found in X:/a/dir or above", + " no extension", + " existing file: X:/a/dir/index", + " reporting result X:/a/dir/index", +] +`; diff --git a/test/alias.test.js b/test/alias.test.js index 81cf5bcb..5bbbf455 100644 --- a/test/alias.test.js +++ b/test/alias.test.js @@ -3,6 +3,12 @@ const { Volume } = require("memfs"); const { ResolverFactory } = require("../"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); const fs = require("fs"); +const { + posixSep, + absoluteOsBasedResolvedPath, + absoluteOsBasedPath, + obps +} = require("./util/path-separator"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); @@ -12,37 +18,37 @@ describe("alias", () => { beforeEach(() => { const fileSystem = Volume.fromJSON( { - "/a/index": "", - "/a/dir/index": "", - "/recursive/index": "", - "/recursive/dir/index": "", - "/b/index": "", - "/b/dir/index": "", - "/c/index": "", - "/c/dir/index": "", - "/d/index.js": "", - "/d/dir/.empty": "", - "/e/index": "", - "/e/anotherDir/index": "", - "/e/dir/file": "" + [`${absoluteOsBasedPath}a${obps}index`]: "", + [`${absoluteOsBasedPath}a${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}recursive${obps}index`]: "", + [`${absoluteOsBasedPath}recursive${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}b${obps}index`]: "", + [`${absoluteOsBasedPath}b${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}c${obps}index`]: "", + [`${absoluteOsBasedPath}c${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}d${obps}index.js`]: "", + [`${absoluteOsBasedPath}d${obps}dir${obps}.empty`]: "", + [`${absoluteOsBasedPath}e${obps}index`]: "", + [`${absoluteOsBasedPath}e${obps}anotherDir${obps}index`]: "", + [`${absoluteOsBasedPath}e${obps}dir${obps}file`]: "" }, - "/" + absoluteOsBasedPath ); resolver = ResolverFactory.createResolver({ alias: { aliasA: "a", - b$: "a/index", - c$: "/a/index", + b$: `a${obps}index`, + c$: `${absoluteOsBasedPath}a${obps}index`, multiAlias: ["b", "c", "d", "e", "a"], - recursive: "recursive/dir", - "/d/dir": "/c/dir", - "/d/index.js": "/c/index", + recursive: `recursive${obps}dir`, + [`${absoluteOsBasedPath}d${obps}dir`]: `${absoluteOsBasedPath}c${obps}dir`, + [`${absoluteOsBasedPath}d${obps}index.js`]: `${absoluteOsBasedPath}c${obps}index`, // alias configuration should work - "#": "/c/dir", - "@": "/c/dir", + "#": `${absoluteOsBasedPath}c${obps}dir`, + "@": `${absoluteOsBasedPath}c${obps}dir`, ignored: false }, - modules: "/", + modules: absoluteOsBasedPath, useSyncFileSystemCalls: true, //@ts-ignore fileSystem: fileSystem @@ -50,92 +56,176 @@ describe("alias", () => { }); it("should resolve a not aliased module", () => { - expect(resolver.resolveSync({}, "/", "a")).toEqual("/a/index"); - expect(resolver.resolveSync({}, "/", "a/index")).toEqual("/a/index"); - expect(resolver.resolveSync({}, "/", "a/dir")).toEqual("/a/dir/index"); - expect(resolver.resolveSync({}, "/", "a/dir/index")).toEqual( - "/a/dir/index" + expect(resolver.resolveSync({}, absoluteOsBasedPath, "a")).toEqual( + `${absoluteOsBasedResolvedPath}a${posixSep}index` ); + expect( + resolver.resolveSync({}, absoluteOsBasedPath, `a${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}index`); + expect( + resolver.resolveSync({}, absoluteOsBasedPath, `a${obps}dir`) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync({}, absoluteOsBasedPath, `a${obps}dir${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); }); it("should resolve an aliased module", () => { - expect(resolver.resolveSync({}, "/", "aliasA")).toEqual("/a/index"); - expect(resolver.resolveSync({}, "/", "aliasA/index")).toEqual("/a/index"); - expect(resolver.resolveSync({}, "/", "aliasA/dir")).toEqual("/a/dir/index"); - expect(resolver.resolveSync({}, "/", "aliasA/dir/index")).toEqual( - "/a/dir/index" - ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "aliasA") + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `aliasA${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `aliasA${obps}dir`) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `aliasA${obps}dir${obps}index` + ) + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); }); it('should resolve "#" alias', () => { - expect(resolver.resolveSync({}, "/", "#")).toEqual("/c/dir/index"); - expect(resolver.resolveSync({}, "/", "#/index")).toEqual("/c/dir/index"); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "#")).toEqual( + `${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index` + ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `#${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); }); it('should resolve "@" alias', () => { - expect(resolver.resolveSync({}, "/", "@")).toEqual("/c/dir/index"); - expect(resolver.resolveSync({}, "/", "@/index")).toEqual("/c/dir/index"); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "@")).toEqual( + `${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index` + ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `@${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); }); it("should resolve an ignore module", () => { - expect(resolver.resolveSync({}, "/", "ignored")).toEqual(false); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "ignored") + ).toEqual(false); }); it("should resolve a recursive aliased module", () => { - expect(resolver.resolveSync({}, "/", "recursive")).toEqual( - "/recursive/dir/index" + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "recursive") + ).toEqual( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); - expect(resolver.resolveSync({}, "/", "recursive/index")).toEqual( - "/recursive/dir/index" + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `recursive${obps}index` + ) + ).toEqual( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); - expect(resolver.resolveSync({}, "/", "recursive/dir")).toEqual( - "/recursive/dir/index" + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `recursive${obps}dir`) + ).toEqual( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); - expect(resolver.resolveSync({}, "/", "recursive/dir/index")).toEqual( - "/recursive/dir/index" + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `recursive${posixSep}dir${posixSep}index` + ) + ).toEqual( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); }); it("should resolve a file aliased module", () => { - expect(resolver.resolveSync({}, "/", "b")).toEqual("/a/index"); - expect(resolver.resolveSync({}, "/", "c")).toEqual("/a/index"); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "b")).toEqual( + `${absoluteOsBasedResolvedPath}a${posixSep}index` + ); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "c")).toEqual( + `${absoluteOsBasedResolvedPath}a${posixSep}index` + ); }); it("should resolve a file aliased module with a query", () => { - expect(resolver.resolveSync({}, "/", "b?query")).toEqual("/a/index?query"); - expect(resolver.resolveSync({}, "/", "c?query")).toEqual("/a/index?query"); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "b?query") + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}index?query`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "c?query") + ).toEqual(`${absoluteOsBasedResolvedPath}a${posixSep}index?query`); }); it("should resolve a path in a file aliased module", () => { - expect(resolver.resolveSync({}, "/", "b/index")).toEqual("/b/index"); - expect(resolver.resolveSync({}, "/", "b/dir")).toEqual("/b/dir/index"); - expect(resolver.resolveSync({}, "/", "b/dir/index")).toEqual( - "/b/dir/index" - ); - expect(resolver.resolveSync({}, "/", "c/index")).toEqual("/c/index"); - expect(resolver.resolveSync({}, "/", "c/dir")).toEqual("/c/dir/index"); - expect(resolver.resolveSync({}, "/", "c/dir/index")).toEqual( - "/c/dir/index" - ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `b${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}b${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `b${obps}dir`) + ).toEqual(`${absoluteOsBasedResolvedPath}b${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `b${obps}dir${obps}index` + ) + ).toEqual(`${absoluteOsBasedResolvedPath}b${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `c${obps}index`) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `c${obps}dir`) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `c${obps}dir${obps}index` + ) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); }); it("should resolve a file aliased file", () => { - expect(resolver.resolveSync({}, "/", "d")).toEqual("/c/index"); - expect(resolver.resolveSync({}, "/", "d/dir/index")).toEqual( - "/c/dir/index" + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "d")).toEqual( + `${absoluteOsBasedResolvedPath}c${posixSep}index` ); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `d${obps}dir${obps}index` + ) + ).toEqual(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); }); it("should resolve a file in multiple aliased dirs", () => { - expect(resolver.resolveSync({}, "/", "multiAlias/dir/file")).toEqual( - "/e/dir/file" - ); - expect(resolver.resolveSync({}, "/", "multiAlias/anotherDir")).toEqual( - "/e/anotherDir/index" + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `multiAlias${obps}dir${obps}file` + ) + ).toEqual(`${absoluteOsBasedResolvedPath}e${posixSep}dir${posixSep}file`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `multiAlias${obps}anotherDir` + ) + ).toEqual( + `${absoluteOsBasedResolvedPath}e${posixSep}anotherDir${posixSep}index` ); }); it("should log the correct info", done => { const log = []; resolver.resolve( {}, - "/", - "aliasA/dir", + `${absoluteOsBasedPath}`, + `aliasA${obps}dir`, { log: v => log.push(v) }, (err, result) => { if (err) return done(err); - expect(result).toEqual("/a/dir/index"); - expect(log).toMatchSnapshot(); + expect(result).toEqual( + `${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index` + ); + expect(log).toMatchSnapshot(path.sep === "/" ? "posix" : "win32"); done(); } @@ -151,7 +241,7 @@ describe("alias", () => { fileSystem: nodeFileSystem }); - resolver.resolve({}, __dirname, "foo/index", {}, (err, result) => { + resolver.resolve({}, __dirname, `foo${obps}index`, {}, (err, result) => { if (err) done(err); expect(result).toEqual(false); done(); diff --git a/test/browserField.test.js b/test/browserField.test.js index a77c49c7..239755ef 100644 --- a/test/browserField.test.js +++ b/test/browserField.test.js @@ -1,13 +1,16 @@ const path = require("path"); const fs = require("fs"); const { ResolverFactory } = require("../"); +const { obps, transferPathToPosix } = require("./util/path-separator"); const browserModule = path.join(__dirname, "fixtures", "browser-module"); function p() { - return path.join.apply( - path, - [browserModule].concat(Array.prototype.slice.call(arguments)) + return transferPathToPosix( + path.join.apply( + path, + [browserModule].concat(Array.prototype.slice.call(arguments)) + ) ); } @@ -28,31 +31,43 @@ describe("browserField", () => { }); it("should ignore", function (done) { - resolver.resolve({}, p(), "./lib/ignore", {}, function (err, result) { - if (err) throw err; - expect(result).toEqual(false); - done(); - }); + resolver.resolve( + {}, + p(), + `.${obps}lib${obps}ignore`, + {}, + function (err, result) { + if (err) throw err; + expect(result).toEqual(false); + done(); + } + ); }); - it("should ignore", () => { - expect(resolver.resolveSync({}, p(), "./lib/ignore")).toEqual(false); - expect(resolver.resolveSync({}, p(), "./lib/ignore.js")).toEqual(false); - expect(resolver.resolveSync({}, p("lib"), "./ignore")).toEqual(false); - expect(resolver.resolveSync({}, p("lib"), "./ignore.js")).toEqual(false); + it("should ignore with file-check", () => { + expect(resolver.resolveSync({}, p(), `.${obps}lib${obps}ignore`)).toEqual( + false + ); + expect( + resolver.resolveSync({}, p(), `.${obps}lib${obps}ignore.js`) + ).toEqual(false); + expect(resolver.resolveSync({}, p("lib"), `.${obps}ignore`)).toEqual(false); + expect(resolver.resolveSync({}, p("lib"), `.${obps}ignore.js`)).toEqual( + false + ); }); it("should replace a file", () => { - expect(resolver.resolveSync({}, p(), "./lib/replaced")).toEqual( - p("lib", "browser.js") - ); - expect(resolver.resolveSync({}, p(), "./lib/replaced.js")).toEqual( + expect(resolver.resolveSync({}, p(), `.${obps}lib${obps}replaced`)).toEqual( p("lib", "browser.js") ); - expect(resolver.resolveSync({}, p("lib"), "./replaced")).toEqual( + expect( + resolver.resolveSync({}, p(), `.${obps}lib${obps}replaced.js`) + ).toEqual(p("lib", "browser.js")); + expect(resolver.resolveSync({}, p("lib"), `.${obps}replaced`)).toEqual( p("lib", "browser.js") ); - expect(resolver.resolveSync({}, p("lib"), "./replaced.js")).toEqual( + expect(resolver.resolveSync({}, p("lib"), `.${obps}replaced.js`)).toEqual( p("lib", "browser.js") ); }); @@ -76,16 +91,16 @@ describe("browserField", () => { }); it("should resolve in nested property", () => { - expect(resolver.resolveSync({}, p(), "./lib/main1.js")).toEqual( + expect(resolver.resolveSync({}, p(), `.${obps}lib${obps}main1.js`)).toEqual( p("lib", "main.js") ); - expect(resolver.resolveSync({}, p(), "./lib/main2.js")).toEqual( + expect(resolver.resolveSync({}, p(), `.${obps}lib${obps}main2.js`)).toEqual( p("lib", "browser.js") ); }); it("should check only alias field properties", () => { - expect(resolver.resolveSync({}, p(), "./toString")).toEqual( + expect(resolver.resolveSync({}, p(), `.${obps}toString`)).toEqual( p("lib", "toString.js") ); }); diff --git a/test/dependencies.test.js b/test/dependencies.test.js index a8426e55..b96c7cbb 100644 --- a/test/dependencies.test.js +++ b/test/dependencies.test.js @@ -1,5 +1,11 @@ const { Volume } = require("memfs"); const resolve = require("../"); +const { + posixSep, + obps, + absoluteOsBasedPath, + absoluteOsBasedResolvedPath +} = require("./util/path-separator"); describe("dependencies", function () { let resolver; @@ -7,18 +13,21 @@ describe("dependencies", function () { beforeEach(function () { const fileSystem = Volume.fromJSON( { - "/a/b/node_modules/some-module/index.js": "", - "/a/node_modules/module/package.json": JSON.stringify({ - main: "entry.js" - }), - "/a/node_modules/module/file.js": JSON.stringify({ main: "entry.js" }), - "/modules/other-module/file.js": "" + [`${absoluteOsBasedPath}a${obps}b${obps}node_modules${obps}some-module${obps}index.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}module${obps}package.json`]: + JSON.stringify({ + main: "entry.js" + }), + [`${absoluteOsBasedPath}a${obps}node_modules${obps}module${obps}file.js`]: + JSON.stringify({ main: "entry.js" }), + [`${absoluteOsBasedPath}modules${obps}other-module${obps}file.js`]: "" }, - "/" + `${absoluteOsBasedPath}` ); resolver = resolve.create({ extensions: [".json", ".js"], - modules: ["/modules", "node_modules"], + modules: [`${absoluteOsBasedPath}modules`, "node_modules"], // @ts-ignore fileSystem: fileSystem }); @@ -27,55 +36,47 @@ describe("dependencies", function () { const testCases = [ { name: "middle module request", - context: "/a/b/c", - request: "module/file", - result: "/a/node_modules/module/file.js", + context: `${absoluteOsBasedPath}a${obps}b${obps}c`, + request: `module${obps}file`, + result: `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module${posixSep}file.js`, fileDependencies: [ - // found package.json - "/a/node_modules/module/package.json", - // symlink checks - "/a/node_modules/module/file.js", - "/a/node_modules/module", - "/a/node_modules", - "/a", - "/" + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module${posixSep}file.js`, + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module`, + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules`, + `${absoluteOsBasedResolvedPath}a`, + `${absoluteOsBasedResolvedPath}` ], missingDependencies: [ - // missing package.jsons - "/a/b/c/package.json", - "/a/b/package.json", - "/a/package.json", - "/package.json", - // missing modules directories - "/a/b/c/node_modules", - // missing single file modules - "/modules/module", - "/a/b/node_modules/module", - // missing files with alterative extensions - "/a/node_modules/module/file", - "/a/node_modules/module/file.json" + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}c${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}c${posixSep}node_modules`, + `${absoluteOsBasedResolvedPath}modules${posixSep}module`, + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}node_modules${posixSep}module`, + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module${posixSep}file`, + `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}module${posixSep}file.json` ] }, { name: "fast found module request", - context: "/a/b/c", - request: "other-module/file.js", - result: "/modules/other-module/file.js", + context: `${absoluteOsBasedPath}a${obps}b${obps}c`, + request: `other-module${obps}file.js`, + result: `${absoluteOsBasedResolvedPath}modules${posixSep}other-module${posixSep}file.js`, fileDependencies: [ - // symlink checks - "/modules/other-module/file.js", - "/modules/other-module", - "/modules", - "/" + `${absoluteOsBasedResolvedPath}modules${posixSep}other-module${posixSep}file.js`, + `${absoluteOsBasedResolvedPath}modules${posixSep}other-module`, + `${absoluteOsBasedResolvedPath}modules`, + `${absoluteOsBasedResolvedPath}` ], missingDependencies: [ - // missing package.jsons - "/a/b/c/package.json", - "/a/b/package.json", - "/a/package.json", - "/package.json", - "/modules/other-module/package.json", - "/modules/package.json" + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}c${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}b${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}a${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}package.json`, + `${absoluteOsBasedResolvedPath}modules${posixSep}other-module${posixSep}package.json`, + `${absoluteOsBasedResolvedPath}modules${posixSep}package.json` ] } ]; diff --git a/test/exportsField.test.js b/test/exportsField.test.js index 5ec5d4e9..789714d1 100644 --- a/test/exportsField.test.js +++ b/test/exportsField.test.js @@ -3,6 +3,7 @@ const fs = require("fs"); const { processExportsField } = require("../lib/util/entrypoints"); const ResolverFactory = require("../lib/ResolverFactory"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); +const { transferPathToPosix, obps } = require("./util/path-separator"); /** @typedef {import("../lib/util/entrypoints").ExportsField} ExportsField */ @@ -2172,7 +2173,9 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/exports-field/x.js") + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}exports-field${obps}x.js`) + ) ); done(); }); @@ -2189,13 +2192,18 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "exports-field/dist/main.js", + `exports-field${obps}dist${obps}main.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/exports-field/lib/lib2/main.js") + transferPathToPosix( + path.resolve( + fixture, + `node_modules${obps}exports-field${obps}lib${obps}lib2${obps}main.js` + ) + ) ); done(); } @@ -2213,13 +2221,18 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/main.js", + `exports-field${obps}dist${obps}main.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture2, "node_modules/exports-field/lib/browser.js") + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}lib${obps}browser.js` + ) + ) ); done(); } @@ -2230,7 +2243,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/main", + `exports-field${obps}dist${obps}main`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2245,7 +2258,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/main", + `exports-field${obps}dist${obps}main`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2260,13 +2273,18 @@ describe("ExportsFieldPlugin", () => { commonjsResolver.resolve( {}, fixture2, - "exports-field/dist/main", + `exports-field${obps}dist${obps}main`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture2, "node_modules/exports-field/lib/main.js") + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}lib${obps}main.js` + ) + ) ); done(); } @@ -2277,13 +2295,18 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "exports-field/dist/main.js", + `exports-field${obps}dist${obps}main.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/exports-field/lib/main.js") + transferPathToPosix( + path.resolve( + fixture, + `node_modules${obps}exports-field${obps}lib${obps}main.js` + ) + ) ); done(); } @@ -2294,13 +2317,18 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/browser.js", + `exports-field${obps}dist${obps}browser.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture2, "node_modules/exports-field/lib/browser.js") + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}lib${obps}browser.js` + ) + ) ); done(); } @@ -2311,15 +2339,17 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/browser.js?foo", + `exports-field${obps}dist${obps}browser.js?foo`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve( - fixture2, - "node_modules/exports-field/lib/browser.js?foo" + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}lib${obps}browser.js?foo` + ) ) ); done(); @@ -2340,15 +2370,17 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture2, - "exports-field/dist/browser.js#foo", + `exports-field${obps}dist${obps}browser.js#foo`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve( - fixture2, - "node_modules/exports-field/lib/browser.js#foo" + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}lib${obps}browser.js#foo` + ) ) ); done(); @@ -2369,13 +2401,18 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "./node_modules/exports-field/lib/main.js", + `.${obps}node_modules${obps}exports-field${obps}lib${obps}main.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/exports-field/lib/main.js") + transferPathToPosix( + path.resolve( + fixture, + `node_modules${obps}exports-field${obps}lib${obps}main.js` + ) + ) ); done(); } @@ -2386,7 +2423,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "./node_modules/exports-field/dist/main.js", + `.${obps}node_modules${obps}exports-field${obps}dist${obps}main.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2401,7 +2438,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "exports-field/dist/../../../a.js", + `exports-field${obps}dist${obps}..${obps}..${obps}..${obps}a.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2418,7 +2455,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "exports-field/dist/a.js", + `exports-field${obps}dist${obps}a.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2432,19 +2469,27 @@ describe("ExportsFieldPlugin", () => { }); it("self-resolving root", done => { - resolver.resolve({}, fixture, "@exports-field/core", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "./a.js")); - done(); - }); + resolver.resolve( + {}, + fixture, + `@exports-field${obps}core`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `.${obps}a.js`)) + ); + done(); + } + ); }); it("not exported error", done => { resolver.resolve( {}, fixture, - "exports-field/anything/else", + `exports-field${obps}anything${obps}else`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2467,7 +2512,12 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture3, "node_modules/exports-field/main.js") + transferPathToPosix( + path.resolve( + fixture3, + `node_modules${obps}exports-field${obps}main.js` + ) + ) ); done(); }); @@ -2485,7 +2535,12 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture3, "node_modules/exports-field/main.js") + transferPathToPosix( + path.resolve( + fixture3, + `node_modules${obps}exports-field${obps}main.js` + ) + ) ); done(); }); @@ -2503,7 +2558,12 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture3, "node_modules/exports-field/main.js") + transferPathToPosix( + path.resolve( + fixture3, + `node_modules${obps}exports-field${obps}main.js` + ) + ) ); done(); }); @@ -2521,7 +2581,12 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture2, "node_modules/exports-field/index.js") + transferPathToPosix( + path.resolve( + fixture2, + `node_modules${obps}exports-field${obps}index.js` + ) + ) ); done(); }); @@ -2539,14 +2604,16 @@ describe("ExportsFieldPlugin", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture3, "node_modules/exports-field/index") + transferPathToPosix( + path.resolve(fixture3, `node_modules${obps}exports-field${obps}index`) + ) ); done(); }); }); it("request ending with slash #1", done => { - resolver.resolve({}, fixture, "exports-field/", {}, (err, result) => { + resolver.resolve({}, fixture, `exports-field${obps}`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Resolving to directories is not possible/); @@ -2555,21 +2622,33 @@ describe("ExportsFieldPlugin", () => { }); it("request ending with slash #2", done => { - resolver.resolve({}, fixture, "exports-field/dist/", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Resolving to directories is not possible/); - done(); - }); + resolver.resolve( + {}, + fixture, + `exports-field${obps}dist${obps}`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Resolving to directories is not possible/); + done(); + } + ); }); it("request ending with slash #3", done => { - resolver.resolve({}, fixture, "exports-field/lib/", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Resolving to directories is not possible/); - done(); - }); + resolver.resolve( + {}, + fixture, + `exports-field${obps}lib${obps}`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Resolving to directories is not possible/); + done(); + } + ); }); it("should throw error if target is invalid", done => { @@ -2604,16 +2683,25 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "exports-field/dist/browser.js", + `exports-field${obps}dist${obps}browser.js`, { log: v => log.push(v) }, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/exports-field/lib/browser.js") + transferPathToPosix( + path.resolve( + fixture, + `node_modules${obps}exports-field${obps}lib${obps}browser.js` + ) + ) ); expect( - log.map(line => line.replace(fixture, "...").replace(/\\/g, "/")) + log.map(line => + line + .replace(transferPathToPosix(fixture), "...") + .replace(/\\/g, `${obps}`) + ) ).toMatchSnapshot(); done(); } @@ -2623,67 +2711,105 @@ describe("ExportsFieldPlugin", () => { it("should resolve with wildcard pattern #1", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/features/f.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/features/f.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}features${obps}f.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}features${obps}f.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #2", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/features/y/y.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/features/y/y.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}features${obps}y${obps}y.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}features${obps}y${obps}y.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #2", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/features/y/y.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/features/y/y.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}features${obps}y${obps}y.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}features${obps}y${obps}y.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #3", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); resolver.resolve( {}, fixture, - "m/features-no-ext/y/y.js", + `m${obps}features-no-ext${obps}y${obps}y.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/features/y/y.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}features${obps}y${obps}y.js` + ) + ) ); done(); } @@ -2693,35 +2819,51 @@ describe("ExportsFieldPlugin", () => { it("should resolve with wildcard pattern #4", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/middle/nested/f.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/middle/nested/f.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}middle${obps}nested${obps}f.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle${obps}nested${obps}f.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #5", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); resolver.resolve( {}, fixture, - "m/middle-1/nested/f.js", + `m${obps}middle-1${obps}nested${obps}f.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/middle-1/nested/f.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle-1${obps}nested${obps}f.js` + ) + ) ); done(); } @@ -2731,19 +2873,24 @@ describe("ExportsFieldPlugin", () => { it("should resolve with wildcard pattern #6", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); resolver.resolve( {}, fixture, - "m/middle-2/nested/f.js", + `m${obps}middle-2${obps}nested${obps}f.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/middle-2/nested/f.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle-2${obps}nested${obps}f.js` + ) + ) ); done(); } @@ -2753,64 +2900,94 @@ describe("ExportsFieldPlugin", () => { it("should resolve with wildcard pattern #7", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/middle-3/nested/f", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve( - fixture, - "./node_modules/m/src/middle-3/nested/f/nested/f.js" - ) - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}middle-3${obps}nested${obps}f`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle-3${obps}nested${obps}f${obps}nested${obps}f.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #8", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/middle-4/f/nested", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/middle-4/f/f.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}middle-4${obps}f${obps}nested`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle-4${obps}f${obps}f.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with wildcard pattern #9", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); - resolver.resolve({}, fixture, "m/middle-5/f$/$", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/m/src/middle-5/f$/$.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `m${obps}middle-5${obps}f$${obps}$`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}m${obps}src${obps}middle-5${obps}f$${obps}$.js` + ) + ) + ); + done(); + } + ); }); it("should throw error if target is 'null'", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}` ); resolver.resolve( {}, fixture, - "m/features/internal/file.js", + `m${obps}features${obps}internal${obps}file.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -2835,17 +3012,28 @@ describe("ExportsFieldPlugin", () => { }); const fixture = path.resolve( __dirname, - "./fixtures/exports-field-and-extension-alias/" + `.${obps}fixtures${obps}exports-field-and-extension-alias${obps}` ); - resolver.resolve({}, fixture, "@org/pkg/string.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/@org/pkg/dist/string.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `@org${obps}pkg${obps}string.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}@org${obps}pkg${obps}dist${obps}string.js` + ) + ) + ); + done(); + } + ); }); it("should resolve with the `extensionAlias` option #2", done => { @@ -2860,14 +3048,19 @@ describe("ExportsFieldPlugin", () => { }); const fixture = path.resolve( __dirname, - "./fixtures/exports-field-and-extension-alias/" + `.${obps}fixtures${obps}exports-field-and-extension-alias${obps}` ); - resolver.resolve({}, fixture, "pkg/string.js", {}, (err, result) => { + resolver.resolve({}, fixture, `pkg${obps}string.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/pkg/dist/string.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}pkg${obps}dist${obps}string.js` + ) + ) ); done(); }); @@ -2885,14 +3078,19 @@ describe("ExportsFieldPlugin", () => { }); const fixture = path.resolve( __dirname, - "./fixtures/exports-field-and-extension-alias/" + `.${obps}fixtures${obps}exports-field-and-extension-alias${obps}` ); - resolver.resolve({}, fixture, "pkg/string.js", {}, (err, result) => { + resolver.resolve({}, fixture, `pkg${obps}string.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/pkg/dist/string.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}pkg${obps}dist${obps}string.js` + ) + ) ); done(); }); @@ -2910,10 +3108,10 @@ describe("ExportsFieldPlugin", () => { }); const fixture = path.resolve( __dirname, - "./fixtures/exports-field-and-extension-alias/" + `.${obps}fixtures${obps}exports-field-and-extension-alias${obps}` ); - resolver.resolve({}, fixture, "pkg/string.js", {}, (err, result) => { + resolver.resolve({}, fixture, `pkg${obps}string.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -2935,10 +3133,10 @@ describe("ExportsFieldPlugin", () => { }); const fixture = path.resolve( __dirname, - "./fixtures/exports-field-and-extension-alias/" + `.${obps}fixtures${obps}exports-field-and-extension-alias${obps}` ); - resolver.resolve({}, fixture, "pkg/string.js", {}, (err, result) => { + resolver.resolve({}, fixture, `pkg${obps}string.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -2952,12 +3150,16 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier", + `@exports-field${obps}bad-specifier`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js") + "?foo=../"); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture5, `.${obps}a.js`) + `?foo=..${obps}` + ) + ); done(); } ); @@ -2967,13 +3169,15 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/foo/file.js", + `@exports-field${obps}bad-specifier${obps}foo${obps}file.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture5, "./a.js") + "?foo=../#../" + transferPathToPosix( + path.resolve(fixture5, `.${obps}a.js`) + `?foo=..${obps}#..${obps}` + ) ); done(); } @@ -2984,7 +3188,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/bar", + `@exports-field${obps}bad-specifier${obps}bar`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3001,7 +3205,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/baz-multi", + `@exports-field${obps}bad-specifier${obps}baz-multi`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3018,12 +3222,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/pattern/a.js", + `@exports-field${obps}bad-specifier${obps}pattern${obps}a.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3033,12 +3239,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/slash", + `@exports-field${obps}bad-specifier${obps}slash`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3048,12 +3256,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/no-slash", + `@exports-field${obps}bad-specifier${obps}no-slash`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3063,7 +3273,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils/index.mjs", + `@exports-field${obps}bad-specifier${obps}utils${obps}index.mjs`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3080,7 +3290,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils1/index.mjs", + `@exports-field${obps}bad-specifier${obps}utils1${obps}index.mjs`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3097,7 +3307,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils2/index", + `@exports-field${obps}bad-specifier${obps}utils2${obps}index`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3114,7 +3324,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils3/index", + `@exports-field${obps}bad-specifier${obps}utils3${obps}index`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3131,7 +3341,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils4/index", + `@exports-field${obps}bad-specifier${obps}utils4${obps}index`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3148,7 +3358,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/utils5/index", + `@exports-field${obps}bad-specifier${obps}utils5${obps}index`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3165,7 +3375,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/timezones/pdt.mjs", + `@exports-field${obps}bad-specifier${obps}timezones${obps}pdt.mjs`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3182,7 +3392,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/non-existent.js", + `@exports-field${obps}bad-specifier${obps}non-existent.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3199,7 +3409,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi1", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi1`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3216,7 +3426,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi2", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi2`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3233,7 +3443,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi4", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi4`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3250,7 +3460,7 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi5", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi5`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); @@ -3267,12 +3477,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/bad-specifier.js", + `@exports-field${obps}bad-specifier${obps}bad-specifier.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3282,12 +3494,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/bad-specifier1.js", + `@exports-field${obps}bad-specifier${obps}bad-specifier1.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3297,12 +3511,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); @@ -3312,12 +3528,14 @@ describe("ExportsFieldPlugin", () => { resolver.resolve( {}, fixture5, - "@exports-field/bad-specifier/dep/multi3", + `@exports-field${obps}bad-specifier${obps}dep${obps}multi3`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture5, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture5, `.${obps}a.js`)) + ); done(); } ); diff --git a/test/extension-alias.test.js b/test/extension-alias.test.js index aafc760e..8aec071d 100644 --- a/test/extension-alias.test.js +++ b/test/extension-alias.test.js @@ -4,6 +4,8 @@ const fs = require("fs"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); const ResolverFactory = require("../lib/ResolverFactory"); +const { obps, transferPathToPosix } = require("./util/path-separator"); + /** @typedef {import("../lib/util/entrypoints").ImportsField} ImportsField */ describe("extension-alias", () => { @@ -21,39 +23,65 @@ describe("extension-alias", () => { }); it("should alias fully specified file", done => { - resolver.resolve({}, fixture, "./index.js", {}, (err, result) => { + resolver.resolve({}, fixture, `.${obps}index.js`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "index.ts")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "index.ts")) + ); done(); }); }); it("should alias fully specified file when there are two alternatives", done => { - resolver.resolve({}, fixture, "./dir/index.js", {}, (err, result) => { - if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "dir", "index.ts")); - done(); - }); + resolver.resolve( + {}, + fixture, + `.${obps}dir${obps}index.js`, + {}, + (err, result) => { + if (err) return done(err); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "dir", "index.ts")) + ); + done(); + } + ); }); it("should also allow the second alternative", done => { - resolver.resolve({}, fixture, "./dir2/index.js", {}, (err, result) => { - if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "dir2", "index.js")); - done(); - }); + resolver.resolve( + {}, + fixture, + `.${obps}dir2${obps}index.js`, + {}, + (err, result) => { + if (err) return done(err); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "dir2", "index.js")) + ); + done(); + } + ); }); it("should support alias option without an array", done => { - resolver.resolve({}, fixture, "./dir2/index.mjs", {}, (err, result) => { - if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "dir2", "index.mts")); - done(); - }); + resolver.resolve( + {}, + fixture, + `.${obps}dir2${obps}index.mjs`, + {}, + (err, result) => { + if (err) return done(err); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "dir2", "index.mts")) + ); + done(); + } + ); }); it("should not allow to fallback to the original extension or add extensions", done => { - resolver.resolve({}, fixture, "./index.mjs", {}, (err, result) => { + resolver.resolve({}, fixture, `.${obps}index.mjs`, {}, (err, result) => { expect(err).toBeInstanceOf(Error); done(); }); @@ -70,19 +98,29 @@ describe("extension-alias", () => { }); it("directory", done => { - resolver.resolve({}, fixture, "./dir2", {}, (err, result) => { + resolver.resolve({}, fixture, `.${obps}dir2`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "dir2", "index.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "dir2", "index.js")) + ); done(); }); }); it("file", done => { - resolver.resolve({}, fixture, "./dir2/index", {}, (err, result) => { - if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "dir2", "index.js")); - done(); - }); + resolver.resolve( + {}, + fixture, + `.${obps}dir2${obps}index`, + {}, + (err, result) => { + if (err) return done(err); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "dir2", "index.js")) + ); + done(); + } + ); }); }); }); diff --git a/test/extensions.test.js b/test/extensions.test.js index 3c851a6f..29564dd5 100644 --- a/test/extensions.test.js +++ b/test/extensions.test.js @@ -1,6 +1,7 @@ const path = require("path"); const fs = require("fs"); const { ResolverFactory, CachedInputFileSystem } = require("../"); +const { transferPathToPosix, obps } = require("./util/path-separator"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); @@ -24,18 +25,22 @@ const fixture = path.resolve(__dirname, "fixtures", "extensions"); describe("extensions", function () { it("should resolve according to order of provided extensions", function (done) { - resolver.resolve({}, fixture, "./foo", {}, (err, result) => { + resolver.resolve({}, fixture, `.${obps}foo`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "foo.ts")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "foo.ts")) + ); done(); }); }); it("should resolve according to order of provided extensions (dir index)", function (done) { - resolver.resolve({}, fixture, "./dir", {}, (err, result) => { + resolver.resolve({}, fixture, `.${obps}dir`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "dir/index.ts")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `dir${obps}index.ts`)) + ); done(); }); }); @@ -43,7 +48,9 @@ describe("extensions", function () { resolver.resolve({}, fixture, ".", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "index.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "index.js")) + ); done(); }); }); @@ -51,29 +58,41 @@ describe("extensions", function () { resolver.resolve({}, fixture, "module", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "node_modules/module.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}module.js`) + ) + ); done(); }); }); it("should resolve trailing slash directory before single file", function (done) { - resolver.resolve({}, fixture, "module/", {}, (err, result) => { + resolver.resolve({}, fixture, `module${obps}`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/module/index.ts") + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}module${obps}index.ts`) + ) ); done(); }); }); it("should not resolve to file when request has a trailing slash (relative)", function (done) { - resolver.resolve({}, fixture, "./foo.js/", {}, (err, result) => { - if (!err) return done(new Error("No error")); - expect(err).toBeInstanceOf(Error); - done(); - }); + resolver.resolve( + {}, + fixture, + `.${obps}foo.js${obps}`, + {}, + (err, result) => { + if (!err) return done(new Error("No error")); + expect(err).toBeInstanceOf(Error); + done(); + } + ); }); it("should not resolve to file when request has a trailing slash (module)", function (done) { - resolver.resolve({}, fixture, "module.js/", {}, (err, result) => { + resolver.resolve({}, fixture, `module.js${obps}`, {}, (err, result) => { if (!err) return done(new Error("No error")); expect(err).toBeInstanceOf(Error); done(); @@ -81,16 +100,32 @@ describe("extensions", function () { }); it("should default enforceExtension to true when extensions includes an empty string", function (done) { const missingDependencies = new Set(); - resolver2.resolve({}, fixture, "./foo", { missingDependencies }, () => { - expect(missingDependencies).not.toContain(path.resolve(fixture, "foo")); - done(); - }); + resolver2.resolve( + {}, + fixture, + `.${obps}foo`, + { missingDependencies }, + () => { + expect(missingDependencies).not.toContain( + transferPathToPosix(path.resolve(fixture, "foo")) + ); + done(); + } + ); }); it("should respect enforceExtension when extensions includes an empty string", function (done) { const missingDependencies = new Set(); - resolver3.resolve({}, fixture, "./foo", { missingDependencies }, () => { - expect(missingDependencies).toContain(path.resolve(fixture, "foo")); - done(); - }); + resolver3.resolve( + {}, + fixture, + `.${obps}foo`, + { missingDependencies }, + () => { + expect(missingDependencies).toContain( + transferPathToPosix(path.resolve(fixture, "foo")) + ); + done(); + } + ); }); }); diff --git a/test/fallback.test.js b/test/fallback.test.js index a6f71528..dc062088 100644 --- a/test/fallback.test.js +++ b/test/fallback.test.js @@ -1,5 +1,12 @@ const { Volume } = require("memfs"); +const path = require("path"); const { ResolverFactory } = require("../"); +const { + posixSep, + absoluteOsBasedResolvedPath, + absoluteOsBasedPath, + obps +} = require("./util/path-separator"); describe("fallback", function () { let resolver; @@ -7,36 +14,36 @@ describe("fallback", function () { beforeEach(function () { const fileSystem = Volume.fromJSON( { - "/a/index": "", - "/a/dir/index": "", - "/recursive/index": "", - "/recursive/dir/index": "", - "/recursive/dir/file": "", - "/recursive/dir/dir/index": "", - "/b/index": "", - "/b/dir/index": "", - "/c/index": "", - "/c/dir/index": "", - "/d/index.js": "", - "/d/dir/.empty": "", - "/e/index": "", - "/e/anotherDir/index": "", - "/e/dir/file": "" + [`${absoluteOsBasedPath}a${obps}index`]: "", + [`${absoluteOsBasedPath}a${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}recursive${obps}index`]: "", + [`${absoluteOsBasedPath}recursive${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}recursive${obps}dir${obps}file`]: "", + [`${absoluteOsBasedPath}recursive${obps}dir${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}b${obps}index`]: "", + [`${absoluteOsBasedPath}b${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}c${obps}index`]: "", + [`${absoluteOsBasedPath}c${obps}dir${obps}index`]: "", + [`${absoluteOsBasedPath}d${obps}index.js`]: "", + [`${absoluteOsBasedPath}d${obps}dir${obps}.empty`]: "", + [`${absoluteOsBasedPath}e${obps}index`]: "", + [`${absoluteOsBasedPath}e${obps}anotherDir${obps}index`]: "", + [`${absoluteOsBasedPath}e${obps}dir${obps}file`]: "" }, - "/" + `${absoluteOsBasedPath}` ); resolver = ResolverFactory.createResolver({ fallback: { aliasA: "a", - b$: "a/index", - c$: "/a/index", + b$: `a${obps}index`, + c$: `${absoluteOsBasedPath}a${obps}index`, multiAlias: ["b", "c", "d", "e", "a"], - recursive: "recursive/dir", - "/d/dir": "/c/dir", - "/d/index.js": "/c/index", + recursive: `recursive${obps}dir`, + [`${absoluteOsBasedPath}d${obps}dir`]: `${absoluteOsBasedPath}c${obps}dir`, + [`${absoluteOsBasedPath}d${obps}index.js`]: `${absoluteOsBasedPath}c${obps}index`, ignored: false }, - modules: "/", + modules: `${absoluteOsBasedPath}`, useSyncFileSystemCalls: true, //@ts-ignore fileSystem: fileSystem @@ -44,68 +51,144 @@ describe("fallback", function () { }); it("should resolve a not aliased module", function () { - expect(resolver.resolveSync({}, "/", "a")).toBe("/a/index"); - expect(resolver.resolveSync({}, "/", "a/index")).toBe("/a/index"); - expect(resolver.resolveSync({}, "/", "a/dir")).toBe("/a/dir/index"); - expect(resolver.resolveSync({}, "/", "a/dir/index")).toBe("/a/dir/index"); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "a")).toBe( + `${absoluteOsBasedResolvedPath}a${posixSep}index` + ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `a${obps}index`) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `a${obps}dir`) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `a${obps}dir${obps}index` + ) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); }); it("should resolve an fallback module", function () { - expect(resolver.resolveSync({}, "/", "aliasA")).toBe("/a/index"); - expect(resolver.resolveSync({}, "/", "aliasA/index")).toBe("/a/index"); - expect(resolver.resolveSync({}, "/", "aliasA/dir")).toBe("/a/dir/index"); - expect(resolver.resolveSync({}, "/", "aliasA/dir/index")).toBe( - "/a/dir/index" + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "aliasA")).toBe( + `${absoluteOsBasedResolvedPath}a${posixSep}index` ); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `aliasA${obps}index`) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `aliasA${obps}dir`) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `aliasA${obps}dir${obps}index` + ) + ).toBe(`${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index`); }); it("should resolve an ignore module", () => { - expect(resolver.resolveSync({}, "/", "ignored")).toBe(false); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "ignored")).toBe( + false + ); }); it("should resolve a recursive aliased module", function () { - expect(resolver.resolveSync({}, "/", "recursive")).toBe("/recursive/index"); - expect(resolver.resolveSync({}, "/", "recursive/index")).toBe( - "/recursive/index" - ); - expect(resolver.resolveSync({}, "/", "recursive/dir")).toBe( - "/recursive/dir/index" + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, "recursive") + ).toBe(`${absoluteOsBasedResolvedPath}recursive${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `recursive${obps}index` + ) + ).toBe(`${absoluteOsBasedResolvedPath}recursive${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `recursive${obps}dir`) + ).toBe( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); - expect(resolver.resolveSync({}, "/", "recursive/dir/index")).toBe( - "/recursive/dir/index" + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `recursive${obps}dir${obps}index` + ) + ).toBe( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}index` ); - expect(resolver.resolveSync({}, "/", "recursive/file")).toBe( - "/recursive/dir/file" + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `recursive${obps}file`) + ).toBe( + `${absoluteOsBasedResolvedPath}recursive${posixSep}dir${posixSep}file` ); }); it("should resolve a file aliased module with a query", function () { - expect(resolver.resolveSync({}, "/", "b?query")).toBe("/b/index?query"); - expect(resolver.resolveSync({}, "/", "c?query")).toBe("/c/index?query"); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "b?query")).toBe( + `${absoluteOsBasedResolvedPath}b${posixSep}index?query` + ); + expect(resolver.resolveSync({}, `${absoluteOsBasedPath}`, "c?query")).toBe( + `${absoluteOsBasedResolvedPath}c${posixSep}index?query` + ); }); it("should resolve a path in a file aliased module", function () { - expect(resolver.resolveSync({}, "/", "b/index")).toBe("/b/index"); - expect(resolver.resolveSync({}, "/", "b/dir")).toBe("/b/dir/index"); - expect(resolver.resolveSync({}, "/", "b/dir/index")).toBe("/b/dir/index"); - expect(resolver.resolveSync({}, "/", "c/index")).toBe("/c/index"); - expect(resolver.resolveSync({}, "/", "c/dir")).toBe("/c/dir/index"); - expect(resolver.resolveSync({}, "/", "c/dir/index")).toBe("/c/dir/index"); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `b${obps}index`) + ).toBe(`${absoluteOsBasedResolvedPath}b${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `b${obps}dir`) + ).toBe(`${absoluteOsBasedResolvedPath}b${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `b${obps}dir${obps}index` + ) + ).toBe(`${absoluteOsBasedResolvedPath}b${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `c${obps}index`) + ).toBe(`${absoluteOsBasedResolvedPath}c${posixSep}index`); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}`, `c${obps}dir`) + ).toBe(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `c${obps}dir${obps}index` + ) + ).toBe(`${absoluteOsBasedResolvedPath}c${posixSep}dir${posixSep}index`); }); it("should resolve a file in multiple aliased dirs", function () { - expect(resolver.resolveSync({}, "/", "multiAlias/dir/file")).toBe( - "/e/dir/file" - ); - expect(resolver.resolveSync({}, "/", "multiAlias/anotherDir")).toBe( - "/e/anotherDir/index" + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `multiAlias${obps}dir${obps}file` + ) + ).toBe(`${absoluteOsBasedResolvedPath}e${posixSep}dir${posixSep}file`); + expect( + resolver.resolveSync( + {}, + `${absoluteOsBasedPath}`, + `multiAlias${obps}anotherDir` + ) + ).toBe( + `${absoluteOsBasedResolvedPath}e${posixSep}anotherDir${posixSep}index` ); }); it("should log the correct info", done => { const log = []; resolver.resolve( {}, - "/", - "aliasA/dir", + `${absoluteOsBasedPath}`, + `aliasA${obps}dir`, { log: v => log.push(v) }, (err, result) => { if (err) return done(err); - expect(result).toBe("/a/dir/index"); - expect(log).toMatchSnapshot(); + expect(result).toBe( + `${absoluteOsBasedResolvedPath}a${posixSep}dir${posixSep}index` + ); + expect(log).toMatchSnapshot(path.sep === "/" ? "posix" : "win32"); done(); } ); diff --git a/test/fullSpecified.test.js b/test/fullSpecified.test.js index e97cb6a7..dec1717a 100644 --- a/test/fullSpecified.test.js +++ b/test/fullSpecified.test.js @@ -1,36 +1,52 @@ const { Volume } = require("memfs"); const { ResolverFactory } = require("../"); +const { + posixSep, + absoluteOsBasedResolvedPath, + absoluteOsBasedPath, + obps +} = require("./util/path-separator"); describe("fullSpecified", function () { const fileSystem = Volume.fromJSON( { - "/a/node_modules/package1/index.js": "", - "/a/node_modules/package1/file.js": "", - "/a/node_modules/package2/package.json": JSON.stringify({ - main: "a" - }), - "/a/node_modules/package2/a.js": "", - "/a/node_modules/package3/package.json": JSON.stringify({ - main: "dir" - }), - "/a/node_modules/package3/dir/index.js": "", - "/a/node_modules/package4/package.json": JSON.stringify({ - browser: { - "./a.js": "./b" - } - }), - "/a/node_modules/package4/a.js": "", - "/a/node_modules/package4/b.js": "", - "/a/abc.js": "", - "/a/dir/index.js": "", - "/a/index.js": "" + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package1${obps}index.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package1${obps}file.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package2${obps}package.json`]: + JSON.stringify({ + main: "a" + }), + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package2${obps}a.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package3${obps}package.json`]: + JSON.stringify({ + main: "dir" + }), + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package3${obps}dir${obps}index.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package4${obps}package.json`]: + JSON.stringify({ + browser: { + // It needs to be posixSep because it alias field inside file, this fields use only posix separator based on specification + [`.${posixSep}a.js`]: `.${posixSep}b` + } + }), + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package4${obps}a.js`]: + "", + [`${absoluteOsBasedPath}a${obps}node_modules${obps}package4${obps}b.js`]: + "", + [`${absoluteOsBasedPath}a${obps}abc.js`]: "", + [`${absoluteOsBasedPath}a${obps}dir${obps}index.js`]: "", + [`${absoluteOsBasedPath}a${obps}index.js`]: "" }, - "/" + `${absoluteOsBasedPath}` ); const resolver = ResolverFactory.createResolver({ alias: { - alias1: "/a/abc", - alias2: "/a/" + alias1: `${absoluteOsBasedPath}a${obps}abc`, + alias2: `${absoluteOsBasedPath}a${obps}` }, aliasFields: ["browser"], fullySpecified: true, @@ -40,8 +56,8 @@ describe("fullSpecified", function () { }); const contextResolver = ResolverFactory.createResolver({ alias: { - alias1: "/a/abc", - alias2: "/a/" + alias1: `${absoluteOsBasedPath}a${obps}abc`, + alias2: `${absoluteOsBasedPath}a${obps}` }, aliasFields: ["browser"], fullySpecified: true, @@ -52,33 +68,54 @@ describe("fullSpecified", function () { }); const failingResolves = { - "no extensions": "./abc", - "no extensions (absolute)": "/a/abc", - "no extensions in packages": "package1/file", + "no extensions": `.${obps}abc`, + "no extensions (absolute)": `${absoluteOsBasedResolvedPath}a${obps}abc`, + "no extensions in packages": `package1${obps}file`, "no directories": ".", - "no directories 2": "./", - "no directories in packages": "package3/dir", - "no extensions in packages 2": "package3/a" + "no directories 2": `.${obps}`, + "no directories in packages": `package3${obps}dir`, + "no extensions in packages 2": `package3${obps}a` }; - const pkg = "/a/node_modules/package"; + const pkg = `${absoluteOsBasedResolvedPath}a${posixSep}node_modules${posixSep}package`; const successfulResolves = { - "fully relative": ["./abc.js", "/a/abc.js"], - "fully absolute": ["/a/abc.js", "/a/abc.js"], - "fully relative in package": ["package1/file.js", `${pkg}1/file.js`], - "extensions in mainFiles": ["package1", `${pkg}1/index.js`], - "extensions in mainFields": ["package2", `${pkg}2/a.js`], - "extensions in alias": ["alias1", `/a/abc.js`], - "directories in alias": ["alias2", `/a/index.js`], - "directories in packages": ["package3", `${pkg}3/dir/index.js`], - "extensions in aliasFields": ["package4/a.js", `${pkg}4/b.js`] + "fully relative": [ + `.${obps}abc.js`, + `${absoluteOsBasedResolvedPath}a${posixSep}abc.js` + ], + "fully absolute": [ + `${absoluteOsBasedPath}a${obps}abc.js`, + `${absoluteOsBasedResolvedPath}a${posixSep}abc.js` + ], + "fully relative in package": [ + `package1${obps}file.js`, + `${pkg}1${posixSep}file.js` + ], + "extensions in mainFiles": ["package1", `${pkg}1${posixSep}index.js`], + "extensions in mainFields": ["package2", `${pkg}2${posixSep}a.js`], + "extensions in alias": [ + "alias1", + `${absoluteOsBasedResolvedPath}a${posixSep}abc.js` + ], + "directories in alias": [ + "alias2", + `${absoluteOsBasedResolvedPath}a${posixSep}index.js` + ], + "directories in packages": [ + "package3", + `${pkg}3${posixSep}dir${posixSep}index.js` + ], + "extensions in aliasFields": [ + `package4${obps}a.js`, + `${pkg}4${posixSep}b.js` + ] }; for (const key of Object.keys(failingResolves)) { const request = failingResolves[key]; it(`should fail resolving ${key}`, () => { expect(() => { - resolver.resolveSync({}, "/a", request); + resolver.resolveSync({}, `${absoluteOsBasedPath}a`, request); }).toThrowError(); }); } @@ -87,7 +124,9 @@ describe("fullSpecified", function () { const [request, expected] = successfulResolves[key]; it(`should resolve ${key} successfully`, () => { try { - expect(resolver.resolveSync({}, "/a", request)).toEqual(expected); + expect( + resolver.resolveSync({}, `${absoluteOsBasedPath}a`, request) + ).toEqual(expected); } catch (e) { e.message += `\n${e.details}`; throw e; @@ -96,29 +135,38 @@ describe("fullSpecified", function () { } const successfulContextResolves = { - "current folder": [".", "/a"], - "current folder 2": ["./", "/a"], - "relative directory": ["./dir", "/a/dir"], - "relative directory 2": ["./dir/", "/a/dir"], + "current folder": [".", `${absoluteOsBasedResolvedPath}a`], + "current folder 2": [`.${posixSep}`, `${absoluteOsBasedResolvedPath}a`], + "relative directory": [ + `.${posixSep}dir`, + `${absoluteOsBasedResolvedPath}a${posixSep}dir` + ], + "relative directory 2": [ + `.${posixSep}dir${posixSep}`, + `${absoluteOsBasedResolvedPath}a${posixSep}dir` + ], "relative directory with query and fragment": [ - "./dir?123#456", - "/a/dir?123#456" + `.${posixSep}dir?123#456`, + `${absoluteOsBasedResolvedPath}a${posixSep}dir?123#456` ], "relative directory with query and fragment 2": [ - "./dir/?123#456", - "/a/dir?123#456" + `.${posixSep}dir${posixSep}?123#456`, + `${absoluteOsBasedResolvedPath}a${posixSep}dir?123#456` + ], + "absolute directory": [ + `${absoluteOsBasedResolvedPath}a${posixSep}dir`, + `${absoluteOsBasedResolvedPath}a${posixSep}dir` ], - "absolute directory": ["/a/dir", "/a/dir"], - "directory in package": ["package3/dir", `${pkg}3/dir`] + "directory in package": [`package3${posixSep}dir`, `${pkg}3${posixSep}dir`] }; for (const key of Object.keys(successfulContextResolves)) { const [request, expected] = successfulContextResolves[key]; it(`should resolve ${key} successfully to an context`, () => { try { - expect(contextResolver.resolveSync({}, "/a", request)).toEqual( - expected - ); + expect( + contextResolver.resolveSync({}, `${absoluteOsBasedPath}a`, request) + ).toEqual(expected); } catch (e) { e.message += `\n${e.details}`; throw e; diff --git a/test/getPaths.test.js b/test/getPaths.test.js index eff8f0ad..30dc4b31 100644 --- a/test/getPaths.test.js +++ b/test/getPaths.test.js @@ -1,17 +1,41 @@ const getPaths = require("../lib/getPaths"); +const { posixSep } = require("./util/path-separator"); /** * @type {[string,{paths: string[], segments: string[]}][]} */ const cases = [ - ["/a", { paths: ["/a", "/"], segments: ["a", "/"] }], - ["/a/", { paths: ["/a/", "/a", "/"], segments: ["", "a", "/"] }], - ["/a/b", { paths: ["/a/b", "/a", "/"], segments: ["b", "a", "/"] }], [ - "/a/b/", - { paths: ["/a/b/", "/a/b", "/a", "/"], segments: ["", "b", "a", "/"] } + `${posixSep}a`, + { paths: [`${posixSep}a`, `${posixSep}`], segments: ["a", `${posixSep}`] } ], - ["/", { paths: ["/"], segments: [""] }] + [ + `${posixSep}a${posixSep}`, + { + paths: [`${posixSep}a${posixSep}`, `${posixSep}a`, `${posixSep}`], + segments: ["", "a", `${posixSep}`] + } + ], + [ + `${posixSep}a${posixSep}b`, + { + paths: [`${posixSep}a${posixSep}b`, `${posixSep}a`, `${posixSep}`], + segments: ["b", "a", `${posixSep}`] + } + ], + [ + `${posixSep}a${posixSep}b${posixSep}`, + { + paths: [ + `${posixSep}a${posixSep}b${posixSep}`, + `${posixSep}a${posixSep}b`, + `${posixSep}a`, + `${posixSep}` + ], + segments: ["", "b", "a", `${posixSep}`] + } + ], + [`${posixSep}`, { paths: [`${posixSep}`], segments: [""] }] ]; cases.forEach(case_ => { diff --git a/test/identifier.test.js b/test/identifier.test.js index 6d18954c..918c0f15 100644 --- a/test/identifier.test.js +++ b/test/identifier.test.js @@ -1,4 +1,5 @@ const { parseIdentifier } = require("../lib/util/identifier"); +const { posixSep } = require("./util/path-separator"); /** * @typedef {{input: string, expected: [string, string, string]}} TestSuite @@ -23,36 +24,40 @@ describe("parse identifier. edge cases", () => { /** @type {TestSuite[]} */ const tests = [ { - input: "path/#", - expected: ["path/", "", "#"] + input: `path${posixSep}#`, + expected: [`path${posixSep}`, "", "#"] }, { - input: "path/as/?", - expected: ["path/as/", "?", ""] + input: `path${posixSep}as${posixSep}?`, + expected: [`path${posixSep}as${posixSep}`, "?", ""] }, { - input: "path/#/?", - expected: ["path/", "", "#/?"] + input: `path${posixSep}#${posixSep}?`, + expected: [`path${posixSep}`, "", `#${posixSep}?`] }, { - input: "path/#repo#hash", - expected: ["path/", "", "#repo#hash"] + input: `path${posixSep}#repo#hash`, + expected: [`path${posixSep}`, "", "#repo#hash"] }, { - input: "path/#r#hash", - expected: ["path/", "", "#r#hash"] + input: `path${posixSep}#r#hash`, + expected: [`path${posixSep}`, "", "#r#hash"] }, { - input: "path/#repo/#repo2#hash", - expected: ["path/", "", "#repo/#repo2#hash"] + input: `path${posixSep}#repo${posixSep}#repo2#hash`, + expected: [`path${posixSep}`, "", `#repo${posixSep}#repo2#hash`] }, { - input: "path/#r/#r#hash", - expected: ["path/", "", "#r/#r#hash"] + input: `path${posixSep}#r${posixSep}#r#hash`, + expected: [`path${posixSep}`, "", `#r${posixSep}#r#hash`] }, { - input: "path/#/not/a/hash?not-a-query", - expected: ["path/", "", "#/not/a/hash?not-a-query"] + input: `path${posixSep}#${posixSep}not${posixSep}a${posixSep}hash?not-a-query`, + expected: [ + `path${posixSep}`, + "", + `#${posixSep}not${posixSep}a${posixSep}hash?not-a-query` + ] } ]; @@ -83,8 +88,12 @@ describe("parse identifier. Windows-like paths", () => { expected: ["path\\", "", "#r#hash"] }, { - input: "path\\#/not/a/hash?not-a-query", - expected: ["path\\", "", "#/not/a/hash?not-a-query"] + input: `path\\#${posixSep}not${posixSep}a${posixSep}hash?not-a-query`, + expected: [ + "path\\", + "", + `#${posixSep}not${posixSep}a${posixSep}hash?not-a-query` + ] } ]; diff --git a/test/importsField.test.js b/test/importsField.test.js index 5f642379..c3d93884 100644 --- a/test/importsField.test.js +++ b/test/importsField.test.js @@ -3,6 +3,11 @@ const fs = require("fs"); const { processImportsField } = require("../lib/util/entrypoints"); const ResolverFactory = require("../lib/ResolverFactory"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); /** @typedef {import("../lib/util/entrypoints").ImportsField} ImportsField */ @@ -1153,7 +1158,6 @@ describe("Process imports field", function exportsField() { }); }); }); - describe("ImportsFieldPlugin", () => { const nodeFileSystem = new CachedInputFileSystem(fs, 4000); @@ -1168,7 +1172,9 @@ describe("ImportsFieldPlugin", () => { resolver.resolve({}, fixture, "#imports-field", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "b.js")) + ); done(); }); }); @@ -1182,7 +1188,9 @@ describe("ImportsFieldPlugin", () => { (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "b.js")) + ); done(); } ); @@ -1211,7 +1219,9 @@ describe("ImportsFieldPlugin", () => { resolver.resolve({}, fixture, "#imports-field", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "b.js")) + ); done(); }); }); @@ -1228,20 +1238,33 @@ describe("ImportsFieldPlugin", () => { resolver.resolve({}, fixture, "#b", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, "a.js")) + ); done(); }); }); it("should resolve package #1", done => { - resolver.resolve({}, fixture, "#a/dist/main.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "node_modules/a/lib/main.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `#a${obps}dist${obps}main.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `node_modules${posixSep}a${posixSep}lib${posixSep}main.js` + ) + ) + ); + done(); + } + ); }); it("should resolve package #2", done => { @@ -1254,10 +1277,14 @@ describe("ImportsFieldPlugin", () => { }); it("should resolve package #3", done => { - resolver.resolve({}, fixture, "#ccc/index.js", {}, (err, result) => { + resolver.resolve({}, fixture, `#ccc${obps}index.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "node_modules/c/index.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `node_modules${posixSep}c${posixSep}index.js`) + ) + ); done(); }); }); @@ -1266,18 +1293,22 @@ describe("ImportsFieldPlugin", () => { resolver.resolve({}, fixture, "#c", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "node_modules/c/index.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `node_modules${posixSep}c${posixSep}index.js`) + ) + ); done(); }); }); it("should resolve absolute path as an imports field target", done => { - const tmpdirPrefix = path.join(fixture, "node_modules/absolute-tmp-"); + const tmpdirPrefix = path.join(fixture, `node_modules${obps}absolute-tmp-`); fs.mkdtemp(tmpdirPrefix, (err, dir) => { if (err) done(err); - const pjson = path.resolve(dir, "./package.json"); - const file = path.resolve(dir, "./index"); + const pjson = path.resolve(dir, `.${obps}package.json`); + const file = path.resolve(dir, `.${posixSep}index`); // PosixSep because we use it inside package.json (package.json handles only posix separators) fs.writeFileSync(file, ""); fs.writeFileSync(pjson, JSON.stringify({ imports: { "#a": file } })); @@ -1298,16 +1329,25 @@ describe("ImportsFieldPlugin", () => { resolver.resolve( {}, fixture, - "#a/dist/index.js", + `#a${obps}dist${obps}index.js`, { log: v => log.push(v) }, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.join(fixture, "node_modules/a/lib/index.js") + transferPathToPosix( + path.join( + fixture, + `node_modules${posixSep}a${posixSep}lib${posixSep}index.js` + ) + ) ); expect( - log.map(line => line.replace(fixture, "...").replace(/\\/g, "/")) + log.map(line => + line + .replace(transferPathToPosix(fixture), "...") + .replace(/\\/g, `${posixSep}`) + ) ).toMatchSnapshot(); done(); } @@ -1317,18 +1357,25 @@ describe("ImportsFieldPlugin", () => { it("should resolve with wildcard pattern", done => { const fixture = path.resolve( __dirname, - "./fixtures/imports-exports-wildcard/node_modules/m/" + `.${obps}fixtures${obps}imports-exports-wildcard${obps}node_modules${obps}m${obps}` ); - resolver.resolve({}, fixture, "#internal/i.js", {}, (err, result) => { + resolver.resolve({}, fixture, `#internal${obps}i.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture, "./src/internal/i.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${posixSep}src${posixSep}internal${posixSep}i.js` + ) + ) + ); done(); }); }); it("should work and throw an error on invalid imports #1", done => { - resolver.resolve({}, fixture, "#/dep", {}, (err, result) => { + resolver.resolve({}, fixture, `#${obps}dep`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Request should not start with "#\/"/); @@ -1337,7 +1384,7 @@ describe("ImportsFieldPlugin", () => { }); it("should work and throw an error on invalid imports #2", done => { - resolver.resolve({}, fixture, "#dep/", {}, (err, result) => { + resolver.resolve({}, fixture, `#dep${obps}`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -1351,22 +1398,37 @@ describe("ImportsFieldPlugin", () => { resolver.resolve({}, fixture1, "#dep", {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js") + "?foo=../"); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture1, `.${posixSep}a.js`) + `?foo=..${posixSep}` + ) + ); done(); }); }); it("should work with invalid imports #2", done => { - resolver.resolve({}, fixture1, "#dep/foo/a.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js") + "?foo=../#../"); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#dep${obps}foo${obps}a.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture1, `.${posixSep}a.js`) + + `?foo=..${posixSep}#..${posixSep}` + ) + ); + done(); + } + ); }); it("should work with invalid imports #3", done => { - resolver.resolve({}, fixture1, "#dep/bar", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}bar`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Can't resolve '#dep\/bar' in/); @@ -1375,7 +1437,7 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #3", done => { - resolver.resolve({}, fixture1, "#dep/baz", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}baz`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Can't resolve '#dep\/baz' in/); @@ -1384,43 +1446,63 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #4", done => { - resolver.resolve({}, fixture1, "#dep/baz-multi", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Can't resolve '#dep\/baz-multi' in/); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#dep${obps}baz-multi`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Can't resolve '#dep\/baz-multi' in/); + done(); + } + ); }); it("should work with invalid imports #5", done => { - resolver.resolve({}, fixture1, "#dep/baz-multi", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Can't resolve '#dep\/baz-multi' in/); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#dep${obps}baz-multi`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Can't resolve '#dep\/baz-multi' in/); + done(); + } + ); }); it("should work with invalid imports #6", done => { - resolver.resolve({}, fixture1, "#dep/pattern/a.js", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Can't resolve '#dep\/pattern\/a.js' in/); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#dep${obps}pattern${obps}a.js`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Can't resolve '#dep\/pattern\/a.js' in/); + done(); + } + ); }); it("should work with invalid imports #7", done => { - resolver.resolve({}, fixture1, "#dep/array", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}array`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture1, `.${posixSep}a.js`)) + ); done(); }); }); it("should work with invalid imports #8", done => { - resolver.resolve({}, fixture1, "#dep/array2", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}array2`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Can't resolve '#dep\/array2' in/); @@ -1429,16 +1511,18 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #9", done => { - resolver.resolve({}, fixture1, "#dep/array3", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}array3`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture1, `.${posixSep}a.js`)) + ); done(); }); }); it("should work with invalid imports #10", done => { - resolver.resolve({}, fixture1, "#dep/empty", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}empty`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch(/Can't resolve '#dep\/empty' in/); @@ -1447,34 +1531,50 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #10", done => { - resolver.resolve({}, fixture1, "#dep/with-bad", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}with-bad`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture1, `.${posixSep}a.js`)) + ); done(); }); }); it("should work with invalid imports #10", done => { - resolver.resolve({}, fixture1, "#dep/with-bad2", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js")); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#dep${obps}with-bad2`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture1, `.${posixSep}a.js`)) + ); + done(); + } + ); }); it("should work with invalid imports #11", done => { - resolver.resolve({}, fixture1, "#timezones/pdt.mjs", {}, (err, result) => { - if (!err) return done(new Error(`expect error, got ${result}`)); - expect(err).toBeInstanceOf(Error); - expect(err.message).toMatch(/Expecting folder to folder mapping/); - done(); - }); + resolver.resolve( + {}, + fixture1, + `#timezones${obps}pdt.mjs`, + {}, + (err, result) => { + if (!err) return done(new Error(`expect error, got ${result}`)); + expect(err).toBeInstanceOf(Error); + expect(err.message).toMatch(/Expecting folder to folder mapping/); + done(); + } + ); }); it("should work with invalid imports #12", done => { - resolver.resolve({}, fixture1, "#dep/multi1", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}multi1`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -1485,7 +1585,7 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #13", done => { - resolver.resolve({}, fixture1, "#dep/multi2", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}multi2`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -1496,7 +1596,7 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #13", done => { - resolver.resolve({}, fixture1, "#dep/multi1", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}multi1`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -1507,7 +1607,7 @@ describe("ImportsFieldPlugin", () => { }); it("should work with invalid imports #14", done => { - resolver.resolve({}, fixture1, "#dep/multi2", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}multi2`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); expect(err.message).toMatch( @@ -1518,10 +1618,12 @@ describe("ImportsFieldPlugin", () => { }); it("should work and resolve with array imports", done => { - resolver.resolve({}, fixture1, "#dep/multi", {}, (err, result) => { + resolver.resolve({}, fixture1, `#dep${obps}multi`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixture1, "./a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture1, `.${posixSep}a.js`)) + ); done(); }); }); diff --git a/test/incorrect-description-file.test.js b/test/incorrect-description-file.test.js index 622d4b48..06ec101f 100644 --- a/test/incorrect-description-file.test.js +++ b/test/incorrect-description-file.test.js @@ -1,17 +1,28 @@ const path = require("path"); const fs = require("fs"); const { CachedInputFileSystem, ResolverFactory } = require("../"); +const { transferPathToPosix } = require("./util/path-separator"); const fixtures = path.join(__dirname, "fixtures", "incorrect-package"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); -function p() { +// We need this function to pass win32 paths to library code +function pForLibrary() { return path.join.apply( path, [fixtures].concat(Array.prototype.slice.call(arguments)) ); } +function p() { + return transferPathToPosix( + path.join.apply( + path, + [fixtures].concat(Array.prototype.slice.call(arguments)) + ) + ); +} + describe("incorrect description file", () => { const resolver = ResolverFactory.createResolver({ useSyncFileSystemCalls: true, @@ -26,15 +37,21 @@ describe("incorrect description file", () => { called = true; } }; - resolver.resolve({}, p("pack1"), ".", ctx, function (err, result) { - if (!err) return done(new Error("No error")); - expect(err).toBeInstanceOf(Error); - expect(ctx.fileDependencies.has(p("pack1", "package.json"))).toEqual( - true - ); - expect(called).toBe(true); - done(); - }); + resolver.resolve( + {}, + pForLibrary("pack1"), + ".", + ctx, + function (err, result) { + if (!err) return done(new Error("No error")); + expect(err).toBeInstanceOf(Error); + expect(ctx.fileDependencies.has(p("pack1", "package.json"))).toEqual( + true + ); + expect(called).toBe(true); + done(); + } + ); }); it("should not resolve main in incorrect description file #2", done => { @@ -45,18 +62,24 @@ describe("incorrect description file", () => { called = true; } }; - resolver.resolve({}, p("pack2"), ".", ctx, function (err, result) { - if (!err) return done(new Error("No error")); - expect(ctx.fileDependencies.has(p("pack2", "package.json"))).toEqual( - true - ); - expect(called).toBe(true); - done(); - }); + resolver.resolve( + {}, + pForLibrary("pack2"), + ".", + ctx, + function (err, result) { + if (!err) return done(new Error("No error")); + expect(ctx.fileDependencies.has(p("pack2", "package.json"))).toEqual( + true + ); + expect(called).toBe(true); + done(); + } + ); }); it("should not resolve main in incorrect description file #3", done => { - resolver.resolve({}, p("pack2"), ".", {}, function (err, result) { + resolver.resolve({}, pForLibrary("pack2"), ".", {}, function (err, result) { if (!err) return done(new Error("No error")); expect(err).toBeInstanceOf(Error); done(); diff --git a/test/missing.test.js b/test/missing.test.js index 15f771f3..a9933511 100644 --- a/test/missing.test.js +++ b/test/missing.test.js @@ -1,5 +1,6 @@ const path = require("path"); const resolve = require("../"); +const { transferPathToPosix, obps } = require("./util/path-separator"); describe("missing", function () { /** @@ -8,7 +9,7 @@ describe("missing", function () { const testCases = [ [ path.join(__dirname, "fixtures"), - "./missing-file", + `.${obps}missing-file`, [ path.join(__dirname, "fixtures", "missing-file"), path.join(__dirname, "fixtures", "missing-file.js"), @@ -25,7 +26,7 @@ describe("missing", function () { ], [ path.join(__dirname, "fixtures"), - "missing-module/missing-file", + `missing-module${obps}missing-file`, [ path.join(__dirname, "fixtures", "node_modules", "missing-module"), path.join(__dirname, "..", "node_modules", "missing-module") @@ -33,7 +34,7 @@ describe("missing", function () { ], [ path.join(__dirname, "fixtures"), - "m1/missing-file", + `m1${obps}missing-file`, [ path.join(__dirname, "fixtures", "node_modules", "m1", "missing-file"), path.join( @@ -55,7 +56,7 @@ describe("missing", function () { ], [ path.join(__dirname, "fixtures"), - "m1/", + `m1${obps}`, [ path.join(__dirname, "fixtures", "node_modules", "m1", "index"), path.join(__dirname, "fixtures", "node_modules", "m1", "index.js"), @@ -65,7 +66,7 @@ describe("missing", function () { ], [ path.join(__dirname, "fixtures"), - "m1/a", + `m1${obps}a`, [path.join(__dirname, "fixtures", "node_modules", "m1", "a")] ] ]; @@ -75,7 +76,7 @@ describe("missing", function () { done => { const callback = function (err, filename) { expect(Array.from(missingDependencies).sort()).toEqual( - expect.arrayContaining(testCase[2].sort()) + expect.arrayContaining(testCase[2].map(transferPathToPosix).sort()) ); done(); }; @@ -92,7 +93,7 @@ describe("missing", function () { const details = err.details.split("\n"); const firstDetail = details.shift(); - expect(firstDetail).toContain(testCase[1]); + expect(firstDetail).toContain(transferPathToPosix(testCase[1])); expect(details).not.toContain(firstDetail); } done(); diff --git a/test/plugins.test.js b/test/plugins.test.js index 6a9e770d..15982d60 100644 --- a/test/plugins.test.js +++ b/test/plugins.test.js @@ -2,6 +2,11 @@ const path = require("path"); const { ResolverFactory, CloneBasenamePlugin } = require("../"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); describe("plugins", function () { it("should resolve with the CloneBasenamePlugin", done => { @@ -18,15 +23,17 @@ describe("plugins", function () { resolver.resolve( {}, __dirname, - "./fixtures/directory-default", + `.${obps}fixtures${obps}directory-default`, {}, function (err, result) { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve( - __dirname, - "fixtures/directory-default/directory-default.js" + transferPathToPosix( + path.resolve( + __dirname, + `fixtures${posixSep}directory-default${posixSep}directory-default.js` + ) ) ); done(); @@ -34,7 +41,7 @@ describe("plugins", function () { ); }); - it("should ignore 'false'/'null'/'undefined' plugins", done => { + it(`should ignore 'false'/'null'/'undefined' plugins`, done => { const FailedPlugin = class { apply() { throw new Error("FailedPlugin"); @@ -60,15 +67,17 @@ describe("plugins", function () { resolver.resolve( {}, __dirname, - "./fixtures/directory-default", + `.${obps}fixtures${obps}directory-default`, {}, function (err, result) { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve( - __dirname, - "fixtures/directory-default/directory-default.js" + transferPathToPosix( + path.resolve( + __dirname, + `fixtures${posixSep}directory-default${posixSep}directory-default.js` + ) ) ); done(); diff --git a/test/pnp.test.js b/test/pnp.test.js index 28280ff6..083624ae 100644 --- a/test/pnp.test.js +++ b/test/pnp.test.js @@ -1,6 +1,11 @@ const path = require("path"); const fs = require("fs"); const { ResolverFactory, CachedInputFileSystem } = require("../"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); const fixture = path.resolve(__dirname, "fixtures", "pnp"); @@ -8,13 +13,13 @@ const fixture = path.resolve(__dirname, "fixtures", "pnp"); let isAdmin = false; try { - fs.symlinkSync("dir", path.resolve(fixture, "pkg/symlink"), "dir"); + fs.symlinkSync("dir", path.resolve(fixture, `pkg${obps}symlink`), "dir"); isAdmin = true; } catch (e) { // ignore } try { - fs.unlinkSync(path.resolve(fixture, "pkg/symlink")); + fs.unlinkSync(path.resolve(fixture, `pkg${obps}symlink`)); } catch (e) { isAdmin = false; // ignore @@ -26,10 +31,10 @@ describe("pnp", () => { let resolver; if (isAdmin) { beforeAll(() => { - fs.symlinkSync("dir", path.resolve(fixture, "pkg/symlink"), "dir"); + fs.symlinkSync("dir", path.resolve(fixture, `pkg${obps}symlink`), "dir"); }); afterAll(() => { - fs.unlinkSync(path.resolve(fixture, "pkg/symlink")); + fs.unlinkSync(path.resolve(fixture, `pkg${obps}symlink`)); }); } beforeEach(() => { @@ -57,7 +62,7 @@ describe("pnp", () => { alias: path.resolve(fixture, "pkg") }, pnpApi, - modules: ["node_modules", path.resolve(fixture, "../pnp-a")] + modules: ["node_modules", path.resolve(fixture, `..${obps}pnp-a`)] }); resolver = ResolverFactory.createResolver({ aliasFields: ["browser"], @@ -70,24 +75,41 @@ describe("pnp", () => { modules: [ "alternative-modules", "node_modules", - path.resolve(fixture, "../pnp-a") + path.resolve(fixture, `..${obps}pnp-a`) ] }); }); it("should resolve by going through the pnp api", done => { + // TODO: find a solution how to work with pnp cause it causes some problems pnpApi.mocks.set("pkg", path.resolve(fixture, "pkg")); - resolver.resolve({}, __dirname, "pkg/dir/index.js", {}, (err, result) => { - if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/dir/index.js")); - done(); - }); + resolver.resolve( + {}, + __dirname, + `pkg${obps}dir${obps}index.js`, + {}, + (err, result) => { + if (err) return done(err); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `pkg${obps}dir${obps}index.js`) + ) + ); + done(); + } + ); }); it("should not resolve a not fully specified request when fullySpecified is set", done => { pnpApi.mocks.set("pkg", path.resolve(fixture, "pkg")); - resolver.resolve({}, __dirname, "pkg/dir/index", {}, (err, result) => { - expect(err).toBeInstanceOf(Error); - done(); - }); + resolver.resolve( + {}, + __dirname, + `pkg${obps}dir${obps}index`, + {}, + (err, result) => { + expect(err).toBeInstanceOf(Error); + done(); + } + ); }); it("should track dependency to the pnp api", done => { pnpApi.mocks.set("pkg", path.resolve(fixture, "pkg")); @@ -96,13 +118,17 @@ describe("pnp", () => { resolver.resolve( {}, __dirname, - "pkg/dir/index.js", + `pkg${obps}dir${obps}index.js`, { fileDependencies }, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/dir/index.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `pkg${obps}dir${obps}index.js`) + ) + ); expect(Array.from(fileDependencies)).toContainEqual( - path.resolve(fixture, ".pnp.js") + transferPathToPosix(path.resolve(fixture, ".pnp.js")) ); done(); } @@ -112,15 +138,19 @@ describe("pnp", () => { pnpApi.mocks.set("pkg", path.resolve(fixture, "pkg")); resolver.resolve({}, __dirname, "pkg", {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/main.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg${obps}main.js`)) + ); done(); }); }); it("should resolve namespaced module names", done => { - pnpApi.mocks.set("@user/pkg", path.resolve(fixture, "pkg")); - resolver.resolve({}, __dirname, "@user/pkg", {}, (err, result) => { + pnpApi.mocks.set(`@user${posixSep}pkg`, path.resolve(fixture, "pkg")); + resolver.resolve({}, __dirname, `@user${obps}pkg`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/main.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg${obps}main.js`)) + ); done(); }); }); @@ -132,30 +162,34 @@ describe("pnp", () => { resolverFuzzy.resolve( {}, __dirname, - "pkg/symlink", + `pkg${obps}symlink`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve(fixture, "pkg/symlink/index.js") + transferPathToPosix( + path.resolve(fixture, `pkg${obps}symlink${obps}index.js`) + ) ); done(); } ); } - : undefined + : () => {} ); it("should properly deal with other extensions", done => { - pnpApi.mocks.set("@user/pkg", path.resolve(fixture, "pkg")); + pnpApi.mocks.set(`@user${posixSep}pkg`, path.resolve(fixture, "pkg")); resolverFuzzy.resolve( {}, __dirname, - "@user/pkg/typescript", + `@user${obps}pkg${obps}typescript`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve(fixture, "pkg/typescript/index.ts") + transferPathToPosix( + path.resolve(fixture, `pkg${obps}typescript${obps}index.ts`) + ) ); done(); } @@ -166,46 +200,58 @@ describe("pnp", () => { resolverFuzzy.resolve( {}, __dirname, - "pkg/package-alias", + `pkg${obps}package-alias`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve(fixture, "pkg/package-alias/browser.js") + transferPathToPosix( + path.resolve(fixture, `pkg${obps}package-alias${obps}browser.js`) + ) ); done(); } ); }); it("should prefer pnp resolves over normal modules", done => { - pnpApi.mocks.set("m1", path.resolve(fixture, "../node_modules/m2")); + pnpApi.mocks.set( + "m1", + path.resolve(fixture, `..${obps}node_modules${obps}m2`) + ); resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "m1/b.js", + `m1${obps}b.js`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve(fixture, "../node_modules/m2/b.js") + transferPathToPosix( + path.resolve(fixture, `..${obps}node_modules${obps}m2${obps}b.js`) + ) ); done(); } ); }); it("should prefer alternative module directories over pnp", done => { - pnpApi.mocks.set("m1", path.resolve(fixture, "../node_modules/m2")); + pnpApi.mocks.set( + "m1", + path.resolve(fixture, `..${obps}node_modules${obps}m2`) + ); resolver.resolve( {}, - path.resolve(__dirname, "fixtures/prefer-pnp"), - "m1/b.js", + path.resolve(__dirname, `fixtures${obps}prefer-pnp`), + `m1${obps}b.js`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve( - __dirname, - "fixtures/prefer-pnp/alternative-modules/m1/b.js" + transferPathToPosix( + path.resolve( + __dirname, + `fixtures${obps}prefer-pnp${obps}alternative-modules${obps}m1${obps}b.js` + ) ) ); done(); @@ -213,15 +259,17 @@ describe("pnp", () => { ); }); it("should prefer alias over pnp resolves", done => { - pnpApi.mocks.set("alias", path.resolve(fixture, "pkg/dir")); + pnpApi.mocks.set("alias", path.resolve(fixture, `pkg${obps}dir`)); resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "alias/index.js", + `alias${obps}index.js`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/index.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg${obps}index.js`)) + ); done(); } ); @@ -231,11 +279,13 @@ describe("pnp", () => { resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "m2/index.js", + `m2${obps}index.js`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg/index.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg${obps}index.js`)) + ); done(); } ); @@ -244,28 +294,39 @@ describe("pnp", () => { resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "m2/a.js", + `m2${obps}a.js`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "../pnp-a/m2/a.js")); + expect(result).toEqual( + transferPathToPosix( + path.resolve(fixture, `..${obps}pnp-a${obps}m2${obps}a.js`) + ) + ); done(); } ); }); it("should fallback to alternatives when pnp doesn't manage the issuer", done => { - pnpApi.ignoredIssuers.add(path.resolve(__dirname, "fixtures") + "/"); + pnpApi.ignoredIssuers.add( + transferPathToPosix(path.resolve(__dirname, "fixtures") + `${posixSep}`) + ); // Add the wrong path on purpose to make sure the issuer is ignored pnpApi.mocks.set("m2", path.resolve(fixture, "pkg")); resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "m2/b.js", + `m2${obps}b.js`, {}, (err, result) => { if (err) return done(err); expect(result).toEqual( - path.resolve(__dirname, "fixtures/node_modules/m2/b.js") + transferPathToPosix( + path.resolve( + __dirname, + `fixtures${obps}node_modules${obps}m2${obps}b.js` + ) + ) ); done(); } @@ -280,21 +341,25 @@ describe("pnp", () => { {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg3/a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg3${obps}a.js`)) + ); done(); } ); }); it("should handle the exports field when using PnP (with sub path)", done => { - pnpApi.mocks.set("@user/m1", path.resolve(fixture, "pkg3")); + pnpApi.mocks.set(`@user${posixSep}m1`, path.resolve(fixture, "pkg3")); resolver.resolve( {}, path.resolve(__dirname, "fixtures"), - "@user/m1/x", + `@user${obps}m1${obps}x`, {}, (err, result) => { if (err) return done(err); - expect(result).toEqual(path.resolve(fixture, "pkg3/a.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixture, `pkg3${obps}a.js`)) + ); done(); } ); diff --git a/test/resolve.test.js b/test/resolve.test.js index d940b8779c669d3ae4c4e9262819950008456a38..7196535b43112bef8928950bd6251383e5c4aa2b 100644 GIT binary patch literal 8557 zcmd5>S#R7n5caF~R}gZ6YSHz&c3+AVX^N&Pke4P%^VSAgtwh-jwB&}Qd?4_D?+h%jyr=Ra*KtSSgu(_XU^hE?q51<96M?&BSISI6RAyu8(en_(PMOt)!rYceG43 zyP`vA+bx?s7ZuMmEEUmI`9)2v1VEm+(hFiI|I6qC)~qV^oWL^YRArK_scW9h$@5?F zdBk)Qt4mRpIcVOB8yAUWLQ0zH@)kI%TSs;q6s)8;uMx3Tlv&vh6rhhN0+nrHu*CP9 zFSYoc{y_`IX`b{pdG)zU%cNr$CC)O_6D8PbhuH!xLjr+GE;u#BL|)lR2lxf4dr&Fi z)*0@)MywzSyqE)butPb)Va)?$^%S$a+Dx-Mip*@5JxhZ5i+}EBvw*xImX}r~PoSBJ zTz7b-hw=U`5dPpjwC_2)NU;n3hw5z4_-F~Xo)S3Dx5|t() zVD1^(p7H+ErCjJsDvh(5U|$N>_fLjzDOmTk^_ z*c~*j6>K5+Zq6{CABbSYzBlq@x(er8NYDrXtqJ;9^d69%x?DlYIE+4SRb~^=ZGHr^vQZ0xhTL@ zNy_#8Z2%0{bRBX%xCQxr4Z}EiL7Edt{vo3h@)lP{Tv2%~nTAw8tdd=~{?*w)YREuK z!2}0>+TPpi4Fv42_k{h38tXC$Jm8ZUb)eLYLup8DCn@&X#I!p#ZQl68EY=qGdqh+VtC^Un{;PU2=GxZ`& zGL@>jhXvH5mbSm|W2z23W7G_7yJ;HQLDbJt4Qc{8W4OW)L(A6#ZAfDsARkI$fI7Y( zcK}aOUJbZbP`~EJXsyTSP@(?-jNQjBDFo)3w!8#!)n7uj!>7+s*6>g93#5^R`@z8F zt-8i@;k{%~F6ncN{$*zZ0WUjZd}G>9GhAZ1?BC)ruEVzUR)!02t8Y*n;h!v9*6e?q zOv5+gARCJHh<5jKYc0%oSk4NlF_AUZ*Ay~=Iz>Q_jL~8dYCL$?PZ0EcBmaaZ{W1(q z1`@FY@C2+AK)HpOfDJQ6#&dd8gWP8gicmRe?kWN~xMDdakR~>t8)%(ET}yGTs66pG z*G?|9n_2ZEZ%^0pNwW_hDj?r$lF3wE5-1H~{s3!Dp`N#eGO@-)9Wq2k%c7rJ>~vx} zLH)Tb`tj{FoW$=F06d?J(0nY6O5hSU2-FgM;3G7@pd?EbB?*V`9+zFs`w8SCgb1h3 zWBWYh_MlXMEaCdZ!mE?baJRTD50OAM1?L`aOy}<)sXw`)p>4TMqI8BC*1La@iHb77wp2RZ*%)* z{RzGkgD;P2+`|R!$1JR(IZ@YXm@#zMR@=HJ1#<`U!;~aw%$OhUECr3%uoQ-c(4xr% z2pJ@5eoz_1pZ#YmtgW&-yvC0PKvzwBro?8hBzsqVr^P-+r+z5uJM$ z_1F2CM;WZagvgto1J^Y>T{6vq zOC;tX)VbgwQnPJQP7vW)*kOhT;3pS%FrK-N*m*A^2dgU5riyh#s%9Bqb^G8uzfBUS zaKYTR>b?LUhwk)XkGpm~bPF&u{FGsqFDHZ{;+Yn#qh-qa?0Q|QZJB4}q2ZYecCe{Z zEx)Epn$aP!!%Hs*3GZC&IALENm0u5aNN0}=b-=z~gh>w%zkOcV@P&t1hdR=7LK43E z<~ric!EU(Amxgiw4R0&2*O-KN{;Tu~5kvyx&6vLZK`b4cbBk-(vS+CpL1b%R!8NQZnVJ`Dc{3!MY~_E6LL^A>JAw l?-O>!yYSqXZSKY&*l6<%NjEUL@rrU=qAr+8)Zs;P?;j`5YTN(- diff --git a/test/restrictions.test.js b/test/restrictions.test.js index 65561a1c..b1165174 100644 --- a/test/restrictions.test.js +++ b/test/restrictions.test.js @@ -2,6 +2,11 @@ const path = require("path"); const fs = require("fs"); const ResolverFactory = require("../lib/ResolverFactory"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); const fixture = path.resolve(__dirname, "fixtures", "restrictions"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); @@ -33,7 +38,9 @@ describe("restrictions", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/pck1/index.css") + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}pck1${obps}index.css`) + ) ); done(); }); @@ -65,7 +72,9 @@ describe("restrictions", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/pck2/index.css") + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}pck2${obps}index.css`) + ) ); done(); }); @@ -90,14 +99,22 @@ describe("restrictions", () => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "node_modules/pck2/index.css") + transferPathToPosix( + path.resolve(fixture, `node_modules${obps}pck2${obps}index.css`) + ) ); expect( log.map(line => line - .replace(path.resolve(__dirname, ".."), "...") - .replace(path.resolve(__dirname, ".."), "...") - .replace(/\\/g, "/") + .replace( + transferPathToPosix(path.resolve(__dirname, "..")), + "..." + ) + .replace( + transferPathToPosix(path.resolve(__dirname, "..")), + "..." + ) + .replace(/\\/g, `${posixSep}`) ) ).toMatchSnapshot(); done(); diff --git a/test/roots.test.js b/test/roots.test.js index 55cda5b1..875aa8ea 100644 --- a/test/roots.test.js +++ b/test/roots.test.js @@ -2,6 +2,11 @@ const path = require("path"); const fs = require("fs"); const ResolverFactory = require("../lib/ResolverFactory"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); describe("roots", () => { const fixtures = path.resolve(__dirname, "fixtures"); @@ -9,7 +14,7 @@ describe("roots", () => { const resolver = ResolverFactory.createResolver({ extensions: [".js"], alias: { - foo: "/fixtures" + foo: `${obps}fixtures` }, roots: [__dirname, fixtures], fileSystem @@ -18,7 +23,7 @@ describe("roots", () => { const resolverPreferAbsolute = ResolverFactory.createResolver({ extensions: [".js"], alias: { - foo: "/fixtures" + foo: `${obps}fixtures` }, roots: [__dirname, fixtures], fileSystem, @@ -42,43 +47,66 @@ describe("roots", () => { }); it("should respect roots option", done => { - resolver.resolve({}, fixtures, "/fixtures/b.js", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "b.js")); - done(); - }); + resolver.resolve( + {}, + fixtures, + `${obps}fixtures${obps}b.js`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "b.js")) + ); + done(); + } + ); }); it("should try another root option, if it exists", done => { - resolver.resolve({}, fixtures, "/b.js", {}, (err, result) => { + resolver.resolve({}, fixtures, `${obps}b.js`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "b.js")) + ); done(); }); }); it("should respect extension", done => { - resolver.resolve({}, fixtures, "/fixtures/b", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "b.js")); - done(); - }); + resolver.resolve( + {}, + fixtures, + `${obps}fixtures${obps}b`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "b.js")) + ); + done(); + } + ); }); it("should resolve in directory", done => { resolver.resolve( {}, fixtures, - "/fixtures/extensions/dir", + `${obps}fixtures${obps}extensions${obps}dir`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixtures, "extensions/dir/index.js") + transferPathToPosix( + path.resolve( + fixtures, + `extensions${posixSep}dir${posixSep}index.js` + ) + ) ); done(); } @@ -86,10 +114,12 @@ describe("roots", () => { }); it("should respect aliases", done => { - resolver.resolve({}, fixtures, "foo/b", {}, (err, result) => { + resolver.resolve({}, fixtures, `foo${obps}b`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "b.js")) + ); done(); }); }); @@ -98,19 +128,21 @@ describe("roots", () => { contextResolver.resolve( {}, fixtures, - "/fixtures/lib", + `${obps}fixtures${obps}lib`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "lib")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "lib")) + ); done(); } ); }); it("should not work with relative path", done => { - resolver.resolve({}, fixtures, "fixtures/b.js", {}, (err, result) => { + resolver.resolve({}, fixtures, `fixtures${obps}b.js`, {}, (err, result) => { if (!err) return done(new Error(`expect error, got ${result}`)); expect(err).toBeInstanceOf(Error); done(); @@ -126,7 +158,9 @@ describe("roots", () => { (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); - expect(result).toEqual(path.resolve(fixtures, "b.js")); + expect(result).toEqual( + transferPathToPosix(path.resolve(fixtures, "b.js")) + ); done(); } ); diff --git a/test/scoped-packages.test.js b/test/scoped-packages.test.js index 0df20ab5..6ec91e88 100644 --- a/test/scoped-packages.test.js +++ b/test/scoped-packages.test.js @@ -1,6 +1,7 @@ const path = require("path"); const fs = require("fs"); const { CachedInputFileSystem, ResolverFactory } = require("../"); +const { transferPathToPosix, obps } = require("./util/path-separator"); const fixture = path.join(__dirname, "fixtures", "scoped"); @@ -13,35 +14,56 @@ const resolver = ResolverFactory.createResolver({ describe("scoped-packages", () => { it("main field should work", done => { - resolver.resolve({}, fixture, "@scope/pack1", {}, (err, result) => { + resolver.resolve({}, fixture, `@scope${obps}pack1`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/@scope/pack1/main.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}@scope${obps}pack1${obps}main.js` + ) + ) ); done(); }); }); it("browser field should work", done => { - resolver.resolve({}, fixture, "@scope/pack2", {}, (err, result) => { + resolver.resolve({}, fixture, `@scope${obps}pack2`, {}, (err, result) => { if (err) return done(err); if (!result) return done(new Error("No result")); expect(result).toEqual( - path.resolve(fixture, "./node_modules/@scope/pack2/main.js") + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}@scope${obps}pack2${obps}main.js` + ) + ) ); done(); }); }); it("folder request should work", done => { - resolver.resolve({}, fixture, "@scope/pack2/lib", {}, (err, result) => { - if (err) return done(err); - if (!result) return done(new Error("No result")); - expect(result).toEqual( - path.resolve(fixture, "./node_modules/@scope/pack2/lib/index.js") - ); - done(); - }); + resolver.resolve( + {}, + fixture, + `@scope${obps}pack2${obps}lib`, + {}, + (err, result) => { + if (err) return done(err); + if (!result) return done(new Error("No result")); + expect(result).toEqual( + transferPathToPosix( + path.resolve( + fixture, + `.${obps}node_modules${obps}@scope${obps}pack2${obps}lib${obps}index.js` + ) + ) + ); + done(); + } + ); }); }); diff --git a/test/simple.test.js b/test/simple.test.js index 22d439df..67fa96ed 100644 --- a/test/simple.test.js +++ b/test/simple.test.js @@ -1,14 +1,15 @@ const path = require("path"); const resolve = require("../"); +const { transferPathToPosix, obps } = require("./util/path-separator"); describe("simple", () => { const pathsToIt = [ - [__dirname, "../lib/index", "direct"], + [__dirname, `..${obps}lib${obps}index`, "direct"], [__dirname, "..", "as directory"], - [path.join(__dirname, "..", ".."), "./enhanced-resolve", "as module"], + [path.join(__dirname, "..", ".."), `.${obps}enhanced-resolve`, "as module"], [ path.join(__dirname, "..", ".."), - "./enhanced-resolve/lib/index", + `.${obps}enhanced-resolve${obps}lib${obps}index`, "in module" ] ]; @@ -22,7 +23,9 @@ describe("simple", () => { expect(filename).toBeDefined(); expect(typeof filename).toEqual("string"); - expect(filename).toEqual(path.join(__dirname, "..", "lib", "index.js")); + expect(filename).toEqual( + transferPathToPosix(path.join(__dirname, "..", "lib", "index.js")) + ); done(); }); }); @@ -31,7 +34,9 @@ describe("simple", () => { expect(filename).toBeDefined(); expect(typeof filename).toEqual("string"); - expect(filename).toEqual(path.join(__dirname, "..", "lib", "index.js")); + expect(filename).toEqual( + transferPathToPosix(path.join(__dirname, "..", "lib", "index.js")) + ); }); }); }); diff --git a/test/symlink.test.js b/test/symlink.test.js index b90755c4..6e35dc64 100644 --- a/test/symlink.test.js +++ b/test/symlink.test.js @@ -2,6 +2,7 @@ const path = require("path"); const fs = require("fs"); const { platform } = require("os"); const resolve = require("../"); +const { obps } = require("./util/path-separator"); const tempPath = path.join(__dirname, "temp"); @@ -108,103 +109,115 @@ describe("symlink", () => { }); [ - [tempPath, "./index.js", "with a symlink to a file"], - [tempPath, "./node.relative.js", "with a relative symlink to a file"], + [tempPath, `.${obps}index.js`, "with a symlink to a file"], [ tempPath, - "./node.relative.sym.js", + `.${obps}node.relative.js`, + "with a relative symlink to a file" + ], + [ + tempPath, + `.${obps}node.relative.sym.js`, "with a relative symlink to a symlink to a file" ], - [tempPath, "./lib/index.js", "with a symlink to a directory 1"], - [tempPath, "./this/lib/index.js", "with a symlink to a directory 2"], [ tempPath, - "./this/test/temp/index.js", + `.${obps}lib${obps}index.js`, + "with a symlink to a directory 1" + ], + [ + tempPath, + `.${obps}this${obps}lib${obps}index.js`, + "with a symlink to a directory 2" + ], + [ + tempPath, + `.${obps}this${obps}test${obps}temp${obps}index.js`, "with multiple symlinks in the path 1" ], [ tempPath, - "./this/test/temp/lib/index.js", + `.${obps}this${obps}test${obps}temp${obps}lib${obps}index.js`, "with multiple symlinks in the path 2" ], [ tempPath, - "./this/test/temp/this/lib/index.js", + `.${obps}this${obps}test${obps}temp${obps}this${obps}lib${obps}index.js`, "with multiple symlinks in the path 3" ], [ tempPath, - "./that/lib/index.js", + `.${obps}that${obps}lib${obps}index.js`, "with a symlink to a directory 2 (chained)" ], [ tempPath, - "./that/test/temp/index.js", + `.${obps}that${obps}test${obps}temp${obps}index.js`, "with multiple symlinks in the path 1 (chained)" ], [ tempPath, - "./that/test/temp/lib/index.js", + `.${obps}that${obps}test${obps}temp${obps}lib${obps}index.js`, "with multiple symlinks in the path 2 (chained)" ], [ tempPath, - "./that/test/temp/that/lib/index.js", + `.${obps}that${obps}test${obps}temp${obps}that${obps}lib${obps}index.js`, "with multiple symlinks in the path 3 (chained)" ], [ path.join(tempPath, "lib"), - "./index.js", + `.${obps}index.js`, "with symlinked directory as context 1" ], [ path.join(tempPath, "this"), - "./lib/index.js", + `.${obps}lib${obps}index.js`, "with symlinked directory as context 2" ], [ path.join(tempPath, "this"), - "./test/temp/lib/index.js", + `.${obps}test${obps}temp${obps}lib${obps}index.js`, "with symlinked directory as context and in path" ], [ path.join(tempPath, "this", "lib"), - "./index.js", + `.${obps}index.js`, "with symlinked directory in context path" ], [ path.join(tempPath, "this", "test"), - "./temp/index.js", + `.${obps}temp${obps}index.js`, "with symlinked directory in context path and symlinked file" ], [ path.join(tempPath, "this", "test"), - "./temp/lib/index.js", + `.${obps}temp${obps}lib${obps}index.js`, "with symlinked directory in context path and symlinked directory" ], [ path.join(tempPath, "that"), - "./lib/index.js", + `.${obps}lib${obps}index.js`, "with symlinked directory as context 2 (chained)" ], [ path.join(tempPath, "that"), - "./test/temp/lib/index.js", + `.${obps}test${obps}temp${obps}lib${obps}index.js`, "with symlinked directory as context and in path (chained)" ], [ path.join(tempPath, "that", "lib"), - "./index.js", + `.${obps}index.js`, "with symlinked directory in context path (chained)" ], [ path.join(tempPath, "that", "test"), - "./temp/index.js", + `.${obps}temp${obps}index.js`, "with symlinked directory in context path and symlinked file (chained)" ], [ path.join(tempPath, "that", "test"), - "./temp/lib/index.js", + `.${obps}temp${obps}lib${obps}index.js`, "with symlinked directory in context path and symlinked directory (chained)" ] ].forEach(function (pathToIt) { @@ -242,6 +255,6 @@ describe("symlink", () => { }); }); } else { - it("cannot test symlinks because we have no permission to create them"); + it("cannot test symlinks because we have no permission to create them", () => {}); } }); diff --git a/test/unsafe-cache.test.js b/test/unsafe-cache.test.js index cbcab00a..36d91f3a 100644 --- a/test/unsafe-cache.test.js +++ b/test/unsafe-cache.test.js @@ -1,5 +1,6 @@ const path = require("path"); const resolve = require("../"); +const { obps } = require("./util/path-separator"); describe("unsafe-cache", () => { let cache; @@ -26,7 +27,7 @@ describe("unsafe-cache", () => { it("should cache request", done => { cachedResolve( path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(Object.keys(cache)).toHaveLength(1); @@ -37,7 +38,7 @@ describe("unsafe-cache", () => { }); cachedResolve( path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(result).toEqual("yep"); @@ -51,7 +52,7 @@ describe("unsafe-cache", () => { cachedResolve( context, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(Object.keys(cache)).toHaveLength(1); @@ -63,7 +64,7 @@ describe("unsafe-cache", () => { cachedResolve( otherContext, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(result).not.toEqual("yep"); @@ -76,7 +77,7 @@ describe("unsafe-cache", () => { it("should not return from cache if query does not match", done => { cachedResolve( path.join(__dirname, "fixtures"), - "m2/b?query", + `m2${obps}b?query`, function (err, result) { if (err) return done(err); expect(Object.keys(cache)).toHaveLength(1); @@ -87,7 +88,7 @@ describe("unsafe-cache", () => { }); cachedResolve( path.join(__dirname, "fixtures"), - "m2/b?query2", + `m2${obps}b?query2`, function (err, result) { if (err) return done(err); expect(result).not.toEqual("yep"); @@ -111,7 +112,7 @@ describe("unsafe-cache", () => { cachedResolve( context, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(Object.keys(cache)).toHaveLength(1); @@ -123,7 +124,7 @@ describe("unsafe-cache", () => { cachedResolve( context, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(result).toEqual("yep"); @@ -137,7 +138,7 @@ describe("unsafe-cache", () => { cachedResolve( context, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(Object.keys(cache)).toHaveLength(1); @@ -149,7 +150,7 @@ describe("unsafe-cache", () => { cachedResolve( otherContext, path.join(__dirname, "fixtures"), - "m2/b", + `m2${obps}b`, function (err, result) { if (err) return done(err); expect(result).toEqual("yep"); diff --git a/test/util/path-separator.js b/test/util/path-separator.js new file mode 100644 index 00000000..ad0a6f95 --- /dev/null +++ b/test/util/path-separator.js @@ -0,0 +1,35 @@ +const path = require('path'); + +// Should be used in comparing results: inside .isEqual(...) or another similar function +// Also sometimes it's necessary to use posixSep in executing process of library (thing inside expect): +// aliasFields, importFields, exportFields - these things require posix path separator by the Node.js +// Documentation reference for exports field for example: +// "All paths defined in the "exports" must be relative file URLs starting with './'" (https://nodejs.org/api/packages.html#exports)\ +// Exception in tests: when we pass aliasFields, importFields, exportFields right to the library function and not parse it from package.json file itself, +// we should correctly handle osBasedPathSeparator (obps) also. +const posixPathSeparator = '/'; +const absoluteOsBasedResolvedPath = path.sep === '/' ? '/' : 'X:/'; + +// Should be used on executing library code in tests: inside expect(...) or another similar function +const osBasedPathSeparator = path.sep; +// If path starts with posix path separator, we should use win32 absolute path in tests +const absoluteOsBasedPath = path.sep === '/' ? '/' : 'X:\\'; + +// Test should be executed with win32 path separators, but result of the test should be compared against posix path separators. +// Concept: we pass "X:\\" or "..\\new\\path" but the library takes responsibility to transform win32 path separator to posix path separator +// that's why we receive results like "X:/new/path" - win32 path but with posix separators. Windows can handle posix separator correct, so +// we can use it in our interest - to make support for Windows paths easier. +// With this idea in mind, we can write all the code in project based on single difference in win32 and posix paths - absolute paths. Everything else is going to work the same way on different OS. + +// This function is used to transfer path from win32 to posix path separator. It usually used in tests to compare results. We can omit this by refactor all the existing tests +// where a test use something like this "path.resolve(fixture, '/example/index.js')" code in expecting result. Right now, I'm solving another problem, so I'm not going to do it right now - just to make less +// changes in existing tests and make this transition to Windows-friendly code easier. +const transferPathToPosix = (path) => path.replace(/\\/g, '/'); + +module.exports = { + absoluteOsBasedPath, + absoluteOsBasedResolvedPath, + posixSep: posixPathSeparator, + obps: osBasedPathSeparator, + transferPathToPosix, +}; diff --git a/test/yield.test.js b/test/yield.test.js index 90568459..c77ab2b9 100644 --- a/test/yield.test.js +++ b/test/yield.test.js @@ -3,18 +3,32 @@ const fs = require("fs"); const { ResolverFactory } = require("../"); const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); +const { + posixSep, + transferPathToPosix, + obps +} = require("./util/path-separator"); /** @typedef {import("../lib/Resolver").ResolveContext} ResolveContext */ /** @typedef {ResolveContext & Required>} StrictResolveContext */ +// Functions below sometime handle transferPathToPosix and based on reading of test file you can see, that +// sometimes absolute paths started with obps (osBasedPathSeparator) and not absoluteOsBasedPath. That's because we use path.join too much in this test, +// and it works tricky on platforms: +// > path.posix.join('/abc/ab', '/abc/de') -> '/abc/ab/abc/de' (correct path after all, ) +// > path.win32.join('X:\\a', 'X:\\b') -> 'X:\\a\\X:\\b' (not so correct when we pass two absolute paths to path.join) +// That's why we use obps sometimes, because: +// > path.join("X:\\example", "\case") -> 'X:\\example\\case' const nodeFileSystem = new CachedInputFileSystem(fs, 4000); const fixtures = path.resolve(__dirname, "fixtures", "yield"); -const makeFixturePaths = paths => +const makeFixturePathsForLibrary = paths => paths.map(pth => (pth ? path.join(fixtures, pth) : pth)); +const makeFixturePaths = paths => + paths.map(pth => (pth ? transferPathToPosix(path.join(fixtures, pth)) : pth)); const contextifyDependencies = paths => Array.from(paths) - .filter(pth => pth.startsWith(fixtures)) - .map(pth => pth.slice(fixtures.length).split(path.sep).join("/")) + .filter(pth => pth.startsWith(transferPathToPosix(fixtures))) + .map(pth => pth.slice(transferPathToPosix(fixtures).length)) .sort(); const beatifyLogs = logs => logs.map(l => { @@ -22,7 +36,8 @@ const beatifyLogs = logs => l ); if (match) return `${match[1]}using description file ${match[2]}`; - while (l.includes(fixtures)) l = l.replace(fixtures, "fixtures"); + while (l.includes(transferPathToPosix(fixtures))) + l = l.replace(transferPathToPosix(fixtures), "fixtures"); return l; }); @@ -30,7 +45,10 @@ describe("should resolve all aliases", () => { const resolver = ResolverFactory.createResolver({ extensions: [".js"], alias: { - index: makeFixturePaths(["/a/foo", "/a/foo-2"]), + index: makeFixturePathsForLibrary([ + `${obps}a${obps}foo`, + `${obps}a${obps}foo-2` + ]), foo: false }, aliasFields: ["browser"], @@ -38,7 +56,7 @@ describe("should resolve all aliases", () => { }); const modulesResolver = ResolverFactory.createResolver({ extensions: [".js"], - modules: makeFixturePaths(["a", "b"]), + modules: makeFixturePathsForLibrary(["a", "b"]), fileSystem: nodeFileSystem }); @@ -56,27 +74,32 @@ describe("should resolve all aliases", () => { missingDependencies }; - resolver.resolve({}, fixtures, "index/b", context, (err, result) => { + resolver.resolve({}, fixtures, `index${obps}b`, context, (err, result) => { expect(err).toEqual(null); expect(result).toBeUndefined(); - expect(paths).toEqual(makeFixturePaths(["/a/foo/b", "/a/foo-2/b"])); + expect(paths).toEqual( + makeFixturePaths([ + `${obps}a${obps}foo${obps}b`, + `${obps}a${obps}foo-2${obps}b` + ]) + ); expect(contextifyDependencies(fileDependencies)).toEqual([ "", - "/a", - "/a/foo", - "/a/foo-2", - "/a/foo-2/b", - "/a/foo/b" + `${posixSep}a`, + `${posixSep}a${posixSep}foo`, + `${posixSep}a${posixSep}foo-2`, + `${posixSep}a${posixSep}foo-2${posixSep}b`, + `${posixSep}a${posixSep}foo${posixSep}b` ]); expect(contextifyDependencies(missingDependencies)).toEqual([ - "/a/foo-2/b", - "/a/foo-2/b.js", - "/a/foo-2/package.json", - "/a/foo/b", - "/a/foo/b.js", - "/a/foo/package.json", - "/a/package.json", - "/package.json" + `${posixSep}a${posixSep}foo-2${posixSep}b`, + `${posixSep}a${posixSep}foo-2${posixSep}b.js`, + `${posixSep}a${posixSep}foo-2${posixSep}package.json`, + `${posixSep}a${posixSep}foo${posixSep}b`, + `${posixSep}a${posixSep}foo${posixSep}b.js`, + `${posixSep}a${posixSep}foo${posixSep}package.json`, + `${posixSep}a${posixSep}package.json`, + `${posixSep}package.json` ]); expect(Array.from(contextDependencies).sort()).toEqual([]); done(); @@ -97,33 +120,44 @@ describe("should resolve all aliases", () => { missingDependencies }; - modulesResolver.resolve({}, fixtures, "foo/a", context, (err, result) => { - expect(err).toEqual(null); - expect(result).toBeUndefined(); - expect(paths).toEqual(makeFixturePaths(["/a/foo/a", "/b/foo/a"])); - expect(contextifyDependencies(fileDependencies)).toEqual([ - "", - "/a", - "/a/foo", - "/a/foo/a", - "/b", - "/b/foo", - "/b/foo/a" - ]); - expect(contextifyDependencies(missingDependencies)).toEqual([ - "/a/foo/a", - "/a/foo/a.js", - "/a/foo/package.json", - "/a/package.json", - "/b/foo/a", - "/b/foo/a.js", - "/b/foo/package.json", - "/b/package.json", - "/package.json" - ]); - expect(Array.from(contextDependencies).sort()).toEqual([]); - done(); - }); + modulesResolver.resolve( + {}, + fixtures, + `foo${obps}a`, + context, + (err, result) => { + expect(err).toEqual(null); + expect(result).toBeUndefined(); + expect(paths).toEqual( + makeFixturePaths([ + `${obps}a${obps}foo${obps}a`, + `${obps}b${obps}foo${obps}a` + ]) + ); + expect(contextifyDependencies(fileDependencies)).toEqual([ + "", + `${posixSep}a`, + `${posixSep}a${posixSep}foo`, + `${posixSep}a${posixSep}foo${posixSep}a`, + `${posixSep}b`, + `${posixSep}b${posixSep}foo`, + `${posixSep}b${posixSep}foo${posixSep}a` + ]); + expect(contextifyDependencies(missingDependencies)).toEqual([ + `${posixSep}a${posixSep}foo${posixSep}a`, + `${posixSep}a${posixSep}foo${posixSep}a.js`, + `${posixSep}a${posixSep}foo${posixSep}package.json`, + `${posixSep}a${posixSep}package.json`, + `${posixSep}b${posixSep}foo${posixSep}a`, + `${posixSep}b${posixSep}foo${posixSep}a.js`, + `${posixSep}b${posixSep}foo${posixSep}package.json`, + `${posixSep}b${posixSep}package.json`, + `${posixSep}package.json` + ]); + expect(Array.from(contextDependencies).sort()).toEqual([]); + done(); + } + ); }); it("should yield c file", done => { @@ -134,10 +168,10 @@ describe("should resolve all aliases", () => { yield: yield_ }; - resolver.resolve({}, fixtures, "index/c", context, (err, result) => { + resolver.resolve({}, fixtures, `index${obps}c`, context, (err, result) => { expect(err).toEqual(null); expect(result).toBeUndefined(); - expect(paths).toEqual(makeFixturePaths(["/a/foo-2/c"])); + expect(paths).toEqual(makeFixturePaths([`${obps}a${obps}foo-2${obps}c`])); done(); }); }); @@ -162,8 +196,8 @@ describe("should resolve all aliases", () => { expect(paths).toEqual([false]); expect(contextifyDependencies(fileDependencies)).toEqual([]); expect(contextifyDependencies(missingDependencies)).toEqual([ - "/node_modules", - "/package.json" + `${posixSep}node_modules`, + `${posixSep}package.json` ]); expect(Array.from(contextDependencies).sort()).toEqual([]); done(); @@ -184,25 +218,31 @@ describe("should resolve all aliases", () => { missingDependencies }; - resolver.resolve({}, fixtures, "index/unknown", context, (err, result) => { - expect(err).not.toEqual(null); - expect(err).not.toBeUndefined(); - expect(result).toBeUndefined(); - expect(paths).toEqual([]); - expect(contextifyDependencies(fileDependencies)).toEqual([]); - expect(contextifyDependencies(missingDependencies)).toEqual([ - "/a/foo-2/package.json", - "/a/foo-2/unknown", - "/a/foo-2/unknown.js", - "/a/foo/package.json", - "/a/foo/unknown", - "/a/foo/unknown.js", - "/a/package.json", - "/package.json" - ]); - expect(Array.from(contextDependencies).sort()).toEqual([]); - done(); - }); + resolver.resolve( + {}, + fixtures, + `index${obps}unknown`, + context, + (err, result) => { + expect(err).not.toEqual(null); + expect(err).not.toBeUndefined(); + expect(result).toBeUndefined(); + expect(paths).toEqual([]); + expect(contextifyDependencies(fileDependencies)).toEqual([]); + expect(contextifyDependencies(missingDependencies)).toEqual([ + `${posixSep}a${posixSep}foo-2${posixSep}package.json`, + `${posixSep}a${posixSep}foo-2${posixSep}unknown`, + `${posixSep}a${posixSep}foo-2${posixSep}unknown.js`, + `${posixSep}a${posixSep}foo${posixSep}package.json`, + `${posixSep}a${posixSep}foo${posixSep}unknown`, + `${posixSep}a${posixSep}foo${posixSep}unknown.js`, + `${posixSep}a${posixSep}package.json`, + `${posixSep}package.json` + ]); + expect(Array.from(contextDependencies).sort()).toEqual([]); + done(); + } + ); }); describe("resolve alias field", () => { @@ -210,7 +250,7 @@ describe("should resolve all aliases", () => { const resolver = ResolverFactory.createResolver({ extensions: [".js"], alias: { - index: makeFixturePaths(["/c/foo"]) + index: makeFixturePathsForLibrary([`${obps}c${obps}foo`]) }, aliasFields: ["browser"], fileSystem: nodeFileSystem @@ -233,43 +273,49 @@ describe("should resolve all aliases", () => { log: l => logs.push(l) }; - resolver.resolve({}, fixtures, "index/a", context, (err, result) => { - calls++; - expect(calls).toEqual(1); - expect(err).toEqual(null); - expect(result).toBeUndefined(); - expect(paths).toEqual([false]); - expect(contextifyDependencies(fileDependencies)).toEqual([ - "/c/foo/package.json" - ]); - expect(contextifyDependencies(missingDependencies)).toEqual([ - "/c/foo/a", - "/c/foo/a.js", - "/package.json" - ]); - expect(Array.from(contextDependencies).sort()).toEqual([]); + resolver.resolve( + {}, + fixtures, + `index${obps}a`, + context, + (err, result) => { + calls++; + expect(calls).toEqual(1); + expect(err).toEqual(null); + expect(result).toBeUndefined(); + expect(paths).toEqual([false]); + expect(contextifyDependencies(fileDependencies)).toEqual([ + `${posixSep}c${posixSep}foo${posixSep}package.json` + ]); + expect(contextifyDependencies(missingDependencies)).toEqual([ + `${posixSep}c${posixSep}foo${posixSep}a`, + `${posixSep}c${posixSep}foo${posixSep}a.js`, + `${posixSep}package.json` + ]); + expect(Array.from(contextDependencies).sort()).toEqual([]); - expect(beatifyLogs(logs)).toEqual([ - "resolve 'index/a' in 'fixtures'", - " Parsed request is a module", - " using description file (relative path: ./test/fixtures/yield)", - ` aliased with mapping 'index': '${["fixtures", "c", "foo"].join( - path.sep - )}' to '${["fixtures", "c", "foo"].join(path.sep)}/a'`, - " using description file (relative path: ./test/fixtures/yield)", - " using description file (relative path: ./a)", - " .js", - ` ${["fixtures", "c", "foo", "a.js"].join( - path.sep - )} doesn't exist`, - " as directory", - ` ${["fixtures", "c", "foo", "a"].join( - path.sep - )} is not a directory` - ]); + expect(beatifyLogs(logs)).toEqual([ + `resolve 'index${posixSep}a' in 'fixtures'`, + " Parsed request is a module", + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, + ` aliased with mapping 'index': '${["fixtures", "c", "foo"].join( + posixSep + )}' to '${["fixtures", "c", "foo"].join(posixSep)}${posixSep}a'`, + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, + ` using description file (relative path: .${posixSep}a)`, + " .js", + ` ${["fixtures", "c", "foo", "a.js"].join( + posixSep + )} doesn't exist`, + " as directory", + ` ${["fixtures", "c", "foo", "a"].join( + posixSep + )} is not a directory` + ]); - done(); - }); + done(); + } + ); }); describe("alias + alias field", () => { @@ -277,59 +323,59 @@ describe("should resolve all aliases", () => { ResolverFactory.createResolver({ extensions: [".js"], alias: { - index: makeFixturePaths(aliases) + index: makeFixturePathsForLibrary(aliases) }, aliasFields: ["browser"], fileSystem: nodeFileSystem }); const cLog = [ ` aliased with mapping 'index': '${["fixtures", "c", "foo"].join( - path.sep - )}' to '${["fixtures", "c", "foo"].join(path.sep)}/a'`, - " using description file (relative path: ./test/fixtures/yield)", - " using description file (relative path: ./a)", + posixSep + )}' to '${["fixtures", "c", "foo"].join(posixSep)}${posixSep}a'`, + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, + ` using description file (relative path: .${posixSep}a)`, " .js", ` ${["fixtures", "c", "foo", "a.js"].join( - path.sep + posixSep )} doesn't exist`, " as directory", ` ${["fixtures", "c", "foo", "a"].join( - path.sep + posixSep )} is not a directory` ]; const aLog = [ ` aliased with mapping 'index': '${["fixtures", "a", "foo"].join( - path.sep - )}' to '${["fixtures", "a", "foo"].join(path.sep)}/a'`, - " using description file (relative path: ./test/fixtures/yield)", - " using description file (relative path: ./test/fixtures/yield/a/foo/a)", + posixSep + )}' to '${["fixtures", "a", "foo"].join(posixSep)}${posixSep}a'`, + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield${posixSep}a${posixSep}foo${posixSep}a)`, " no extension", ` existing file: ${["fixtures", "a", "foo", "a"].join( - path.sep + posixSep )}`, ` reporting result ${["fixtures", "a", "foo", "a"].join( - path.sep + posixSep )}`, " .js", ` ${["fixtures", "a", "foo", "a.js"].join( - path.sep + posixSep )} doesn't exist`, " as directory", ` ${["fixtures", "a", "foo", "a"].join( - path.sep + posixSep )} is not a directory` ]; let resolver; it("default order", done => { - resolver = createResolver(["/c/foo", "/a/foo"]); + resolver = createResolver([`${obps}c${obps}foo`, `${obps}a${obps}foo`]); run( done, - [false, "/a/foo/a"], + [false, `${posixSep}a${posixSep}foo${posixSep}a`], [ - "resolve 'index/a' in 'fixtures'", + `resolve 'index${posixSep}a' in 'fixtures'`, " Parsed request is a module", - " using description file (relative path: ./test/fixtures/yield)", + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, ...cLog, ...aLog ] @@ -337,14 +383,14 @@ describe("should resolve all aliases", () => { }); it("reverse order", done => { - resolver = createResolver(["/a/foo", "/c/foo"]); + resolver = createResolver([`${obps}a${obps}foo`, `${obps}c${obps}foo`]); run( done, - ["/a/foo/a", false], + [`${posixSep}a${posixSep}foo${posixSep}a`, false], [ - "resolve 'index/a' in 'fixtures'", + `resolve 'index${posixSep}a' in 'fixtures'`, " Parsed request is a module", - " using description file (relative path: ./test/fixtures/yield)", + ` using description file (relative path: .${posixSep}test${posixSep}fixtures${posixSep}yield)`, ...aLog, ...cLog ] @@ -368,33 +414,39 @@ describe("should resolve all aliases", () => { log: l => logs.push(l) }; - resolver.resolve({}, fixtures, "index/a", context, (err, result) => { - calls++; - expect(calls).toEqual(1); - expect(err).toEqual(null); - expect(result).toBeUndefined(); - expect(paths).toEqual(makeFixturePaths(expectedResult)); - expect(contextifyDependencies(fileDependencies)).toEqual([ - "", - "/a", - "/a/foo", - "/a/foo/a", - "/c/foo/package.json" - ]); - expect(contextifyDependencies(missingDependencies)).toEqual([ - "/a/foo/a", - "/a/foo/a.js", - "/a/foo/package.json", - "/a/package.json", - "/c/foo/a", - "/c/foo/a.js", - "/package.json" - ]); - expect(Array.from(contextDependencies).sort()).toEqual([]); - expect(beatifyLogs(logs)).toEqual(expectedLogs); - - done(); - }); + resolver.resolve( + {}, + fixtures, + `index${obps}a`, + context, + (err, result) => { + calls++; + expect(calls).toEqual(1); + expect(err).toEqual(null); + expect(result).toBeUndefined(); + expect(paths).toEqual(makeFixturePaths(expectedResult)); + expect(contextifyDependencies(fileDependencies)).toEqual([ + "", + `${posixSep}a`, + `${posixSep}a${posixSep}foo`, + `${posixSep}a${posixSep}foo${posixSep}a`, + `${posixSep}c${posixSep}foo${posixSep}package.json` + ]); + expect(contextifyDependencies(missingDependencies)).toEqual([ + `${posixSep}a${posixSep}foo${posixSep}a`, + `${posixSep}a${posixSep}foo${posixSep}a.js`, + `${posixSep}a${posixSep}foo${posixSep}package.json`, + `${posixSep}a${posixSep}package.json`, + `${posixSep}c${posixSep}foo${posixSep}a`, + `${posixSep}c${posixSep}foo${posixSep}a.js`, + `${posixSep}package.json` + ]); + expect(Array.from(contextDependencies).sort()).toEqual([]); + expect(beatifyLogs(logs)).toEqual(expectedLogs); + + done(); + } + ); } }); @@ -407,7 +459,7 @@ describe("should resolve all aliases", () => { }); it("should correctly handle resolve in callback", done => { - const getResult = request => ({ ...request, path: "/a" }); + const getResult = request => ({ ...request, path: `${posixSep}a` }); const resolver = createResolver({ apply(resolver) { resolver @@ -428,7 +480,7 @@ describe("should resolve all aliases", () => { if (err) done(err); expect(err).toBeNull(); expect(result).toBeUndefined(); - expect(paths).toEqual(["/a"]); + expect(paths).toEqual([`${posixSep}a`]); done(); }); }); @@ -465,42 +517,57 @@ describe("should resolve all aliases", () => { const resolver = ResolverFactory.createResolver({ extensions: [".js"], alias: { - index: makeFixturePaths(["/a/foo", "/a/foo-2"]) + index: makeFixturePathsForLibrary([ + `${obps}a${obps}foo`, + `${obps}a${obps}foo-2` + ]) }, unsafeCache: cache, fileSystem: nodeFileSystem }); - resolver.resolve({}, fixtures, "index/b", { yield: () => {} }, err => { - if (err) done(err); - const paths = []; - - resolver.resolve( - {}, - fixtures, - "index/b", - { yield: obj => paths.push(obj.path) }, - (err, result) => { - expect(err).toBe(null); - expect(result).toBeUndefined(); - expect(paths).toEqual( - makeFixturePaths(["/a/foo/b", "/a/foo-2/b"]) - ); - // original + 2 aliases - expect(Object.keys(cache)).toHaveLength(3); - - const cacheId = Object.keys(cache).find(id => { - const { request } = JSON.parse(id); - return request === "index/b"; - }); - expect(cacheId).not.toBeUndefined(); - expect(Array.isArray(cache[cacheId])).toBe(true); - expect(cache[cacheId].map(o => o.path)).toEqual( - makeFixturePaths(["/a/foo/b", "/a/foo-2/b"]) - ); - done(); - } - ); - }); + resolver.resolve( + {}, + fixtures, + `index${obps}b`, + { yield: () => {} }, + err => { + if (err) done(err); + const paths = []; + + resolver.resolve( + {}, + fixtures, + `index${obps}b`, + { yield: obj => paths.push(obj.path) }, + (err, result) => { + expect(err).toBe(null); + expect(result).toBeUndefined(); + expect(paths).toEqual( + makeFixturePaths([ + `${obps}a${obps}foo${obps}b`, + `${obps}a${obps}foo-2${obps}b` + ]) + ); + // original + 2 aliases + expect(Object.keys(cache)).toHaveLength(3); + + const cacheId = Object.keys(cache).find(id => { + const { request } = JSON.parse(id); + return request === `index${posixSep}b`; + }); + expect(cacheId).not.toBeUndefined(); + expect(Array.isArray(cache[cacheId])).toBe(true); + expect(cache[cacheId].map(o => o.path)).toEqual( + makeFixturePaths([ + `${posixSep}a${obps}foo${obps}b`, + `${posixSep}a${obps}foo-2${obps}b` + ]) + ); + done(); + } + ); + } + ); }); // same as "should handle false in alias field"