From 0ac8b8f221f451929c992d45f9016fc9b4e59b15 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Mon, 1 Jun 2020 01:20:19 +0300 Subject: [PATCH 1/3] add restrictions option support --- README.md | 1 + lib/ResolverFactory.js | 25 ++++++-- lib/RestrictionsPlugin.js | 59 +++++++++++++++++++ lib/ResultPlugin.js | 4 +- .../restrictions/node_modules/pck1/index.css | 0 .../restrictions/node_modules/pck1/index.js | 0 .../node_modules/pck1/package.json | 3 + .../node_modules/pck2/package.json | 3 + test/restrictions.js | 38 ++++++++++++ types.d.ts | 6 ++ 10 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 lib/RestrictionsPlugin.js create mode 100644 test/fixtures/restrictions/node_modules/pck1/index.css create mode 100644 test/fixtures/restrictions/node_modules/pck1/index.js create mode 100644 test/fixtures/restrictions/node_modules/pck1/package.json create mode 100644 test/fixtures/restrictions/node_modules/pck2/package.json create mode 100644 test/restrictions.js diff --git a/README.md b/README.md index dfe554ae..4fd1e1b6 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ myResolver.resolve({}, lookupStartPath, request, resolveContext, ( | symlinks | true | Whether to resolve symlinks to their symlinked location | | cachePredicate | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with `path` and `request` properties. | | resolveToContext | false | Resolve to a context instead of a file | +| restrictions | [] | A list of resolve restrictions | | fileSystem | | The file system which should be used | | resolver | undefined | A prepared Resolver to which the plugins are attached | diff --git a/lib/ResolverFactory.js b/lib/ResolverFactory.js index 66a4dfca..d3049723 100644 --- a/lib/ResolverFactory.js +++ b/lib/ResolverFactory.js @@ -27,6 +27,7 @@ const ModulesInRootPlugin = require("./ModulesInRootPlugin"); const NextPlugin = require("./NextPlugin"); const ParsePlugin = require("./ParsePlugin"); const PnpPlugin = require("./PnpPlugin"); +const RestrictionsPlugin = require("./RestrictionsPlugin"); const ResultPlugin = require("./ResultPlugin"); const SelfReferencePlugin = require("./SelfReferencePlugin"); const SymlinkPlugin = require("./SymlinkPlugin"); @@ -64,6 +65,7 @@ const UseFilePlugin = require("./UseFilePlugin"); * @property {Plugin[]=} plugins A list of additional resolve plugins which should be applied * @property {PnpApi | null=} pnpApi A PnP API that should be used - null is "never", undefined is "auto" * @property {boolean=} resolveToContext Resolve to a context instead of a file + * @property {(string|RegExp)[]=} restrictions A list of resolve restrictions * @property {boolean=} useSyncFileSystemCalls Use only the sync constiants of the file system calls */ @@ -88,6 +90,7 @@ const UseFilePlugin = require("./UseFilePlugin"); * @property {Plugin[]} plugins * @property {PnpApi | null} pnpApi * @property {boolean} resolveToContext + * @property {Set} restrictions */ /** @@ -181,7 +184,8 @@ function createOptions(options) { mainFiles: new Set(options.mainFiles || ["index"]), plugins: options.plugins || [], pnpApi: processPnpApiOption(options.pnpApi), - resolveToContext: options.resolveToContext || false + resolveToContext: options.resolveToContext || false, + restrictions: new Set(options.restrictions) }; } @@ -211,7 +215,8 @@ exports.createResolver = function(options) { resolveToContext, symlinks, unsafeCache, - resolver: customResolver + resolver: customResolver, + restrictions } = normalizedOptions; const plugins = userPlugins.slice(); @@ -241,6 +246,7 @@ exports.createResolver = function(options) { resolver.ensureHook("file"); resolver.ensureHook("finalFile"); resolver.ensureHook("existingFile"); + resolver.ensureHook("finalResolved"); resolver.ensureHook("resolved"); // resolve @@ -375,7 +381,9 @@ exports.createResolver = function(options) { if (resolveToContext) { // undescribed-existing-directory - plugins.push(new NextPlugin("undescribed-existing-directory", "resolved")); + plugins.push( + new NextPlugin("undescribed-existing-directory", "final-resolved") + ); } else { // undescribed-existing-directory plugins.push( @@ -445,7 +453,16 @@ exports.createResolver = function(options) { // existing-file if (symlinks) plugins.push(new SymlinkPlugin("existing-file", "existing-file")); - plugins.push(new NextPlugin("existing-file", "resolved")); + plugins.push(new NextPlugin("existing-file", "final-resolved")); + } + + // final-resolved + if (restrictions.size > 0) { + plugins.push( + new RestrictionsPlugin("final-resolved", restrictions, "resolved") + ); + } else { + plugins.push(new NextPlugin("final-resolved", "resolved")); } // resolved diff --git a/lib/RestrictionsPlugin.js b/lib/RestrictionsPlugin.js new file mode 100644 index 00000000..07a59649 --- /dev/null +++ b/lib/RestrictionsPlugin.js @@ -0,0 +1,59 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +/** @typedef {import("./Resolver")} Resolver */ +/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ + +module.exports = class RestrictionsPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Set} restrictions restrictions + * @param {string | ResolveStepHook} target target + */ + constructor(source, restrictions, target) { + this.source = source; + this.target = target; + this.restrictions = restrictions; + } + + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver) { + const target = resolver.ensureHook(this.target); + resolver + .getHook(this.source) + .tapAsync("RestrictionsPlugin", (request, resolveContext, callback) => { + if (typeof request.path === "string") { + const path = request.path; + for (const rule of this.restrictions) { + if (typeof rule === "string") { + if (!path.startsWith(rule)) + return callback( + new Error( + `Resolve restriction ${JSON.stringify(rule)} not passed` + ) + ); + } else if (!rule.test(path)) { + return callback( + new Error(`Resolve restriction ${rule.toString()} not passed`) + ); + } + } + } + + resolver.doResolve( + target, + request, + "restrictions passed", + resolveContext, + callback + ); + }); + } +}; diff --git a/lib/ResultPlugin.js b/lib/ResultPlugin.js index 28d1d4e9..b8496945 100644 --- a/lib/ResultPlugin.js +++ b/lib/ResultPlugin.js @@ -5,12 +5,12 @@ "use strict"; -/** @typedef {import("tapable").AsyncHook} AsyncHook */ /** @typedef {import("./Resolver")} Resolver */ +/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ module.exports = class ResultPlugin { /** - * @param {AsyncHook} source source + * @param {ResolveStepHook} source source */ constructor(source) { this.source = source; diff --git a/test/fixtures/restrictions/node_modules/pck1/index.css b/test/fixtures/restrictions/node_modules/pck1/index.css new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/restrictions/node_modules/pck1/index.js b/test/fixtures/restrictions/node_modules/pck1/index.js new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/restrictions/node_modules/pck1/package.json b/test/fixtures/restrictions/node_modules/pck1/package.json new file mode 100644 index 00000000..14ab704d --- /dev/null +++ b/test/fixtures/restrictions/node_modules/pck1/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/test/fixtures/restrictions/node_modules/pck2/package.json b/test/fixtures/restrictions/node_modules/pck2/package.json new file mode 100644 index 00000000..4a1fdf9e --- /dev/null +++ b/test/fixtures/restrictions/node_modules/pck2/package.json @@ -0,0 +1,3 @@ +{ + "main": "../../../c.js" +} diff --git a/test/restrictions.js b/test/restrictions.js new file mode 100644 index 00000000..bf5dac38 --- /dev/null +++ b/test/restrictions.js @@ -0,0 +1,38 @@ +require("should"); +const path = require("path"); +const fs = require("fs"); +const ResolverFactory = require("../lib/ResolverFactory"); +const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); + +const fixture = path.resolve(__dirname, "fixtures", "restrictions"); +const nodeFileSystem = new CachedInputFileSystem(fs, 4000); + +it("should respect RegExp restriction", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + restrictions: [/\.(sass|scss|css)$/] + }); + + resolver.resolve({}, fixture, "pck1", {}, (err, result) => { + if (!err) throw new Error(`expect error, got ${result}`); + err.should.be.instanceof(Error); + err.message.should.match(/Resolve restriction \/.*\/ not passed/); + done(); + }); +}); + +it("should respect string restriction", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + restrictions: [fixture] + }); + + resolver.resolve({}, fixture, "pck2", {}, (err, result) => { + if (!err) throw new Error(`expect error, got ${result}`); + err.should.be.instanceof(Error); + err.message.should.match(/Resolve restriction ".*" not passed/); + done(); + }); +}); diff --git a/types.d.ts b/types.d.ts index 5aae597b..2b4a814d 100644 --- a/types.d.ts +++ b/types.d.ts @@ -134,6 +134,7 @@ declare interface ResolveOptions { | ((this: Resolver, arg1: Resolver) => void))[]; pnpApi: null | PnpApiImpl; resolveToContext: boolean; + restrictions: Set; } declare interface ResolveRequest { path: string | false; @@ -335,6 +336,11 @@ declare interface UserResolveOptions { */ resolveToContext?: undefined | boolean; + /** + * A list of resolve restrictions + */ + restrictions?: undefined | (string | RegExp)[]; + /** * Use only the sync constiants of the file system calls */ From 2efcc6bf04e9a9bbf1e9a9376cb4f2a2572daa86 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Mon, 1 Jun 2020 21:18:34 +0300 Subject: [PATCH 2/3] fix discussions, add more tests --- lib/ResolverFactory.js | 17 +++------- lib/RestrictionsPlugin.js | 24 +++---------- .../restrictions/node_modules/pck2/index.css | 0 .../node_modules/pck2/package.json | 3 +- test/restrictions.js | 34 +++++++++++++++++-- 5 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 test/fixtures/restrictions/node_modules/pck2/index.css diff --git a/lib/ResolverFactory.js b/lib/ResolverFactory.js index d3049723..1ac476ff 100644 --- a/lib/ResolverFactory.js +++ b/lib/ResolverFactory.js @@ -246,7 +246,6 @@ exports.createResolver = function(options) { resolver.ensureHook("file"); resolver.ensureHook("finalFile"); resolver.ensureHook("existingFile"); - resolver.ensureHook("finalResolved"); resolver.ensureHook("resolved"); // resolve @@ -381,9 +380,7 @@ exports.createResolver = function(options) { if (resolveToContext) { // undescribed-existing-directory - plugins.push( - new NextPlugin("undescribed-existing-directory", "final-resolved") - ); + plugins.push(new NextPlugin("undescribed-existing-directory", "resolved")); } else { // undescribed-existing-directory plugins.push( @@ -453,19 +450,13 @@ exports.createResolver = function(options) { // existing-file if (symlinks) plugins.push(new SymlinkPlugin("existing-file", "existing-file")); - plugins.push(new NextPlugin("existing-file", "final-resolved")); + plugins.push(new NextPlugin("existing-file", "resolved")); } - // final-resolved + // resolved if (restrictions.size > 0) { - plugins.push( - new RestrictionsPlugin("final-resolved", restrictions, "resolved") - ); - } else { - plugins.push(new NextPlugin("final-resolved", "resolved")); + plugins.push(new RestrictionsPlugin(resolver.hooks.resolved, restrictions)); } - - // resolved plugins.push(new ResultPlugin(resolver.hooks.resolved)); //// RESOLVER //// diff --git a/lib/RestrictionsPlugin.js b/lib/RestrictionsPlugin.js index 07a59649..b677d03e 100644 --- a/lib/RestrictionsPlugin.js +++ b/lib/RestrictionsPlugin.js @@ -12,11 +12,9 @@ module.exports = class RestrictionsPlugin { /** * @param {string | ResolveStepHook} source source * @param {Set} restrictions restrictions - * @param {string | ResolveStepHook} target target */ - constructor(source, restrictions, target) { + constructor(source, restrictions) { this.source = source; - this.target = target; this.restrictions = restrictions; } @@ -25,7 +23,6 @@ module.exports = class RestrictionsPlugin { * @returns {void} */ apply(resolver) { - const target = resolver.ensureHook(this.target); resolver .getHook(this.source) .tapAsync("RestrictionsPlugin", (request, resolveContext, callback) => { @@ -33,27 +30,14 @@ module.exports = class RestrictionsPlugin { const path = request.path; for (const rule of this.restrictions) { if (typeof rule === "string") { - if (!path.startsWith(rule)) - return callback( - new Error( - `Resolve restriction ${JSON.stringify(rule)} not passed` - ) - ); + if (!path.startsWith(rule)) return callback(null, null); } else if (!rule.test(path)) { - return callback( - new Error(`Resolve restriction ${rule.toString()} not passed`) - ); + return callback(null, null); } } } - resolver.doResolve( - target, - request, - "restrictions passed", - resolveContext, - callback - ); + callback(); }); } }; diff --git a/test/fixtures/restrictions/node_modules/pck2/index.css b/test/fixtures/restrictions/node_modules/pck2/index.css new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/restrictions/node_modules/pck2/package.json b/test/fixtures/restrictions/node_modules/pck2/package.json index 4a1fdf9e..f35bf123 100644 --- a/test/fixtures/restrictions/node_modules/pck2/package.json +++ b/test/fixtures/restrictions/node_modules/pck2/package.json @@ -1,3 +1,4 @@ { - "main": "../../../c.js" + "main": "../../../c.js", + "style": "index.css" } diff --git a/test/restrictions.js b/test/restrictions.js index bf5dac38..c8c40f34 100644 --- a/test/restrictions.js +++ b/test/restrictions.js @@ -17,7 +17,22 @@ it("should respect RegExp restriction", done => { resolver.resolve({}, fixture, "pck1", {}, (err, result) => { if (!err) throw new Error(`expect error, got ${result}`); err.should.be.instanceof(Error); - err.message.should.match(/Resolve restriction \/.*\/ not passed/); + done(); + }); +}); + +it("should try to find alternative #1", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js", ".css"], + fileSystem: nodeFileSystem, + mainFiles: ["index"], + restrictions: [/\.(sass|scss|css)$/] + }); + + resolver.resolve({}, fixture, "pck1", {}, (err, result) => { + if (err) return done(err); + if (!result) throw new Error("No result"); + result.should.equal(path.resolve(fixture, "node_modules/pck1/index.css")); done(); }); }); @@ -32,7 +47,22 @@ it("should respect string restriction", done => { resolver.resolve({}, fixture, "pck2", {}, (err, result) => { if (!err) throw new Error(`expect error, got ${result}`); err.should.be.instanceof(Error); - err.message.should.match(/Resolve restriction ".*" not passed/); + done(); + }); +}); + +it("should try to find alternative #2", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + mainFields: ["style"], + restrictions: [fixture, /\.(sass|scss|css)$/] + }); + + resolver.resolve({}, fixture, "pck2", {}, (err, result) => { + if (err) return done(err); + if (!result) throw new Error("No result"); + result.should.equal(path.resolve(fixture, "node_modules/pck2/index.css")); done(); }); }); From 4bce6942f122c9242fb2defd2da7a8ed2fd30fda Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 3 Jun 2020 10:17:24 +0200 Subject: [PATCH 3/3] add info log when restriction was matched strings in restrictions are treated as directory --- lib/RestrictionsPlugin.js | 24 ++- .../restrictions/node_modules/pck2/module.js | 0 .../node_modules/pck2/package.json | 1 + test/restrictions.js | 173 +++++++++++++----- 4 files changed, 151 insertions(+), 47 deletions(-) create mode 100644 test/fixtures/restrictions/node_modules/pck2/module.js diff --git a/lib/RestrictionsPlugin.js b/lib/RestrictionsPlugin.js index b677d03e..1d87a5f4 100644 --- a/lib/RestrictionsPlugin.js +++ b/lib/RestrictionsPlugin.js @@ -8,6 +8,16 @@ /** @typedef {import("./Resolver")} Resolver */ /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ +const slashCode = "/".charCodeAt(0); +const backslashCode = "\\".charCodeAt(0); + +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; +}; + module.exports = class RestrictionsPlugin { /** * @param {string | ResolveStepHook} source source @@ -30,8 +40,20 @@ module.exports = class RestrictionsPlugin { const path = request.path; for (const rule of this.restrictions) { if (typeof rule === "string") { - if (!path.startsWith(rule)) return callback(null, null); + if (!isInside(path, rule)) { + if (resolveContext.log) { + resolveContext.log( + `${path} is not inside of the restriction ${rule}` + ); + } + return callback(null, null); + } } else if (!rule.test(path)) { + if (resolveContext.log) { + resolveContext.log( + `${path} doesn't match the restriction ${rule}` + ); + } return callback(null, null); } } diff --git a/test/fixtures/restrictions/node_modules/pck2/module.js b/test/fixtures/restrictions/node_modules/pck2/module.js new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/restrictions/node_modules/pck2/package.json b/test/fixtures/restrictions/node_modules/pck2/package.json index f35bf123..ee0eb71b 100644 --- a/test/fixtures/restrictions/node_modules/pck2/package.json +++ b/test/fixtures/restrictions/node_modules/pck2/package.json @@ -1,4 +1,5 @@ { "main": "../../../c.js", + "module": "module.js", "style": "index.css" } diff --git a/test/restrictions.js b/test/restrictions.js index c8c40f34..da23fda1 100644 --- a/test/restrictions.js +++ b/test/restrictions.js @@ -7,62 +7,143 @@ const CachedInputFileSystem = require("../lib/CachedInputFileSystem"); const fixture = path.resolve(__dirname, "fixtures", "restrictions"); const nodeFileSystem = new CachedInputFileSystem(fs, 4000); -it("should respect RegExp restriction", done => { - const resolver = ResolverFactory.createResolver({ - extensions: [".js"], - fileSystem: nodeFileSystem, - restrictions: [/\.(sass|scss|css)$/] - }); +describe("restrictions", () => { + it("should respect RegExp restriction", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + restrictions: [/\.(sass|scss|css)$/] + }); - resolver.resolve({}, fixture, "pck1", {}, (err, result) => { - if (!err) throw new Error(`expect error, got ${result}`); - err.should.be.instanceof(Error); - done(); + resolver.resolve({}, fixture, "pck1", {}, (err, result) => { + if (!err) throw new Error(`expect error, got ${result}`); + err.should.be.instanceof(Error); + done(); + }); }); -}); -it("should try to find alternative #1", done => { - const resolver = ResolverFactory.createResolver({ - extensions: [".js", ".css"], - fileSystem: nodeFileSystem, - mainFiles: ["index"], - restrictions: [/\.(sass|scss|css)$/] - }); + it("should try to find alternative #1", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js", ".css"], + fileSystem: nodeFileSystem, + mainFiles: ["index"], + restrictions: [/\.(sass|scss|css)$/] + }); - resolver.resolve({}, fixture, "pck1", {}, (err, result) => { - if (err) return done(err); - if (!result) throw new Error("No result"); - result.should.equal(path.resolve(fixture, "node_modules/pck1/index.css")); - done(); + resolver.resolve({}, fixture, "pck1", {}, (err, result) => { + if (err) return done(err); + if (!result) throw new Error("No result"); + result.should.equal(path.resolve(fixture, "node_modules/pck1/index.css")); + done(); + }); }); -}); -it("should respect string restriction", done => { - const resolver = ResolverFactory.createResolver({ - extensions: [".js"], - fileSystem: nodeFileSystem, - restrictions: [fixture] - }); + it("should respect string restriction", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + restrictions: [fixture] + }); - resolver.resolve({}, fixture, "pck2", {}, (err, result) => { - if (!err) throw new Error(`expect error, got ${result}`); - err.should.be.instanceof(Error); - done(); + resolver.resolve({}, fixture, "pck2", {}, (err, result) => { + if (!err) throw new Error(`expect error, got ${result}`); + err.should.be.instanceof(Error); + done(); + }); }); -}); -it("should try to find alternative #2", done => { - const resolver = ResolverFactory.createResolver({ - extensions: [".js"], - fileSystem: nodeFileSystem, - mainFields: ["style"], - restrictions: [fixture, /\.(sass|scss|css)$/] + it("should try to find alternative #2", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + mainFields: ["main", "style"], + restrictions: [fixture, /\.(sass|scss|css)$/] + }); + + resolver.resolve({}, fixture, "pck2", {}, (err, result) => { + if (err) return done(err); + if (!result) throw new Error("No result"); + result.should.equal(path.resolve(fixture, "node_modules/pck2/index.css")); + done(); + }); }); - resolver.resolve({}, fixture, "pck2", {}, (err, result) => { - if (err) return done(err); - if (!result) throw new Error("No result"); - result.should.equal(path.resolve(fixture, "node_modules/pck2/index.css")); - done(); + it("should try to find alternative #3", done => { + const resolver = ResolverFactory.createResolver({ + extensions: [".js"], + fileSystem: nodeFileSystem, + mainFields: ["main", "module", "style"], + restrictions: [fixture, /\.(sass|scss|css)$/] + }); + + const log = []; + + resolver.resolve( + {}, + fixture, + "pck2", + { log: log.push.bind(log) }, + (err, result) => { + if (err) return done(err); + if (!result) throw new Error("No result"); + result.should.equal( + path.resolve(fixture, "node_modules/pck2/index.css") + ); + log + .map(line => + line + .replace(path.resolve(__dirname, ".."), "...") + .replace(path.resolve(__dirname, ".."), "...") + .replace(/\\/g, "/") + ) + .should.be.eql([ + "resolve 'pck2' in '.../test/fixtures/restrictions'", + " Parsed request is a module", + " using description file: .../package.json (relative path: ./test/fixtures/restrictions)", + " resolve as module", + " looking for modules in .../test/fixtures/restrictions/node_modules", + " single file module", + " using description file: .../package.json (relative path: ./test/fixtures/restrictions/node_modules/pck2)", + " no extension", + " .../test/fixtures/restrictions/node_modules/pck2 is not a file", + " .js", + " .../test/fixtures/restrictions/node_modules/pck2.js doesn't exist", + " existing directory .../test/fixtures/restrictions/node_modules/pck2", + " using description file: .../test/fixtures/restrictions/node_modules/pck2/package.json (relative path: .)", + " using description file: .../package.json (relative path: ./test/fixtures/restrictions/node_modules/pck2)", + " no extension", + " .../test/fixtures/restrictions/node_modules/pck2 is not a file", + " .js", + " .../test/fixtures/restrictions/node_modules/pck2.js doesn't exist", + " as directory", + " existing directory .../test/fixtures/restrictions/node_modules/pck2", + " using description file: .../test/fixtures/restrictions/node_modules/pck2/package.json (relative path: .)", + " use ../../../c.js from main in package.json", + " using description file: .../package.json (relative path: ./test/fixtures/c.js)", + " no extension", + " existing file: .../test/fixtures/c.js", + " .../test/fixtures/c.js is not inside of the restriction .../test/fixtures/restrictions", + " .js", + " .../test/fixtures/c.js.js doesn't exist", + " as directory", + " .../test/fixtures/c.js is not a directory", + " use ./module.js from module in package.json", + " using description file: .../test/fixtures/restrictions/node_modules/pck2/package.json (relative path: ./module.js)", + " no extension", + " existing file: .../test/fixtures/restrictions/node_modules/pck2/module.js", + " .../test/fixtures/restrictions/node_modules/pck2/module.js doesn't match the restriction //.(sass|scss|css)$/", + " .js", + " .../test/fixtures/restrictions/node_modules/pck2/module.js.js doesn't exist", + " as directory", + " .../test/fixtures/restrictions/node_modules/pck2/module.js is not a directory", + " use ./index.css from style in package.json", + " using description file: .../test/fixtures/restrictions/node_modules/pck2/package.json (relative path: ./index.css)", + " no extension", + " existing file: .../test/fixtures/restrictions/node_modules/pck2/index.css", + " reporting result .../test/fixtures/restrictions/node_modules/pck2/index.css" + ]); + done(); + } + ); }); });