pax_global_header00006660000000000000000000000064130422403420014504gustar00rootroot0000000000000052 comment=c875814f169348ef712b78e22c6404a7f585df3f loader-runner-2.3.0/000077500000000000000000000000001304224034200142635ustar00rootroot00000000000000loader-runner-2.3.0/.eslintrc000066400000000000000000000025401304224034200161100ustar00rootroot00000000000000{ "root": true, "plugins": ["node"], "extends": ["eslint:recommended", "plugin:node/recommended"], "env": { "node": true, "mocha": true }, "rules": { "quotes": ["error", "double"], "no-undef": "error", "no-extra-semi": "error", "semi": "error", "no-template-curly-in-string": "error", "no-caller": "error", "yoda": "error", "eqeqeq": "error", "global-require": "off", "brace-style": "error", "eol-last": "error", "indent": ["error", "tab", { "SwitchCase": 1 }], "no-extra-bind": "warn", "no-empty": "off", "no-multiple-empty-lines": "error", "no-multi-spaces": "error", "no-process-exit": "warn", "space-in-parens": "error", "no-trailing-spaces": "error", "no-use-before-define": "off", "no-unused-vars": ["error", {"args": "none"}], "key-spacing": "error", "space-infix-ops": "error", "no-unsafe-negation": "error", "no-loop-func": "warn", "space-before-function-paren": ["error", "never"], "space-before-blocks": "error", "object-curly-spacing": ["error", "always"], "keyword-spacing": ["error", { "after": false, "overrides": { "try": {"after": true}, "else": {"after": true}, "throw": {"after": true}, "case": {"after": true}, "return": {"after": true}, "finally": {"after": true}, "do": {"after": true} } }], "no-console": "off", "valid-jsdoc": "error" } } loader-runner-2.3.0/.gitattributes000066400000000000000000000000131304224034200171500ustar00rootroot00000000000000* text=autoloader-runner-2.3.0/.gitignore000066400000000000000000000000271304224034200162520ustar00rootroot00000000000000/node_modules /coverageloader-runner-2.3.0/.jsbeautifyrc000066400000000000000000000013021304224034200167520ustar00rootroot00000000000000{ "js": { "allowed_file_extensions": ["js", "json", "jshintrc", "jsbeautifyrc"], "brace_style": "collapse", "break_chained_methods": false, "e4x": true, "eval_code": false, "end_with_newline": true, "indent_char": "\t", "indent_level": 0, "indent_size": 1, "indent_with_tabs": true, "jslint_happy": false, "jslint_happy_align_switch_case": true, "space_after_anon_function": false, "keep_array_indentation": false, "keep_function_indentation": false, "max_preserve_newlines": 2, "preserve_newlines": true, "space_before_conditional": false, "space_in_paren": false, "unescape_strings": false, "wrap_line_length": 0 } }loader-runner-2.3.0/.travis.yml000066400000000000000000000004231304224034200163730ustar00rootroot00000000000000sudo: false language: node_js node_js: - "4.0" - "5.0" - node script: npm run travis after_success: - cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose - cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js - rm -rf ./coverage loader-runner-2.3.0/README.md000066400000000000000000000021751304224034200155470ustar00rootroot00000000000000# loader-runner ``` js import { runLoaders } from "loader-runner"; runLoaders({ resource: "/abs/path/to/file.txt?query", // String: Absolute path to the resource (optionally including query string) loaders: ["/abs/path/to/loader.js?query"], // String[]: Absolute paths to the loaders (optionally including query string) // {loader, options}[]: Absolute paths to the loaders with options object context: { minimize: true }, // Additional loader context which is used as base context readResource: fs.readFile.bind(fs) // A function to read the resource // Must have signature function(path, function(err, buffer)) }, function(err, result) { // err: Error? // result.result: Buffer | String // The result // result.resourceBuffer: Buffer // The raw resource as Buffer (useful for SourceMaps) // result.cacheable: Bool // Is the result cacheable or do it require reexecution? // result.fileDependencies: String[] // An array of paths (files) on which the result depends on // result.contextDependencies: String[] // An array of paths (directories) on which the result depends on }) ``` More documentation following... loader-runner-2.3.0/lib/000077500000000000000000000000001304224034200150315ustar00rootroot00000000000000loader-runner-2.3.0/lib/LoaderRunner.js000066400000000000000000000252301304224034200177710ustar00rootroot00000000000000/* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ var fs = require("fs"); var readFile = fs.readFile.bind(fs); var loadLoader = require("./loadLoader"); function utf8BufferToString(buf) { var str = buf.toString("utf-8"); if(str.charCodeAt(0) === 0xFEFF) { return str.substr(1); } else { return str; } } function splitQuery(req) { var i = req.indexOf("?"); if(i < 0) return [req, ""]; return [req.substr(0, i), req.substr(i)]; } function dirname(path) { if(path === "/") return "/"; var i = path.lastIndexOf("/"); var j = path.lastIndexOf("\\"); var i2 = path.indexOf("/"); var j2 = path.indexOf("\\"); var idx = i > j ? i : j; var idx2 = i > j ? i2 : j2; if(idx < 0) return path; if(idx === idx2) return path.substr(0, idx + 1); return path.substr(0, idx); } function createLoaderObject(loader) { var obj = { path: null, query: null, options: null, ident: null, normal: null, pitch: null, raw: null, data: null, pitchExecuted: false, normalExecuted: false }; Object.defineProperty(obj, "request", { enumerable: true, get: function() { return obj.path + obj.query; }, set: function(value) { if(typeof value === "string") { var splittedRequest = splitQuery(value); obj.path = splittedRequest[0]; obj.query = splittedRequest[1]; obj.options = undefined; obj.ident = undefined; } else { if(!value.loader) throw new Error("request should be a string or object with loader and object (" + JSON.stringify(value) + ")"); obj.path = value.loader; obj.options = value.options; obj.ident = value.ident; if(obj.options === null) obj.query = ""; else if(obj.options === undefined) obj.query = ""; else if(typeof obj.options === "string") obj.query = "?" + obj.options; else if(obj.ident) obj.query = "??" + obj.ident; else if(typeof obj.options === "object" && obj.options.ident) obj.query = "??" + obj.options.ident; else obj.query = "?" + JSON.stringify(obj.options); } } }); obj.request = loader; if(Object.preventExtensions) { Object.preventExtensions(obj); } return obj; } function runSyncOrAsync(fn, context, args, callback) { var isSync = true; var isDone = false; var isError = false; // internal error var reportedError = false; context.async = function async() { if(isDone) { if(reportedError) return; // ignore throw new Error("async(): The callback was already called."); } isSync = false; return innerCallback; }; var innerCallback = context.callback = function() { if(isDone) { if(reportedError) return; // ignore throw new Error("callback(): The callback was already called."); } isDone = true; isSync = false; try { callback.apply(null, arguments); } catch(e) { isError = true; throw e; } }; try { var result = (function LOADER_EXECUTION() { return fn.apply(context, args); }()); if(isSync) { isDone = true; if(result === undefined) return callback(); if(result && typeof result === "object" && typeof result.then === "function") { return result.catch(callback).then(function(r) { callback(null, r); }); } return callback(null, result); } } catch(e) { if(isError) throw e; if(isDone) { // loader is already "done", so we cannot use the callback function // for better debugging we print the error on the console if(typeof e === "object" && e.stack) console.error(e.stack); else console.error(e); return; } isDone = true; reportedError = true; callback(e); } } function convertArgs(args, raw) { if(!raw && Buffer.isBuffer(args[0])) args[0] = utf8BufferToString(args[0]); else if(raw && typeof args[0] === "string") args[0] = new Buffer(args[0], "utf-8"); // eslint-disable-line } function iteratePitchingLoaders(options, loaderContext, callback) { // abort after last loader if(loaderContext.loaderIndex >= loaderContext.loaders.length) return processResource(options, loaderContext, callback); var currentLoaderObject = loaderContext.loaders[loaderContext.loaderIndex]; // iterate if(currentLoaderObject.pitchExecuted) { loaderContext.loaderIndex++; return iteratePitchingLoaders(options, loaderContext, callback); } // load loader module loadLoader(currentLoaderObject, function(err) { if(err) return callback(err); var fn = currentLoaderObject.pitch; currentLoaderObject.pitchExecuted = true; if(!fn) return iteratePitchingLoaders(options, loaderContext, callback); runSyncOrAsync( fn, loaderContext, [loaderContext.remainingRequest, loaderContext.previousRequest, currentLoaderObject.data = {}], function(err) { if(err) return callback(err); var args = Array.prototype.slice.call(arguments, 1); if(args.length > 0) { loaderContext.loaderIndex--; iterateNormalLoaders(options, loaderContext, args, callback); } else { iteratePitchingLoaders(options, loaderContext, callback); } } ); }); } function processResource(options, loaderContext, callback) { // set loader index to last loader loaderContext.loaderIndex = loaderContext.loaders.length - 1; var resourcePath = loaderContext.resourcePath; if(resourcePath) { loaderContext.addDependency(resourcePath); options.readResource(resourcePath, function(err, buffer) { if(err) return callback(err); options.resourceBuffer = buffer; iterateNormalLoaders(options, loaderContext, [buffer], callback); }); } else { iterateNormalLoaders(options, loaderContext, [null], callback); } } function iterateNormalLoaders(options, loaderContext, args, callback) { if(loaderContext.loaderIndex < 0) return callback(null, args); var currentLoaderObject = loaderContext.loaders[loaderContext.loaderIndex]; // iterate if(currentLoaderObject.normalExecuted) { loaderContext.loaderIndex--; return iterateNormalLoaders(options, loaderContext, args, callback); } var fn = currentLoaderObject.normal; currentLoaderObject.normalExecuted = true; if(!fn) { return iterateNormalLoaders(options, loaderContext, args, callback); } convertArgs(args, currentLoaderObject.raw); runSyncOrAsync(fn, loaderContext, args, function(err) { if(err) return callback(err); var args = Array.prototype.slice.call(arguments, 1); iterateNormalLoaders(options, loaderContext, args, callback); }); } exports.getContext = function getContext(resource) { var splitted = splitQuery(resource); return dirname(splitted[0]); }; exports.runLoaders = function runLoaders(options, callback) { // read options var resource = options.resource || ""; var loaders = options.loaders || []; var loaderContext = options.context || {}; var readResource = options.readResource || readFile; // var splittedResource = resource && splitQuery(resource); var resourcePath = splittedResource ? splittedResource[0] : undefined; var resourceQuery = splittedResource ? splittedResource[1] : undefined; var contextDirectory = resourcePath ? dirname(resourcePath) : null; // execution state var requestCacheable = true; var fileDependencies = []; var contextDependencies = []; // prepare loader objects loaders = loaders.map(createLoaderObject); loaderContext.context = contextDirectory; loaderContext.loaderIndex = 0; loaderContext.loaders = loaders; loaderContext.resourcePath = resourcePath; loaderContext.resourceQuery = resourceQuery; loaderContext.async = null; loaderContext.callback = null; loaderContext.cacheable = function cacheable(flag) { if(flag === false) { requestCacheable = false; } }; loaderContext.dependency = loaderContext.addDependency = function addDependency(file) { fileDependencies.push(file); }; loaderContext.addContextDependency = function addContextDependency(context) { contextDependencies.push(context); }; loaderContext.getDependencies = function getDependencies() { return fileDependencies.slice(); }; loaderContext.getContextDependencies = function getContextDependencies() { return contextDependencies.slice(); }; loaderContext.clearDependencies = function clearDependencies() { fileDependencies.length = 0; contextDependencies.length = 0; requestCacheable = true; }; Object.defineProperty(loaderContext, "resource", { enumerable: true, get: function() { if(loaderContext.resourcePath === undefined) return undefined; return loaderContext.resourcePath + loaderContext.resourceQuery; }, set: function(value) { var splittedResource = value && splitQuery(value); loaderContext.resourcePath = splittedResource ? splittedResource[0] : undefined; loaderContext.resourceQuery = splittedResource ? splittedResource[1] : undefined; } }); Object.defineProperty(loaderContext, "request", { enumerable: true, get: function() { return loaderContext.loaders.map(function(o) { return o.request; }).concat(loaderContext.resource || "").join("!"); } }); Object.defineProperty(loaderContext, "remainingRequest", { enumerable: true, get: function() { if(loaderContext.loaderIndex >= loaderContext.loaders.length - 1 && !loaderContext.resource) return ""; return loaderContext.loaders.slice(loaderContext.loaderIndex + 1).map(function(o) { return o.request; }).concat(loaderContext.resource || "").join("!"); } }); Object.defineProperty(loaderContext, "currentRequest", { enumerable: true, get: function() { return loaderContext.loaders.slice(loaderContext.loaderIndex).map(function(o) { return o.request; }).concat(loaderContext.resource || "").join("!"); } }); Object.defineProperty(loaderContext, "previousRequest", { enumerable: true, get: function() { return loaderContext.loaders.slice(0, loaderContext.loaderIndex).map(function(o) { return o.request; }).join("!"); } }); Object.defineProperty(loaderContext, "query", { enumerable: true, get: function() { var entry = loaderContext.loaders[loaderContext.loaderIndex]; return entry.options && typeof entry.options === "object" ? entry.options : entry.query; } }); Object.defineProperty(loaderContext, "data", { enumerable: true, get: function() { return loaderContext.loaders[loaderContext.loaderIndex].data; } }); // finish loader context if(Object.preventExtensions) { Object.preventExtensions(loaderContext); } var processOptions = { resourceBuffer: null, readResource: readResource }; iteratePitchingLoaders(processOptions, loaderContext, function(err, result) { if(err) { return callback(err, { cacheable: requestCacheable, fileDependencies: fileDependencies, contextDependencies: contextDependencies }); } callback(null, { result: result, resourceBuffer: processOptions.resourceBuffer, cacheable: requestCacheable, fileDependencies: fileDependencies, contextDependencies: contextDependencies }); }); }; loader-runner-2.3.0/lib/loadLoader.js000066400000000000000000000030351304224034200174360ustar00rootroot00000000000000module.exports = function loadLoader(loader, callback) { if(typeof System === "object" && typeof System.import === "function") { System.import(loader.path).catch(callback).then(function(module) { loader.normal = typeof module === "function" ? module : module.default; loader.pitch = module.pitch; loader.raw = module.raw; if(typeof loader.normal !== "function" && typeof loader.pitch !== "function") throw new Error("Module '" + loader.path + "' is not a loader (must have normal or pitch function)"); callback(); }); } else { try { var module = require(loader.path); } catch(e) { // it is possible for node to choke on a require if the FD descriptor // limit has been reached. give it a chance to recover. if(e instanceof Error && e.code === "EMFILE") { var retry = loadLoader.bind(null, loader, callback); if(typeof setImmediate === "function") { // node >= 0.9.0 return setImmediate(retry); } else { // node < 0.9.0 return process.nextTick(retry); } } return callback(e); } if(typeof loader !== "function" && typeof loader !== "object") throw new Error("Module '" + loader.path + "' is not a loader (export function or es6 module))"); loader.normal = typeof module === "function" ? module : module.default; loader.pitch = module.pitch; loader.raw = module.raw; if(typeof loader.normal !== "function" && typeof loader.pitch !== "function") throw new Error("Module '" + loader.path + "' is not a loader (must have normal or pitch function)"); callback(); } }; loader-runner-2.3.0/package.json000066400000000000000000000024761304224034200165620ustar00rootroot00000000000000{ "name": "loader-runner", "version": "2.3.0", "description": "Runs (webpack) loaders", "main": "lib/LoaderRunner.js", "scripts": { "beautify-lint": "beautify-lint lib/**.js test/*.js", "beautify": "beautify-rewrite lib/**.js test/*.js", "lint": "eslint lib test", "pretest": "npm run lint && npm run beautify-lint", "test": "mocha --reporter spec", "precover": "npm run lint && npm run beautify-lint", "cover": "istanbul cover node_modules/mocha/bin/_mocha", "travis": "npm run cover -- --report lcovonly" }, "repository": { "type": "git", "url": "git+https://github.com/webpack/loader-runner.git" }, "keywords": [ "webpack", "loader" ], "author": "Tobias Koppers @sokra", "license": "MIT", "bugs": { "url": "https://github.com/webpack/loader-runner/issues" }, "homepage": "https://github.com/webpack/loader-runner#readme", "engines": { "node": ">=4.3.0 <5.0.0 || >=5.10" }, "files": [ "lib/", "bin/", "hot/", "web_modules/", "schemas/" ], "devDependencies": { "beautify-lint": "^1.0.4", "codecov.io": "^0.1.6", "coveralls": "^2.11.6", "eslint": "^3.12.2", "eslint-plugin-node": "^3.0.5", "eslint-plugin-nodeca": "^1.0.3", "istanbul": "^0.4.1", "mocha": "^3.2.0", "should": "^8.0.2" } } loader-runner-2.3.0/test/000077500000000000000000000000001304224034200152425ustar00rootroot00000000000000loader-runner-2.3.0/test/fixtures/000077500000000000000000000000001304224034200171135ustar00rootroot00000000000000loader-runner-2.3.0/test/fixtures/bom.bin000066400000000000000000000000071304224034200203570ustar00rootroot00000000000000bömloader-runner-2.3.0/test/fixtures/change-stuff-loader.js000066400000000000000000000004311304224034200232650ustar00rootroot00000000000000var path = require("path"); exports.pitch = function pitch(rem, prev, data) { this.loaders[this.loaderIndex + 2].request = path.resolve(__dirname, "identity-loader.js"); this.resource = path.resolve(__dirname, "resource.bin"); this.loaderIndex += 2; this.cacheable(false); }; loader-runner-2.3.0/test/fixtures/dependencies-loader.js000066400000000000000000000004071304224034200233440ustar00rootroot00000000000000module.exports = function(source) { this.clearDependencies(); this.addDependency("a"); this.addDependency("b"); this.addContextDependency("c"); return source + "\n" + JSON.stringify(this.getDependencies()) + JSON.stringify(this.getContextDependencies()); }; loader-runner-2.3.0/test/fixtures/failing-loader.js000066400000000000000000000001011304224034200223160ustar00rootroot00000000000000module.exports = function(source) { throw new Error(source); }; loader-runner-2.3.0/test/fixtures/identity-loader.js000066400000000000000000000002041304224034200225420ustar00rootroot00000000000000module.exports = function(source) { return source; }; module.exports.pitch = function(rem, prev, data) { data.identity = true; }; loader-runner-2.3.0/test/fixtures/keys-loader.js000066400000000000000000000001051304224034200216640ustar00rootroot00000000000000module.exports = function(source) { return JSON.stringify(this); }; loader-runner-2.3.0/test/fixtures/pitch-dependencies-loader.js000066400000000000000000000001551304224034200244510ustar00rootroot00000000000000exports.pitch = function(remainingRequest) { this.addDependency("remainingRequest:" + remainingRequest); }; loader-runner-2.3.0/test/fixtures/pitching-loader.js000066400000000000000000000002011304224034200225130ustar00rootroot00000000000000exports.pitch = function(remaingRequest, previousRequest, data) { return [ remaingRequest, previousRequest ].join(":"); }; loader-runner-2.3.0/test/fixtures/raw-loader.js000066400000000000000000000002771304224034200215140ustar00rootroot00000000000000exports.__es6Module = true; exports.default = function(source) { return new Buffer(source.toString("hex") + source.toString("utf-8"), "utf-8"); // eslint-disable-line }; exports.raw = true; loader-runner-2.3.0/test/fixtures/resource.bin000066400000000000000000000000101304224034200214230ustar00rootroot00000000000000resourceloader-runner-2.3.0/test/fixtures/simple-async-loader.js000066400000000000000000000002231304224034200233160ustar00rootroot00000000000000module.exports = function(source) { var callback = this.async(); setTimeout(function() { callback(null, source + "-async-simple"); }, 50); }; loader-runner-2.3.0/test/fixtures/simple-loader.js000066400000000000000000000001031304224034200222000ustar00rootroot00000000000000module.exports = function(source) { return source + "-simple"; }; loader-runner-2.3.0/test/fixtures/simple-promise-loader.js000066400000000000000000000001341304224034200236600ustar00rootroot00000000000000module.exports = function(source) { return Promise.resolve(source + "-promise-simple"); }; loader-runner-2.3.0/test/runLoaders.js000066400000000000000000000326721304224034200177300ustar00rootroot00000000000000var should = require("should"); // eslint-disable-line var path = require("path"); var runLoaders = require("../").runLoaders; var getContext = require("../").getContext; var fixtures = path.resolve(__dirname, "fixtures"); describe("runLoaders", function() { it("should process only a resource", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin") }, function(err, result) { if(err) return done(err); result.result.should.be.eql([new Buffer("resource", "utf-8")]); // eslint-disable-line result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should process a simple sync loader", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql(["resource-simple"]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should process a simple async loader", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-async-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql(["resource-async-simple"]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should process a simple promise loader", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-promise-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql(["resource-promise-simple"]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should process multiple simple loaders", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-async-loader.js"), path.resolve(fixtures, "simple-loader.js"), path.resolve(fixtures, "simple-async-loader.js"), path.resolve(fixtures, "simple-async-loader.js"), path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql(["resource-simple-async-simple-async-simple-simple-async-simple"]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should process pitching loaders", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-loader.js"), path.resolve(fixtures, "pitching-loader.js"), path.resolve(fixtures, "simple-async-loader.js"), ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql([ path.resolve(fixtures, "simple-async-loader.js") + "!" + path.resolve(fixtures, "resource.bin") + ":" + path.resolve(fixtures, "simple-loader.js") + "-simple" ]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([]); result.contextDependencies.should.be.eql([]); done(); }); }); it("should be possible to add dependencies", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "dependencies-loader.js") ] }, function(err, result) { if(err) return done(err); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql(["a", "b"]); result.contextDependencies.should.be.eql(["c"]); result.result.should.be.eql(["resource\n" + JSON.stringify(["a", "b"]) + JSON.stringify(["c"])]); done(); }); }); it("should have to correct keys in context", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin") + "?query", loaders: [ path.resolve(fixtures, "keys-loader.js") + "?loader-query", path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); try { JSON.parse(result.result[0]).should.be.eql({ context: fixtures, resource: path.resolve(fixtures, "resource.bin") + "?query", resourcePath: path.resolve(fixtures, "resource.bin"), resourceQuery: "?query", loaderIndex: 0, query: "?loader-query", currentRequest: path.resolve(fixtures, "keys-loader.js") + "?loader-query!" + path.resolve(fixtures, "simple-loader.js") + "!" + path.resolve(fixtures, "resource.bin") + "?query", remainingRequest: path.resolve(fixtures, "simple-loader.js") + "!" + path.resolve(fixtures, "resource.bin") + "?query", previousRequest: "", request: path.resolve(fixtures, "keys-loader.js") + "?loader-query!" + path.resolve(fixtures, "simple-loader.js") + "!" + path.resolve(fixtures, "resource.bin") + "?query", data: null, loaders: [{ request: path.resolve(fixtures, "keys-loader.js") + "?loader-query", path: path.resolve(fixtures, "keys-loader.js"), query: "?loader-query", data: null, pitchExecuted: true, normalExecuted: true }, { request: path.resolve(fixtures, "simple-loader.js"), path: path.resolve(fixtures, "simple-loader.js"), query: "", data: null, pitchExecuted: true, normalExecuted: true }] }); } catch(e) { return done(e); } done(); }); }); it("should have to correct keys in context (with options)", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin") + "?query", loaders: [{ loader: path.resolve(fixtures, "keys-loader.js"), options: { ident: "ident", loader: "query" } }] }, function(err, result) { if(err) return done(err); try { JSON.parse(result.result[0]).should.be.eql({ context: fixtures, resource: path.resolve(fixtures, "resource.bin") + "?query", resourcePath: path.resolve(fixtures, "resource.bin"), resourceQuery: "?query", loaderIndex: 0, query: { ident: "ident", loader: "query" }, currentRequest: path.resolve(fixtures, "keys-loader.js") + "??ident!" + path.resolve(fixtures, "resource.bin") + "?query", remainingRequest: path.resolve(fixtures, "resource.bin") + "?query", previousRequest: "", request: path.resolve(fixtures, "keys-loader.js") + "??ident!" + path.resolve(fixtures, "resource.bin") + "?query", data: null, loaders: [{ request: path.resolve(fixtures, "keys-loader.js") + "??ident", path: path.resolve(fixtures, "keys-loader.js"), query: "??ident", options: { ident: "ident", loader: "query" }, data: null, pitchExecuted: true, normalExecuted: true }] }); } catch(e) { return done(e); } done(); }); }); it("should process raw loaders", function(done) { runLoaders({ resource: path.resolve(fixtures, "bom.bin"), loaders: [ path.resolve(fixtures, "raw-loader.js") ] }, function(err, result) { if(err) return done(err); result.result[0].toString("utf-8").should.be.eql( "efbbbf62c3b66dböm" ); done(); }); }); it("should process omit BOM on string convertion", function(done) { runLoaders({ resource: path.resolve(fixtures, "bom.bin"), loaders: [ path.resolve(fixtures, "raw-loader.js"), path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); result.result[0].toString("utf-8").should.be.eql( "62c3b66d2d73696d706c65böm-simple" ); done(); }); }); it("should have to correct keys in context without resource", function(done) { runLoaders({ loaders: [ path.resolve(fixtures, "identity-loader.js"), path.resolve(fixtures, "keys-loader.js"), ] }, function(err, result) { if(err) return done(err); try { JSON.parse(result.result[0]).should.be.eql({ context: null, loaderIndex: 1, query: "", currentRequest: path.resolve(fixtures, "keys-loader.js") + "!", remainingRequest: "", previousRequest: path.resolve(fixtures, "identity-loader.js"), request: path.resolve(fixtures, "identity-loader.js") + "!" + path.resolve(fixtures, "keys-loader.js") + "!", data: null, loaders: [{ request: path.resolve(fixtures, "identity-loader.js"), path: path.resolve(fixtures, "identity-loader.js"), query: "", data: { identity: true }, pitchExecuted: true, normalExecuted: false }, { request: path.resolve(fixtures, "keys-loader.js"), path: path.resolve(fixtures, "keys-loader.js"), query: "", data: null, pitchExecuted: true, normalExecuted: true }] }); } catch(e) { return done(e); } done(); }); }); it("should have to correct keys in context with only resource query", function(done) { runLoaders({ resource: "?query", loaders: [{ loader: path.resolve(fixtures, "keys-loader.js"), options: { ok: true }, ident: "my-ident" }] }, function(err, result) { if(err) return done(err); try { JSON.parse(result.result[0]).should.be.eql({ context: null, resource: "?query", resourcePath: "", resourceQuery: "?query", loaderIndex: 0, query: { ok: true }, currentRequest: path.resolve(fixtures, "keys-loader.js") + "??my-ident!?query", remainingRequest: "?query", previousRequest: "", request: path.resolve(fixtures, "keys-loader.js") + "??my-ident!" + "?query", data: null, loaders: [{ request: path.resolve(fixtures, "keys-loader.js") + "??my-ident", path: path.resolve(fixtures, "keys-loader.js"), query: "??my-ident", ident: "my-ident", options: { ok: true }, data: null, pitchExecuted: true, normalExecuted: true }] }); } catch(e) { return done(e); } done(); }); }); it("should allow to change loader order and execution", function(done) { runLoaders({ resource: path.resolve(fixtures, "bom.bin"), loaders: [ path.resolve(fixtures, "change-stuff-loader.js"), path.resolve(fixtures, "simple-loader.js"), path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql([ "resource" ]); done(); }); }); it("should return dependencies even if resource is missing", function(done) { runLoaders({ resource: path.resolve(fixtures, "missing.txt"), loaders: [ path.resolve(fixtures, "pitch-dependencies-loader.js") ] }, function(err, result) { err.should.be.instanceOf(Error); err.message.should.match(/ENOENT/i); result.fileDependencies.should.be.eql([ "remainingRequest:" + path.resolve(fixtures, "missing.txt"), path.resolve(fixtures, "missing.txt") ]); done(); }); }); it("should return dependencies even if loader is failing", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "failing-loader.js") ] }, function(err, result) { err.should.be.instanceOf(Error); err.message.should.match(/^resource$/i); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); done(); }); }); it("should use an ident if passed", function(done) { runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [{ loader: path.resolve(fixtures, "pitching-loader.js") }, { loader: path.resolve(fixtures, "simple-loader.js"), options: { f: function() {} }, ident: "my-ident" }] }, function(err, result) { if(err) return done(err); result.result.should.be.eql([ path.resolve(fixtures, "simple-loader.js") + "??my-ident!" + path.resolve(fixtures, "resource.bin") + ":" ]); done(); }); }); it("should load a loader using System.import and process", function(done) { global.System = { import: function(moduleId) { return Promise.resolve(require(moduleId)); } }; runLoaders({ resource: path.resolve(fixtures, "resource.bin"), loaders: [ path.resolve(fixtures, "simple-loader.js") ] }, function(err, result) { if(err) return done(err); result.result.should.be.eql(["resource-simple"]); result.cacheable.should.be.eql(true); result.fileDependencies.should.be.eql([ path.resolve(fixtures, "resource.bin") ]); result.contextDependencies.should.be.eql([]); done(); }); delete global.System; }); describe("getContext", function() { var TESTS = [ ["/", "/"], ["/path/file.js", "/path"], ["/some/longer/path/file.js", "/some/longer/path"], ["/file.js", "/"], ["C:\\", "C:\\"], ["C:\\file.js", "C:\\"], ["C:\\some\\path\\file.js", "C:\\some\\path"], ["C:\\path\\file.js", "C:\\path"], ]; TESTS.forEach(function(testCase) { it("should get the context of '" + testCase[0] + "'", function() { getContext(testCase[0]).should.be.eql(testCase[1]); }); }); }); });