test refactored to mocha (part 1), bugfixes

This commit is contained in:
Tobias Koppers 2012-05-26 00:51:02 +02:00
parent a80e5c9f86
commit 23b2476833
11 changed files with 395 additions and 303 deletions

View File

@ -203,7 +203,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
if(c.contexts)
c.contexts.forEach(addContext(c));
});
requiresNames = Object.keys(requires);
var requiresNames = Object.keys(requires);
var count = requiresNames.length + contexts.length + 1;
var errors = [];
if(requiresNames.length)

View File

@ -76,41 +76,41 @@ function doResolve(context, identifier, options, type, callback) {
if(!options.alias)
options.alias = {};
var identifiers = identifier.replace(/^!|!$/g, "").replace(/!!/g, "!").split(/!/g);
if(identifier.indexOf("!") === -1) {
var resource = identifiers.pop();
for(var i = 0; i < options.loaders.length; i++) {
var line = options.loaders[i];
if(line.test.test(resource)) {
Array.prototype.push.apply(identifiers, line.loader.split(/!/g));
break;
}
}
identifiers.push(resource);
}
var errors = [];
var count = identifiers.length;
function endOne() {
count--;
if(count === 0) {
if(errors.length > 0) {
callback(errors.join("\n"));
return;
}
callback(null, identifiers.join("!"));
}
}
identifiers.forEach(function(ident, index) {
resolve(context, ident, options, index === identifiers.length - 1 ? type : "loader", function(err, filename) {
if(err) {
errors.push(err);
} else {
if(!filename) {
throw new Error(JSON.stringify({identifiers: identifiers, from: ident, to: filename}));
var resource = identifiers.pop();
resolve(context, resource, options, type, function(err, resource) {
if(err) return callback(err);
if(identifier.indexOf("!") === -1) {
for(var i = 0; i < options.loaders.length; i++) {
var line = options.loaders[i];
if(line.test.test(resource)) {
Array.prototype.push.apply(identifiers, line.loader.split(/!/g));
break;
}
identifiers[index] = filename;
}
endOne()
}
var errors = [];
var count = identifiers.length;
function endOne() {
count--;
if(count === 0) {
if(errors.length > 0) {
callback(errors.join("\n"));
return;
}
identifiers.push(resource);
callback(null, identifiers.join("!"));
}
}
if(count == 0) endOne(count++);
identifiers.forEach(function(ident, index) {
resolve(context, ident, options, "loader", function(err, filename) {
if(err) {
errors.push(err);
} else {
identifiers[index] = filename;
}
endOne()
});
});
});
}

View File

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "0.4.7",
"version": "0.4.8",
"author": "Tobias Koppers @sokra",
"description": "Packs CommonJs Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loading of js, json, jade, coffee, css, ... out of the box and more with custom loaders.",
"dependencies": {
@ -27,7 +27,8 @@
}
],
"devDependencies": {
"vows": "*"
"mocha": "*",
"should": "*"
},
"engines": {
"node": ">=0.1.30"
@ -36,7 +37,7 @@
"main": "lib/webpack.js",
"bin": "./bin/webpack.js",
"scripts": {
"test": "node node_modules/vows/bin/vows"
"test": "node node_modules/mocha/bin/_mocha --reporter spec"
},
"license": "MIT"
}

View File

@ -107,9 +107,13 @@ module.exports = function(req) {
values = context.values;
}
});
var ret;
if(values !== undefined)
return values[0];
return exec(content[0], cacheLine);
ret = values[0];
else
ret = exec(content[0], cacheLine);
oldReq.cache[cacheLine] = ret;
return ret;
} else {
var resolved = oldReq.resolve(name);
var match = false;

129
test/buildDeps.js Normal file
View File

@ -0,0 +1,129 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var should = require("should");
var path = require("path");
var buildDeps = require("../lib/buildDeps");
describe("buildDeps", function() {
describe("of main1", function() {
var depTree;
before(function(done) {
buildDeps(path.join(__dirname, "fixtures"), "./main1.js", function(err, tree) {
if(err) return done(err);
should.exist(tree);
depTree = tree;
done();
});
});
it("should compile", function() {
depTree.should.have.property("modulesByFile").and.be.a("object");
depTree.should.have.property("modules").and.be.a("object");
depTree.should.have.property("chunks").and.be.a("object");
});
it("should have all modules loaded", function() {
depTree.modulesByFile.should.have.keys([
path.join(__dirname, "fixtures", "main1.js"),
path.join(__dirname, "fixtures", "a.js"),
path.join(__dirname, "fixtures", "b.js"),
path.join(__dirname, "fixtures", "node_modules", "m1", "a.js")
]);
});
it("should be one chunk", function() {
depTree.chunks.should.have.keys(["main"]);
for(var i in depTree.modulesById) {
depTree.modulesById[i].should.have.property("chunks", ["main"]);
}
});
});
describe("of main2", function() {
var depTree;
before(function(done) {
buildDeps(path.join(__dirname, "fixtures"), "./main2.js", function(err, tree) {
if(err) return done(err);
should.not.exist(err);
should.exist(tree);
depTree = tree;
done();
});
});
it("should compile", function() {
depTree.should.have.property("modulesByFile").and.be.a("object");
depTree.should.have.property("modules").and.be.a("object");
depTree.should.have.property("chunks").and.be.a("object");
});
it("should have all modules loaded", function() {
depTree.modulesByFile.should.have.keys([
path.join(__dirname, "fixtures", "main2.js"),
path.join(__dirname, "fixtures", "a.js"),
path.join(__dirname, "fixtures", "b.js"),
path.join(__dirname, "fixtures", "node_modules", "m1", "a.js"),
path.join(__dirname, "fixtures", "node_modules", "m1", "b.js")
]);
});
it("should be two chunks", function() {
depTree.chunks.should.have.keys(["1", "main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "main2.js")].chunks.should.be.eql(["main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].chunks.should.be.eql(["main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "b.js")].chunks.should.be.eql(["main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "a.js")].chunks.should.be.eql([1]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "b.js")].chunks.should.be.eql([1]);
});
});
describe("of main3", function() {
var depTree;
before(function(done) {
buildDeps(path.join(__dirname, "fixtures"), "./main3.js", function(err, tree) {
if(err) return done(err);
should.not.exist(err);
should.exist(tree);
depTree = tree;
done();
});
});
it("should compile", function() {
depTree.should.have.property("modulesByFile").and.be.a("object");
depTree.should.have.property("modules").and.be.a("object");
depTree.should.have.property("chunks").and.be.a("object");
});
it("should have all modules loaded", function() {
depTree.modulesByFile.should.have.keys([
path.join(__dirname, "fixtures", "main3.js"),
path.join(__dirname, "fixtures", "a.js"),
path.join(__dirname, "fixtures", "c.js")
]);
});
it("should be two chunks", function() {
depTree.chunks.should.have.keys(["1", "main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "main3.js")].chunks.should.be.eql(["main"]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].chunks.should.be.eql(["main", 1]);
depTree.modulesByFile[path.join(__dirname, "fixtures", "c.js")].chunks.should.be.eql([1]);
});
it("should have correct chucks", function() {
var main3id = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "main3.js")].id;
var aid = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].id;
var cid = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "c.js")].id;
depTree.chunks.should.have.property("main").have.property("modules");
depTree.chunks.should.have.property("1").have.property("modules");
depTree.chunks.main.modules.should.have.keys([main3id, aid]);
depTree.chunks[1].modules.should.have.keys([cid, aid]);
depTree.chunks.main.modules[main3id].should.be.equal("include");
depTree.chunks.main.modules[aid].should.be.equal("include");
depTree.chunks[1].modules[aid].should.be.equal("in-parent");
depTree.chunks[1].modules[cid].should.be.equal("include");
});
});
});

View File

@ -1,83 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var vows = require("vows");
var assert = require("assert");
var path = require("path");
var buildDeps = require("../lib/buildDeps");
vows.describe("buildDeps").addBatch({
"main1": {
topic: function() {
buildDeps(path.join(__dirname, "fixtures"), "./main1.js", this.callback);
},
"all modules loaded": function(depTree) {
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "main1.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "b.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "a.js")], null);
},
"one chunk": function(depTree) {
assert.deepEqual(Object.keys(depTree.chunks), ["main"]);
for(var i in depTree.modulesById) {
assert.deepEqual(depTree.modulesById[i].chunks, ["main"]);
}
}
},
"main2": {
topic: function() {
buildDeps(path.join(__dirname, "fixtures"), "./main2.js", {}, this.callback);
},
"all modules loaded": function(depTree) {
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "main2.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "b.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "a.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "b.js")], null);
},
"two chunks": function(depTree) {
assert.deepEqual(Object.keys(depTree.chunks), ["1", "main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "main2.js")].chunks, ["main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].chunks, ["main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "b.js")].chunks, ["main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "a.js")].chunks, ["1"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "node_modules", "m1", "b.js")].chunks, ["1"]);
}
},
"main3": {
topic: function() {
buildDeps(path.join(__dirname, "fixtures"), "./main3.js", {}, this.callback);
},
"all modules loaded": function(depTree) {
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "main3.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")], null);
assert.notEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "c.js")], null);
},
"two chunks": function(depTree) {
assert.deepEqual(Object.keys(depTree.chunks), ["1", "main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "main3.js")].chunks, ["main"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].chunks, ["main", "1"]);
assert.deepEqual(depTree.modulesByFile[path.join(__dirname, "fixtures", "c.js")].chunks, ["1"]);
var main3id = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "main3.js")].id;
var aid = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "a.js")].id;
var cid = ""+depTree.modulesByFile[path.join(__dirname, "fixtures", "c.js")].id;
assert.deepEqual(Object.keys(depTree.chunks.main.modules), [main3id, aid]);
assert.deepEqual(Object.keys(depTree.chunks["1"].modules), [cid, aid]);
assert.deepEqual(depTree.chunks.main.modules[main3id], "include");
assert.deepEqual(depTree.chunks.main.modules[aid], "include");
assert.deepEqual(depTree.chunks["1"].modules[aid], "in-parent");
assert.deepEqual(depTree.chunks["1"].modules[cid], "include");
}
}
}).export(module);

3
test/fixtures/node_modules/m2-loader/b.js generated vendored Normal file
View File

@ -0,0 +1,3 @@
module.exports = function() {
"module.exports = 'This is m2-loader/b';";
}

147
test/polyfills.js Normal file
View File

@ -0,0 +1,147 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var should = require("should");
var path = require("path");
require = require("../require-polyfill")(require.valueOf());
describe("polyfill", function() {
describe("require.context", function() {
var context = require.context("./fixtures")
it("should be able to require a file without extension", function() {
var a = context("./a");
should.exist(a);
a.should.be.a("function");
a().should.be.equal("This is a");
});
it("should be able to require a file with extension", function() {
var a = context("./a.js");
should.exist(a);
a.should.be.a("function");
a().should.be.equal("This is a");
});
it("should be able to require a file in a subdirectory", function() {
var complex1 = context("./lib/complex1");
should.exist(complex1);
complex1.should.be.equal("lib complex1");
});
it("should throw an exception if the module does not exists", function() {
(function() {
context("./notExists.js");
}).should.throw(/Cannot find module/);
});
});
describe("require.ensure", function() {
it("should be executed synchron", function() {
var executed = false;
var oldRequire = require;
require.ensure([], function(require) {
executed = true;
should.exist(require);
require.should.be.a("function");
require.should.be.equal(oldRequire);
});
executed.should.be.ok;
});
it("should work with modules list", function() {
require.ensure(["./fixtures/a"], function(require) {
var a = require("./fixtures/a");
should.exist(a);
a.should.be.a("function");
a().should.be.equal("This is a");
});
});
});
describe("loader", function() {
describe("raw", function() {
it("should load abc", function() {
var abc = require("raw!./fixtures/abc.txt");
should.exist(abc);
abc.should.be.equal("abc");
});
});
describe("json", function() {
it("should load the package.json", function() {
var packageJson = require("json!../package.json");
should.exist(packageJson);
packageJson.should.be.a("object");
packageJson.should.have.ownProperty("name", "webpack");
});
});
describe("jade", function() {
it("should load the template", function() {
var template = require("jade!./browsertest/resources/template.jade")
should.exist(template);
template.should.be.a("function");
template({abc: "abc"}).should.be.equal("<p>abc</p>");
});
});
describe("coffee", function() {
it("should load a script", function() {
var coffee = require("coffee!./browsertest/resources/script.coffee");
should.exist(coffee);
coffee.should.be.equal("coffee test");
});
});
describe("css", function() {
it("should load css and resolve imports", function() {
var css = require("css!./browsertest/css/stylesheet.css");
should.exist(css);
css.should.include(".rule-direct");
css.should.include(".rule-import1");
css.should.include(".rule-import2");
});
});
describe("less", function() {
it("should compile to css and resolve imports", function() {
var css = require("less!./browsertest/less/stylesheet.less");
should.exist(css);
css.should.include(".less-rule-direct");
css.should.include(".less-rule-import1");
css.should.include(".less-rule-import2");
});
});
describe("cache", function() {
it("json should be identical if required two times", function() {
var p1 = require("json!../package.json");
var p2 = require("json!../package.json");
p1.should.be.equal(p2);
});
it("jade function should be identical if required two times", function() {
var p1 = require("jade!./browsertest/resources/template.jade");
var p2 = require("jade!./browsertest/resources/template.jade");
p1.should.be.equal(p2);
});
});
});
describe("loader to extension mapping", function() {
function testRequire(ext, testName, okName) {
it("should map ." + ext, function() {
var okValue = require(okName);
var testValue = require(testName);
should.exist(testValue);
testValue.toString().should.eql(okValue.toString());
});
}
testRequire("json", "json!../package.json", "../package.json");
testRequire("jade", "jade!./browsertest/resources/template.jade", "./browsertest/resources/template.jade");
testRequire("coffee", "coffee!./browsertest/resources/script.coffee", "./browsertest/resources/script.coffee");
});
});

View File

@ -1,133 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var vows = require("vows");
var assert = require("assert");
var path = require("path");
require = require("../require-polyfill")(require.valueOf());
vows.describe("polyfills").addBatch({
"polyfill context": {
topic: function() {
return require.context("./fixtures")
},
"simple file": {
topic: function(context) {
return context("./a");
},
"correct file": function(a) {
assert.equal(a(), "This is a");
}
},
"simple file with extension": {
topic: function(context) {
return context("./a.js");
},
"correct file": function(a) {
assert.equal(a(), "This is a");
}
},
"file in folder": {
topic: function(context) {
return context("./lib/complex1");
},
"correct file": function(complex1) {
assert.equal(complex1, "lib complex1");
}
}
},
"polyfill ensure": {
"empty ensure list": {
topic: function() {
var cb = this.callback;
require.ensure([], function(require) {
cb(null, require("./fixtures/a"));
});
},
"executed": function(a) {
assert.equal(a(), "This is a");
}
},
"with ensure list": {
topic: function() {
var cb = this.callback;
require.ensure(["./fixtures/a"], function(require) {
cb(null, require("./fixtures/a"));
});
},
"executed": function(a) {
assert.equal(a(), "This is a");
}
}
},
"polyfill loaders": {
"buildin raw loader": {
topic: require("raw!./fixtures/abc.txt"),
"raw loaded": function(abc) {
assert.equal(abc, "abc");
}
},
"buildin json loader": {
topic: require("json!../package.json"),
"json loaded": function(packageJson) {
assert.equal(packageJson.name, "webpack");
}
},
"buildin jade loader": {
topic: function() {
return require("jade!./browsertest/resources/template.jade");
},
"jade loaded": function(template) {
assert.equal(template({abc:"abc"}), "<p>abc</p>");
}
},
"buildin coffee loader": {
topic: function() {
return require("coffee!./browsertest/resources/script.coffee") || 1;
},
"coffee loaded": function(result) {
assert.equal(result, "coffee test");
}
},
"buildin css loader": {
topic: function() {
return require("css!./browsertest/css/stylesheet.css") || 1;
},
"css loaded": function(result) {
assert.isTrue(result.indexOf(".rule-direct") !== -1);
assert.isTrue(result.indexOf(".rule-import1") !== -1);
assert.isTrue(result.indexOf(".rule-import2") !== -1);
}
},
"buildin less loader": {
topic: function() {
return require("less!./browsertest/less/stylesheet.less") || 1;
},
"less loaded": function(result) {
assert.isTrue(result.indexOf(".less-rule-direct") !== -1);
assert.isTrue(result.indexOf(".less-rule-import1") !== -1);
assert.isTrue(result.indexOf(".less-rule-import2") !== -1);
}
}
}
}).export(module);

72
test/resolve.js Normal file
View File

@ -0,0 +1,72 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var should = require("should");
var path = require("path");
var resolve = require("../lib/resolve");
var fixtures = path.join(__dirname, "fixtures");
function testResolve(name, context, moduleName, result) {
describe(name, function() {
it("should resolve correctly", function() {
resolve(context, moduleName, {}, function(err, filename) {
should.not.exist(err);
should.exist(filename);
filename.should.equal(result);
});
});
});
}
function testResolveContext(name, context, moduleName, result) {
describe(name, function() {
it("should resolve correctly", function() {
resolve.context(context, moduleName, {}, function(err, filename) {
should.not.exist(err);
should.exist(filename)
filename.should.equal(result);
});
});
});
}
describe("resolve", function() {
testResolve("file with .js",
fixtures, "./main1.js", path.join(fixtures, "main1.js"));
testResolve("file without extension",
fixtures, "./main1", path.join(fixtures, "main1.js"));
testResolve("another file with .js",
fixtures, "./a.js", path.join(fixtures, "a.js"));
testResolve("another file without extension",
fixtures, "./a", path.join(fixtures, "a.js"));
testResolve("file in module with .js",
fixtures, "m1/a.js", path.join(fixtures, "node_modules", "m1", "a.js"));
testResolve("file in module without extension",
fixtures, "m1/a", path.join(fixtures, "node_modules", "m1", "a.js"));
testResolve("another file in module without extension",
fixtures, "complexm/step1", path.join(fixtures, "node_modules", "complexm", "step1.js"));
testResolve("from submodule to file in sibling module",
path.join(fixtures, "node_modules", "complexm"), "m2/b.js", path.join(fixtures, "node_modules", "m2", "b.js"));
testResolve("from submodule to file in sibling of parent module",
path.join(fixtures, "node_modules", "complexm", "web_modules", "m1"), "m2/b.js", path.join(fixtures, "node_modules", "m2", "b.js"));
testResolve("loader",
fixtures, "m1/a!./main1.js", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + path.join(fixtures, "main1.js"));
testResolve("loader with prefix",
fixtures, "m2/b!./main1.js", path.join(fixtures, "node_modules", "m2-loader", "b.js") + "!" + path.join(fixtures, "main1.js"));
testResolve("multiple loaders",
fixtures, "m1/a!m1/b!m2/b!./main1.js", path.join(fixtures, "node_modules", "m1", "a.js") + "!" +
path.join(fixtures, "node_modules", "m1", "b.js") + "!" +
path.join(fixtures, "node_modules", "m2", "b.js") + "!" +
path.join(fixtures, "main1.js"));
testResolveContext("context for fixtures",
fixtures, "./", fixtures);
testResolveContext("context for fixtures/lib",
fixtures, "./lib", path.join(fixtures, "lib"));
testResolveContext("context with loader",
fixtures, "m1/a!./", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + fixtures);
testResolveContext("context with loaders in parent directory",
fixtures, "m1/a!m2/b.js!../", path.join(fixtures, "node_modules", "m1", "a.js") + "!" +
path.join(fixtures, "node_modules", "m1", "a.js") + "!" +
path.join(fixtures, ".."));
});

View File

@ -1,48 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var vows = require("vows");
var assert = require("assert");
var path = require("path");
var resolve = require("../lib/resolve");
var fixtures = path.join(__dirname, "fixtures");
function testResolve(context, moduleName, result) {
return {
topic: function() {
resolve(context, moduleName, {}, this.callback);
},
"correct filename": function(filename) {
assert.equal(filename, result);
}
}
}
function testResolveContext(context, moduleName, result) {
return {
topic: function() {
resolve.context(context, moduleName, {}, this.callback);
},
"correct filename": function(filename) {
assert.equal(filename, result);
}
}
}
vows.describe("resolve").addBatch({
"resolve simple 1": testResolve(fixtures, "./main1.js", path.join(fixtures, "main1.js")),
"resolve simple 2": testResolve(fixtures, "./main1", path.join(fixtures, "main1.js")),
"resolve simple 3": testResolve(fixtures, "./a.js", path.join(fixtures, "a.js")),
"resolve simple 4": testResolve(fixtures, "./a", path.join(fixtures, "a.js")),
"resolve module 1": testResolve(fixtures, "m1/a.js", path.join(fixtures, "node_modules", "m1", "a.js")),
"resolve module 2": testResolve(fixtures, "m1/a", path.join(fixtures, "node_modules", "m1", "a.js")),
"resolve complex 1": testResolve(fixtures, "complexm/step1", path.join(fixtures, "node_modules", "complexm", "step1.js")),
"resolve complex 2": testResolve(path.join(fixtures, "node_modules", "complexm", "web_modules", "m1"),
"m2/b.js", path.join(fixtures, "node_modules", "m2", "b.js")),
"resolve loader 1": testResolve(fixtures, "m1/a!./main1.js", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + path.join(fixtures, "main1.js")),
"resolve loader context 1": testResolveContext(fixtures, "m1/a!./", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + fixtures),
}).export(module);