Created
October 28, 2009 21:15
-
-
Save kriskowal/220851 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/engines/rhino/bootstrap.js b/engines/rhino/bootstrap.js | |
index 6532a41..1af8f57 100644 | |
--- a/engines/rhino/bootstrap.js | |
+++ b/engines/rhino/bootstrap.js | |
@@ -89,28 +89,30 @@ | |
try { | |
narwhal({ | |
- global: global, | |
- evalGlobal: evalGlobal, | |
- engine: 'rhino', | |
- engines: ['rhino', 'default'], | |
- os: os, | |
- print: print, | |
- fs: { | |
+ system: { | |
+ global: global, | |
+ evalGlobal: evalGlobal, | |
+ engine: 'rhino', | |
+ engines: ['rhino', 'default'], | |
+ os: os, | |
+ print: print, | |
+ prefix: prefix, | |
+ prefixes: prefixes, | |
+ evaluate: evaluate, | |
+ debug: debug, | |
+ verbose: verbose | |
+ }, | |
+ file: { | |
read: read, | |
isFile: isFile | |
- }, | |
- prefix: prefix, | |
- prefixes: prefixes, | |
- evaluate: evaluate, | |
- debug: debug, | |
- verbose: verbose | |
+ } | |
}); | |
} catch (e) { | |
- print(e); | |
if (e.rhinoException) | |
e.rhinoException.printStackTrace(); | |
if (e.javaException) | |
e.javaException.printStackTrace(); | |
+ print(e); | |
Packages.java.lang.System.exit(1); | |
} | |
diff --git a/engines/template/bootstrap.js b/engines/template/bootstrap.js | |
index 3f850a5..608abc7 100644 | |
--- a/engines/template/bootstrap.js | |
+++ b/engines/template/bootstrap.js | |
@@ -8,31 +8,33 @@ | |
var enginePrefix = "/path/to/engine"; /*TODO*/ | |
eval(read(prefix + "/narwhal.js"))({ | |
- global: this, | |
- evalGlobal: evalGlobal, | |
- engine: '<<<name>>>', /*TODO*/ | |
- engines: ['<<<name>>>', 'default'], /*TODO*/ | |
- os: "", /* TODO /\bwindows\b/i for Windows FS support */ | |
- // XXX engines may include any number of | |
- // prioritized generic engines like: | |
- // rhino, java, c, v8, default | |
- print: print, | |
- evaluate: function (text) { | |
- // TODO maybe something better here: | |
- return eval( | |
- "(function(require,exports,module,system,print){" + | |
- text + | |
- "/**/\n})" | |
- ); | |
+ system: { | |
+ global: this, | |
+ evalGlobal: evalGlobal, | |
+ engine: '<<<name>>>', /*TODO*/ | |
+ engines: ['<<<name>>>', 'default'], /*TODO*/ | |
+ os: "", /* TODO /\bwindows\b/i for Windows FS support */ | |
+ // XXX engines may include any number of | |
+ // prioritized generic engines like: | |
+ // rhino, java, c, v8, default | |
+ print: print, | |
+ evaluate: function (text) { | |
+ // TODO maybe something better here: | |
+ return eval( | |
+ "(function(require,exports,module,system,print){" + | |
+ text + | |
+ "/**/\n})" | |
+ ); | |
+ }, | |
+ prefix: prefix, | |
+ prefixes: [prefix, enginePrefix], | |
+ debug: false, | |
+ verbose: false | |
}, | |
- fs: { | |
+ file: { | |
read: read, | |
isFile: isFile | |
- }, | |
- prefix: prefix, | |
- prefixes: [prefix, enginePrefix], | |
- debug: false, | |
- verbose: false | |
+ } | |
}); | |
}).call(this, function () { | |
diff --git a/lib/args.js b/lib/args.js | |
index 348ca67..b51ee1a 100644 | |
--- a/lib/args.js | |
+++ b/lib/args.js | |
@@ -3,6 +3,7 @@ var os = require('os'); | |
var util = require('util'); | |
var stream = require('term').stream; | |
var system = require('system'); | |
+var file = require('file'); | |
exports.UsageError = function (message) { | |
this.name = "UsageError"; | |
@@ -164,7 +165,7 @@ exports.Parser.prototype.printHelp = function (options) { | |
exports.Parser.prototype.printUsage = function (options) { | |
this.print( | |
- 'Usage: \0bold(\0blue(' + system.fs.basename(options.command || '<unknown>') + ' [OPTIONS]' + | |
+ 'Usage: \0bold(\0blue(' + file.basename(options.command || '<unknown>') + ' [OPTIONS]' + | |
(util.len(this._commands) ? | |
' COMMAND' : | |
'' | |
@@ -684,7 +685,7 @@ exports.Option.prototype.input = function () { | |
if (value == "-") | |
return system.stdin; | |
else | |
- return system.fs.open(value, 'r'); | |
+ return file.open(value, 'r'); | |
}); | |
}; | |
@@ -693,7 +694,7 @@ exports.Option.prototype.output = function () { | |
if (value == "-") | |
return system.stdout; | |
else | |
- return system.fs.open(value, 'w'); | |
+ return file.open(value, 'w'); | |
}); | |
}; | |
diff --git a/lib/file-bootstrap.js b/lib/file-bootstrap.js | |
index e84de99..b4aee04 100644 | |
--- a/lib/file-bootstrap.js | |
+++ b/lib/file-bootstrap.js | |
@@ -2,8 +2,7 @@ | |
// NOTE: this file is used is the bootstrapping process, | |
// so any "requires" must be accounted for in narwhal.js | |
-// use the "file" module as the exports object. | |
-var exports = require("file"); | |
+exports = require("file"); | |
var system = require("system"); | |
/* path manipulation, needed by the sandbox module in the | |
@@ -50,7 +49,7 @@ exports.join = function () { | |
exports.split = function (path) { | |
var parts; | |
try { | |
- parts = String(path).split(exports.SEPARATORS_RE()); | |
+ parts = String(path).split(exports.SEPARATORS_RE()); | |
} catch (exception) { | |
throw new Error("Cannot split " + (typeof path) + ', "' + path + '"'); | |
} | |
diff --git a/lib/file.js b/lib/file.js | |
index 15c0c41..e7c0d89 100644 | |
--- a/lib/file.js | |
+++ b/lib/file.js | |
@@ -4,6 +4,8 @@ | |
var io = require('io'); | |
+require("file-bootstrap"); | |
+ | |
/* streams */ | |
exports.open = function (path, mode, options) { | |
@@ -192,8 +194,9 @@ exports.copy = function (source, target) { | |
source.open("rb").copy(target.open("wb")).close(); | |
}; | |
+var list = exports.list; | |
exports.list = function (path) { | |
- return exports.listImpl(String(path || '') || "."); | |
+ return list(String(path || '') || "."); | |
}; | |
exports.listTree = function (path) { | |
@@ -614,8 +617,5 @@ for (var i = 0; i < nonPathed.length; i++) { | |
})(name); | |
} | |
-// load "file-bootstrap" and "file-engine", which in turn load "file" and modify it's module object. | |
-// "engine" gets priority so it's loaded last. | |
-require("file-bootstrap"); | |
require("file-engine"); | |
diff --git a/lib/loader.js b/lib/loader.js | |
new file mode 100644 | |
index 0000000..168a4bc | |
--- /dev/null | |
+++ b/lib/loader.js | |
@@ -0,0 +1,109 @@ | |
+ | |
+// NOTE: this file is used is the bootstrapping process, | |
+// so any "requires" must be accounted for in narwhal.js | |
+ | |
+var system = require("system"); | |
+// HACK: the stars prevent the file module from being sent to browser | |
+// clients with the regexen we're using. we need a real solution | |
+// for this. | |
+var file = require(/**/"file"/**/); | |
+ | |
+// this gets swapped out with a full fledged-read before | |
+// we're done using it | |
+var read = file.read; | |
+ | |
+exports.Loader = function (options) { | |
+ var loader = {}; | |
+ var factories = options.factories || {}; | |
+ var paths = options.paths; | |
+ var extensions = options.extensions || ["", ".js"]; | |
+ var timestamps = {}; | |
+ var debug = options.debug; | |
+ | |
+ loader.resolve = exports.resolve; | |
+ | |
+ loader.find = function (topId) { | |
+ // if it's absolute only search the "root" directory. | |
+ // file.join() must collapse multiple "/" into a single "/" | |
+ var searchPaths = file.isAbsolute(topId) ? [""] : paths; | |
+ | |
+ for (var j = 0; j < extensions.length; j++) { | |
+ var extension = extensions[j]; | |
+ for (var i = 0; i < searchPaths.length; i++) { | |
+ var path = file.join(searchPaths[i], topId + extension); | |
+ if (file.isFile(path)) | |
+ return path; | |
+ } | |
+ } | |
+ throw new Error("require error: couldn't find \"" + topId + '"'); | |
+ }; | |
+ | |
+ loader.fetch = function (topId, path) { | |
+ if (!path) | |
+ path = loader.find(topId); | |
+ if (typeof file.mtime === "function") | |
+ timestamps[path] = file.mtime(path); | |
+ if (debug) | |
+ print('loader: fetching ' + topId); | |
+ var text = read(path, { | |
+ 'charset': 'utf-8' | |
+ }); | |
+ // we leave the endline so the error line numbers align | |
+ text = text.replace(/^#[^\n]+\n/, "\n"); | |
+ return text; | |
+ }; | |
+ | |
+ loader.evaluate = function (text, topId) { | |
+ if (system.evaluate) { | |
+ var fileName = loader.find(topId); | |
+ var factory = system.evaluate(text, fileName, 1); | |
+ factory.path = fileName; | |
+ return factory; | |
+ } else { | |
+ return new Function("require", "exports", "module", "system", "print", text); | |
+ } | |
+ }; | |
+ | |
+ loader.load = function (topId) { | |
+ if (!Object.prototype.hasOwnProperty.call(factories, topId)) { | |
+ loader.reload(topId); | |
+ } else if (typeof file.mtime === "function") { | |
+ var path = loader.find(topId); | |
+ if (loader.hasChanged(topId, path)) | |
+ loader.reload(topId); | |
+ } | |
+ return factories[topId]; | |
+ }; | |
+ | |
+ loader.reload = function (topId, path) { | |
+ factories[topId] = loader.evaluate(loader.fetch(topId, path), topId); | |
+ }; | |
+ | |
+ loader.isLoaded = function (topId) { | |
+ return Object.prototype.hasOwnProperty.call(factories, topId); | |
+ }; | |
+ | |
+ loader.hasChanged = function (topId, path) { | |
+ if (!path) | |
+ path = loader.resolve(topId); | |
+ return ( | |
+ !Object.prototype.hasOwnProperty.call(timestamps, path) || | |
+ file.mtime(path) > timestamps[path] | |
+ ); | |
+ }; | |
+ | |
+ loader.paths = paths; | |
+ loader.extensions = extensions; | |
+ | |
+ return loader; | |
+}; | |
+ | |
+exports.resolve = function (id, baseId) { | |
+ if (typeof id != "string") | |
+ throw new Error("module id '" + id + "' is not a String"); | |
+ if (id.charAt(0) == ".") { | |
+ id = file.dirname(baseId) + "/" + id; | |
+ } | |
+ return file.normal(id); | |
+}; | |
+ | |
diff --git a/lib/loader/attenuated.js b/lib/loader/attenuated.js | |
new file mode 100644 | |
index 0000000..85adfa3 | |
--- /dev/null | |
+++ b/lib/loader/attenuated.js | |
@@ -0,0 +1,29 @@ | |
+ | |
+exports.AttenuatedLoader = function (loader) { | |
+ var self = {}; | |
+ | |
+ self.resolve = Object.freeze(function (id, baseId) { | |
+ return loader.resolve(id, baseId); | |
+ }); | |
+ | |
+ self.fetch = Object.freeze(function (topId) { | |
+ if (/\./.test(topId)) | |
+ throw new Error("Invalid module identifier: " + topId); | |
+ return loader.fetch(topId); | |
+ }); | |
+ | |
+ self.load = Object.freeze(function (topId, path) { | |
+ if (/\./.test(topId)) | |
+ throw new Error("Invalid module identifier"); | |
+ return loader.load(topId, path); | |
+ }); | |
+ | |
+ self.reload = Object.freeze(function (topId) { | |
+ if (/\./.test(topId)) | |
+ throw new Error("Invalid module identifier"); | |
+ return loader.reload(topId, path); | |
+ }); | |
+ | |
+ return Object.freeze(self); | |
+}; | |
+ | |
diff --git a/lib/loader/multi.js b/lib/loader/multi.js | |
new file mode 100644 | |
index 0000000..3797c28 | |
--- /dev/null | |
+++ b/lib/loader/multi.js | |
@@ -0,0 +1,78 @@ | |
+ | |
+// NOTE: this file is used is the bootstrapping process, | |
+// so any "requires" must be accounted for in narwhal.js | |
+ | |
+var FILE = require("file"); | |
+var LOADER = require("loader"); | |
+ | |
+exports.MultiLoader = function (options) { | |
+ | |
+ var factories = options.factories || {}; | |
+ | |
+ var self = {}; | |
+ self.paths = options.paths || []; | |
+ self.loader = options.loader || LOADER.Loader(options); | |
+ self.loaders = options.loaders || [ | |
+ ["", self.loader], | |
+ [".js", self.loader] | |
+ ]; | |
+ | |
+ self.resolve = LOADER.resolve; | |
+ | |
+ self.find = function (topId) { | |
+ // if it's absolute only search the "root" directory. | |
+ // FILE.join() must collapse multiple "/" into a single "/" | |
+ var searchPaths = FILE.isAbsolute(topId) ? [""] : self.paths; | |
+ | |
+ for (var j = 0; j < self.loaders.length; j++) { | |
+ var extension = self.loaders[j][0]; | |
+ var loader = self.loaders[j][1]; | |
+ for (var i = 0; i < searchPaths.length; i++) { | |
+ var path = FILE.join(searchPaths[i], topId + extension); | |
+ if (FILE.isFile(path)) { | |
+ // now check each extension for a match. | |
+ // handles case when extension is in the id, so it's matched by "", | |
+ // but we want to use the loader corresponding to the actual extension | |
+ for (var k = 0; k < self.loaders.length; k++) { | |
+ var ext = self.loaders[k][0]; | |
+ if (path.lastIndexOf(ext) === path.length - ext.length) | |
+ return [self.loaders[k][1], path]; | |
+ } | |
+ throw "ERROR: shouldn't reach this point!" | |
+ } | |
+ } | |
+ } | |
+ throw "require error: couldn't find \"" + topId + '"'; | |
+ }; | |
+ | |
+ self.load = function (topId, loader, path) { | |
+ if (!loader || !path) { | |
+ var pair = self.find(topId); | |
+ loader = pair[0]; | |
+ path = pair[1]; | |
+ } | |
+ if ( | |
+ !Object.prototype.hasOwnProperty.call(factories, topId) || | |
+ (loader.hasChanged && loader.hasChanged(topId, path)) | |
+ ) | |
+ self.reload(topId, loader, path); | |
+ return factories[topId]; | |
+ }; | |
+ | |
+ self.reload = function (topId, loader, path) { | |
+ if (!loader || !path) { | |
+ var pair = self.find(topId); | |
+ loader = pair[0]; | |
+ path = pair[1]; | |
+ } | |
+ loader.reload(topId, path); | |
+ factories[topId] = loader.load(topId, path); | |
+ }; | |
+ | |
+ self.isLoaded = function (topId) { | |
+ return Object.prototype.hasOwnProperty.call(factories, topId); | |
+ }; | |
+ | |
+ return self; | |
+}; | |
+ | |
diff --git a/lib/loader/prefix.js b/lib/loader/prefix.js | |
new file mode 100644 | |
index 0000000..3439741 | |
--- /dev/null | |
+++ b/lib/loader/prefix.js | |
@@ -0,0 +1,29 @@ | |
+ | |
+exports.PrefixLoader = function (prefix, loader) { | |
+ var self = this || {}; | |
+ | |
+ self.resolve = function (id, baseId) { | |
+ return loader.resolve(id, baseId); | |
+ }; | |
+ | |
+ /**** evaluate | |
+ */ | |
+ self.evaluate = function (text, topId) { | |
+ return loader.evaluate(text, prefix + topId); | |
+ }; | |
+ | |
+ /**** fetch | |
+ */ | |
+ self.fetch = function (topId) { | |
+ return loader.fetch(prefix + topId); | |
+ }; | |
+ | |
+ /**** load | |
+ */ | |
+ self.load = function (topId) { | |
+ return loader.load(prefix + topId); | |
+ }; | |
+ | |
+ return self; | |
+}; | |
+ | |
diff --git a/lib/logger.js b/lib/logger.js | |
index a3d2fce..b4f8dca 100644 | |
--- a/lib/logger.js | |
+++ b/lib/logger.js | |
@@ -8,11 +8,11 @@ | |
// (Stolen from Ruby) | |
// | |
-var system = require("system"); | |
+var file = require("file"); | |
var Logger = exports.Logger = function(output) { | |
if (typeof output === "string") | |
- this.output = system.fs.open(output, "a"); | |
+ this.output = file.open(output, "a"); | |
else | |
this.output = output; | |
diff --git a/lib/narwhal/client.js b/lib/narwhal/client.js | |
index 8506a25..4d6c150 100644 | |
--- a/lib/narwhal/client.js | |
+++ b/lib/narwhal/client.js | |
@@ -184,23 +184,25 @@ function boot() { | |
// and "system" modules with all of their transitive dependencies are ready | |
// to be loaded, we proceed. | |
Q.when(getReady("sandbox").promise, function () { | |
+ return Q.when(getReady("loader").promise, function () { | |
return Q.when(getReady("global").promise, function () { | |
return Q.when(getReady("system").promise, function () { | |
// the sandbox module needs a semi-functional system object | |
- var system = {}; | |
+ var system = modules.system = {}; | |
system.print = function () { | |
if (typeof console != "undefined") { | |
console.log(Array.prototype.join.call(arguments, ' ')); | |
} | |
}; | |
- system.fs = { | |
+ system.engine = "browser"; | |
+ system.engines = ["browser"]; | |
+ | |
+ modules.file = { | |
normal: function (path) { | |
return path; | |
} | |
}; | |
- system.engine = "browser"; | |
- system.engines = ["browser"]; | |
// the loader is relatively simple since it doesn't need to do | |
// any searching or extension resolving. | |
@@ -214,19 +216,34 @@ function boot() { | |
return loader.reload(id); | |
}; | |
+ var requireFake = function (id) { | |
+ return modules[id]; | |
+ }; | |
+ | |
+ // load the loader module manually. | |
+ var LOADER = {}; | |
+ loader.load('loader')( | |
+ requireFake, | |
+ LOADER, | |
+ {}, | |
+ system, | |
+ system.print | |
+ ); | |
+ | |
// load the sandbox module manually. | |
var SANDBOX = {}; | |
loader.load('sandbox')( | |
- function () {return system}, | |
+ requireFake, | |
SANDBOX, | |
{}, | |
system, | |
system.print | |
); | |
+ | |
sandbox = SANDBOX.Sandbox({loader: loader}); | |
// patch the loader with the sandbox module's general purpose resolve | |
// function. | |
- loader.resolve = SANDBOX.resolve; | |
+ loader.resolve = LOADER.resolve; | |
sandbox.async = require.async; | |
@@ -255,7 +272,7 @@ function boot() { | |
} | |
// because lisp wasn't bad enough | |
- });});}); | |
+ });});});}); | |
} | |
diff --git a/lib/narwhal/server.js b/lib/narwhal/server.js | |
index f890e9f..73ceddd 100644 | |
--- a/lib/narwhal/server.js | |
+++ b/lib/narwhal/server.js | |
@@ -2,13 +2,12 @@ | |
var SYSTEM = require("system"); | |
var FILE = require("file"); | |
var UTIL = require("util"); | |
-var SANDBOX = require("sandbox"); | |
var JSMIN = require("jsmin"); | |
var JACKUTILS = require("jack/utils"); | |
-var Loader = SANDBOX.Loader; | |
-var AttenuatedLoader = SANDBOX.AttenuatedLoader; | |
-var Sandbox = SANDBOX.Sandbox; | |
+var Sandbox = require("sandbox").Sandbox; | |
+var Loader = require("loader").Loader; | |
+var AttenuatedLoader = require("loader/attenuated").AttenuatedLoader; | |
var contentType = "application/x-javascript"; | |
@@ -176,6 +175,7 @@ exports.ClientLoader = function (env, path, bundler, options) { | |
var bootstrap = [ | |
"narwhal/client", | |
"sandbox", | |
+ "loader", | |
"system", | |
"ref-send", | |
"reactor" | |
diff --git a/lib/packages.js b/lib/packages.js | |
index 4a99164..d04c2bc 100644 | |
--- a/lib/packages.js | |
+++ b/lib/packages.js | |
@@ -221,46 +221,68 @@ var scan = function scan(catalog, name) { | |
dependent to least dependent, sorted based on | |
their transitive dependencies. | |
*/ | |
-exports.sortedPackages = function sortedPackages(info) { | |
- var order = topo(info); | |
+exports.sortedPackages = function (graph) { | |
var sorted = []; | |
- for (var i = 0; i < order.length; i++) | |
- sorted[i] = info[order[i]]; | |
- return sorted; | |
-}; | |
+ var arrived = {}; | |
+ var departed = {}; | |
+ var t = 0; | |
-var topo = function topo(graph) { | |
- var sorted = [], | |
- visited = {}; | |
+ // linearize the graph nodes | |
+ var nodes = []; | |
for (var name in graph) { | |
- if ( | |
- Object.prototype.hasOwnProperty.call(graph, name) && | |
- !Object.prototype.hasOwnProperty.call(visited, name) | |
- ) { | |
- sorted.push.apply(sorted, _topo(graph, name, visited)); | |
+ if (Object.prototype.hasOwnProperty.call(graph, name)) { | |
+ graph[name].name = name; | |
+ nodes.push(graph[name]); | |
} | |
} | |
- return sorted; | |
-}; | |
-var _topo = function _topo(graph, name, visited) { | |
- var node = graph[name]; | |
- if (Object.prototype.hasOwnProperty.call(visited, node)) | |
- return []; | |
- visited[name] = true; | |
- var sorted = []; | |
- if (graph[name] === undefined) { | |
- system.log.error('"' + name + '" package does not exist.'); | |
- } | |
- var dependencies = graph[name].dependencies || []; | |
- for (var i = 0; i < dependencies.length; i++) { | |
- var dependency = dependencies[i]; | |
- if (Object.prototype.hasOwnProperty.call(visited, dependency)) | |
+ while (nodes.length) { | |
+ var node = nodes.shift(); | |
+ var name = node.name; | |
+ if (Object.prototype.hasOwnProperty.call(arrived, name)) | |
continue; | |
- visited[dependency] = true; | |
- sorted.push.apply(sorted, _topo(graph, dependency, visited)); | |
+ | |
+ var stack = [node]; | |
+ while (stack.length) { | |
+ | |
+ var node = stack[stack.length - 1]; | |
+ var name = node.name; | |
+ | |
+ if (Object.prototype.hasOwnProperty.call(arrived, name)) { | |
+ departed[name] = t++; | |
+ sorted.push(stack.pop()); | |
+ } else { | |
+ arrived[name] = t++; | |
+ var dependencies = node.dependencies || []; | |
+ var length = dependencies.length; | |
+ for (var i = 0; i < length; i++) { | |
+ var dependency = dependencies[i]; | |
+ if (Object.prototype.hasOwnProperty.call(arrived, dependency)) { | |
+ if (!Object.prototype.hasOwnProperty.call(departed, dependency)) { | |
+ throw new Error("Dependency cycle detected among packages: " + stack.map(function (node) { | |
+ return node.name; | |
+ }).join(" -> ") + " -> " + dependency); | |
+ } | |
+ continue; | |
+ } | |
+ if (!Object.prototype.hasOwnProperty.call(graph, dependency)) { | |
+ if (require.debug) { | |
+ print( | |
+ "Throwing away package '" + name + | |
+ "' because it depends on the package '" + dependency + | |
+ "' which is not installed." | |
+ ); | |
+ } | |
+ delete graph[name]; | |
+ continue; | |
+ } | |
+ stack.push(graph[dependency]); | |
+ } | |
+ } | |
+ | |
+ }; | |
} | |
- sorted.push(name); | |
+ | |
return sorted; | |
}; | |
diff --git a/lib/sandbox.js b/lib/sandbox.js | |
index eb67a4c..36c47e8 100644 | |
--- a/lib/sandbox.js | |
+++ b/lib/sandbox.js | |
@@ -4,196 +4,12 @@ | |
var system = require("system"); | |
-exports.Loader = function (options) { | |
- var loader = {}; | |
- var factories = options.factories || {}; | |
- var paths = options.paths; | |
- var extensions = options.extensions || ["", ".js"]; | |
- var timestamps = {}; | |
- var debug = options.debug; | |
- | |
- loader.resolve = exports.resolve; | |
- | |
- loader.find = function (topId) { | |
- // if it's absolute only search the "root" directory. | |
- // file.join() must collapse multiple "/" into a single "/" | |
- var searchPaths = system.fs.isAbsolute(topId) ? [""] : paths; | |
- | |
- for (var j = 0; j < extensions.length; j++) { | |
- var extension = extensions[j]; | |
- for (var i = 0; i < searchPaths.length; i++) { | |
- var path = system.fs.join(searchPaths[i], topId + extension); | |
- if (system.fs.isFile(path)) | |
- return path; | |
- } | |
- } | |
- throw new Error("require error: couldn't find \"" + topId + '"'); | |
- }; | |
- | |
- loader.fetch = function (topId, path) { | |
- if (!path) | |
- path = loader.find(topId); | |
- if (typeof system.fs.mtime === "function") | |
- timestamps[path] = system.fs.mtime(path); | |
- if (debug) | |
- print('loader: fetching ' + topId); | |
- var text = system.fs.read(path, { | |
- 'charset': 'utf-8' | |
- }); | |
- // we leave the endline so the error line numbers align | |
- text = text.replace(/^#[^\n]+\n/, "\n"); | |
- return text; | |
- }; | |
- | |
- loader.evaluate = function (text, topId) { | |
- if (system.evaluate) { | |
- var fileName = loader.find(topId); | |
- var factory = system.evaluate(text, fileName, 1); | |
- factory.path = fileName; | |
- return factory; | |
- } else { | |
- return new Function("require", "exports", "module", "system", "print", text); | |
- } | |
- }; | |
- | |
- loader.load = function (topId) { | |
- if (!Object.prototype.hasOwnProperty.call(factories, topId)) { | |
- loader.reload(topId); | |
- } else if (typeof system.fs.mtime === "function") { | |
- var path = loader.find(topId); | |
- if (loader.hasChanged(topId, path)) | |
- loader.reload(topId); | |
- } | |
- return factories[topId]; | |
- }; | |
- | |
- loader.reload = function (topId, path) { | |
- factories[topId] = loader.evaluate(loader.fetch(topId, path), topId); | |
- }; | |
- | |
- loader.isLoaded = function (topId) { | |
- return Object.prototype.hasOwnProperty.call(factories, topId); | |
- }; | |
- | |
- loader.hasChanged = function (topId, path) { | |
- if (!path) | |
- path = loader.resolve(topId); | |
- return ( | |
- !Object.prototype.hasOwnProperty.call(timestamps, path) || | |
- system.fs.mtime(path) > timestamps[path] | |
- ); | |
- }; | |
- | |
- loader.paths = paths; | |
- loader.extensions = extensions; | |
- | |
- return loader; | |
-}; | |
- | |
-exports.MultiLoader = function (options) { | |
- | |
- var factories = options.factories || {}; | |
- | |
- var self = {}; | |
- self.paths = options.paths || []; | |
- self.loader = options.loader || exports.Loader(options); | |
- self.loaders = options.loaders || [ | |
- ["", self.loader], | |
- [".js", self.loader] | |
- ]; | |
- | |
- self.resolve = exports.resolve; | |
- | |
- self.find = function (topId) { | |
- // if it's absolute only search the "root" directory. | |
- // file.join() must collapse multiple "/" into a single "/" | |
- var searchPaths = system.fs.isAbsolute(topId) ? [""] : self.paths; | |
- | |
- for (var j = 0; j < self.loaders.length; j++) { | |
- var extension = self.loaders[j][0]; | |
- var loader = self.loaders[j][1]; | |
- for (var i = 0; i < searchPaths.length; i++) { | |
- var path = system.fs.join(searchPaths[i], topId + extension); | |
- if (system.fs.isFile(path)) { | |
- // now check each extension for a match. | |
- // handles case when extension is in the id, so it's matched by "", | |
- // but we want to use the loader corresponding to the actual extension | |
- for (var k = 0; k < self.loaders.length; k++) { | |
- var ext = self.loaders[k][0]; | |
- if (path.lastIndexOf(ext) === path.length - ext.length) | |
- return [self.loaders[k][1], path]; | |
- } | |
- throw "ERROR: shouldn't reach this point!" | |
- } | |
- } | |
- } | |
- throw "require error: couldn't find \"" + topId + '"'; | |
- }; | |
- | |
- self.load = function (topId, loader, path) { | |
- if (!loader || !path) { | |
- var pair = self.find(topId); | |
- loader = pair[0]; | |
- path = pair[1]; | |
- } | |
- if ( | |
- !Object.prototype.hasOwnProperty.call(factories, topId) || | |
- (loader.hasChanged && loader.hasChanged(topId, path)) | |
- ) | |
- self.reload(topId, loader, path); | |
- return factories[topId]; | |
- }; | |
- | |
- self.reload = function (topId, loader, path) { | |
- if (!loader || !path) { | |
- var pair = self.find(topId); | |
- loader = pair[0]; | |
- path = pair[1]; | |
- } | |
- loader.reload(topId, path); | |
- factories[topId] = loader.load(topId, path); | |
- }; | |
- | |
- self.isLoaded = function (topId) { | |
- return Object.prototype.hasOwnProperty.call(factories, topId); | |
- }; | |
- | |
- return self; | |
-}; | |
- | |
-exports.AttenuatedLoader = function (loader) { | |
- var self = {}; | |
- | |
- self.resolve = Object.freeze(function (id, baseId) { | |
- return loader.resolve(id, baseId); | |
- }); | |
- | |
- self.fetch = Object.freeze(function (topId) { | |
- if (/\./.test(topId)) | |
- throw new Error("Invalid module identifier: " + topId); | |
- return loader.fetch(topId); | |
- }); | |
- | |
- self.load = Object.freeze(function (topId, path) { | |
- if (/\./.test(topId)) | |
- throw new Error("Invalid module identifier"); | |
- return loader.load(topId, path); | |
- }); | |
- | |
- self.reload = Object.freeze(function (topId) { | |
- if (/\./.test(topId)) | |
- throw new Error("Invalid module identifier"); | |
- return loader.reload(topId, path); | |
- }); | |
- | |
- return Object.freeze(self); | |
-}; | |
- | |
exports.Sandbox = function (options) { | |
options = options || {}; | |
var loader = options.loader; | |
var subsystem = options.system || system || {}; | |
var modules = options.modules || {}; | |
+ var metadata = {}; | |
var debug = options.debug !== undefined ? !!options.debug : !!system.debug; | |
// managed print free variable in the sandbox forwards | |
@@ -203,7 +19,7 @@ exports.Sandbox = function (options) { | |
}; | |
var debugDepth = 0; | |
- var mainId; | |
+ var main; | |
var sandbox = function (id, baseId, force, reload) { | |
id = loader.resolve(id, baseId); | |
@@ -243,17 +59,20 @@ exports.Sandbox = function (options) { | |
} | |
} | |
var require = Require(id, factory.path); | |
- var module = { | |
- 'id': id, | |
- 'path': factory.path | |
+ var module = metadata[id] = metadata[id] || {}; | |
+ module.id = id; | |
+ module.path = factory.path; | |
+ module.toString = function () { | |
+ return this.id; | |
}; | |
+ | |
factory(require, exports, module, subsystem, subprint); | |
if (sandbox.debug) { | |
// check for new globals | |
for (var name in global) | |
if (!globals[name]) | |
- system.log.warn("NEW GLOBAL: " + name); | |
+ system.print("NEW GLOBAL: " + name); | |
} | |
if (sandbox.debug) { | |
@@ -321,7 +140,7 @@ exports.Sandbox = function (options) { | |
//} | |
}; | |
require.loader = loader; | |
- require.main = mainId; | |
+ require.main = main; | |
require.paths = loader.paths; | |
require.extensions = loader.extensions; | |
require.async = sandbox.async; | |
@@ -346,8 +165,9 @@ exports.Sandbox = function (options) { | |
}; | |
sandbox.main = function (id) { | |
- mainId = id; | |
- return sandbox(id); | |
+ main = sandbox.main = metadata[id] = metadata[id] || {}; | |
+ sandbox(id); | |
+ return main; | |
}; | |
sandbox.loader = loader; | |
@@ -359,34 +179,6 @@ exports.Sandbox = function (options) { | |
return sandbox; | |
}; | |
-exports.PrefixLoader = function (prefix, loader) { | |
- var self = this || {}; | |
- | |
- self.resolve = function (id, baseId) { | |
- return loader.resolve(id, baseId); | |
- }; | |
- | |
- /**** evaluate | |
- */ | |
- self.evaluate = function (text, topId) { | |
- return loader.evaluate(text, prefix + topId); | |
- }; | |
- | |
- /**** fetch | |
- */ | |
- self.fetch = function (topId) { | |
- return loader.fetch(prefix + topId); | |
- }; | |
- | |
- /**** load | |
- */ | |
- self.load = function (topId) { | |
- return loader.load(prefix + topId); | |
- }; | |
- | |
- return self; | |
-}; | |
- | |
exports.sandbox = function(main, system, options) { | |
options = options || {}; | |
var prefix = options['prefix']; | |
@@ -400,7 +192,7 @@ exports.sandbox = function(main, system, options) { | |
"sandbox's 'loader' object." | |
); | |
if (prefix) | |
- loader = exports.PrefixLoader(prefix, loader); | |
+ loader = require("loader/prefix").PrefixLoader(prefix, loader); | |
var sandbox = exports.Sandbox({ | |
modules: modules, | |
loader: loader, | |
@@ -408,15 +200,7 @@ exports.sandbox = function(main, system, options) { | |
print: print, | |
debug: debug | |
}); | |
- return sandbox.main(main); | |
-}; | |
-exports.resolve = function (id, baseId) { | |
- if (typeof id != "string") | |
- throw new Error("module id '" + id + "' is not a String"); | |
- if (id.charAt(0) == ".") { | |
- id = system.fs.dirname(baseId) + "/" + id; | |
- } | |
- return system.fs.normal(id); | |
+ return sandbox.main(main); | |
}; | |
diff --git a/narwhal.js b/narwhal.js | |
index 9e8ef52..1051645 100644 | |
--- a/narwhal.js | |
+++ b/narwhal.js | |
@@ -1,29 +1,40 @@ | |
-(function (system) { | |
+(function (modules) { | |
+ | |
+if (modules.fs) { | |
+ // XXX: migration step for deprecated engines | |
+ var system = modules; | |
+ var file = system.fs; | |
+ var modules = {system: system, file: file}; | |
+} else { | |
+ var system = modules.system; | |
+ var file = modules.file; | |
+} | |
// global reference | |
+// XXX: beyond-compliance with CommonJS | |
global = system.global; | |
global.global = global; | |
global.system = system; | |
global.print = system.print; | |
-// logger shim | |
-var logFake = function () { | |
- if (system.debug) { | |
- system.print(Array.prototype.join.apply(arguments, [" "])); | |
- } | |
-}; | |
-var log = {fatal:logFake, error:logFake, warn:logFake, info:logFake, debug:logFake}; | |
-system.log = log; | |
- | |
// this only works for modules with no dependencies and a known absolute path | |
-var requireFake = function(id, path, modules) { | |
- modules = modules || {}; | |
- var exports = {}; | |
+var requireFake = function(id, path, force) { | |
+ // when a real require is ready, use it instead | |
+ if (require) | |
+ require(id); | |
+ // if the module has already been loaded, | |
+ // and this isn't a forced reload, | |
+ // return the memoized exports | |
+ if (modules[id] && !force) | |
+ return modules[id]; | |
+ | |
+ var exports = modules[id] = modules[id] || {}; | |
var module = {id: id, path: path}; | |
- var factory = system.evaluate(system.fs.read(path), path, 1); | |
+ | |
+ var factory = system.evaluate(file.read(path), path, 1); | |
factory( | |
- function(id) { return modules[id]; }, // require | |
+ requireFake, // require | |
exports, // exports | |
module, // module | |
system, // system | |
@@ -33,29 +44,16 @@ var requireFake = function(id, path, modules) { | |
return exports; | |
}; | |
-// bootstrap sandbox module | |
-var sandbox = requireFake( | |
- "sandbox", | |
- system.prefix + "/lib/sandbox.js", | |
- {"system": system} | |
-); | |
+// bootstrap sandbox and loader modules | |
+var loader = requireFake("loader", system.prefix + "/lib/loader.js"); | |
+var multiLoader = requireFake("loader/multi", system.prefix + "/lib/loader/multi.js"); | |
+var sandbox = requireFake("sandbox", system.prefix + "/lib/sandbox.js"); | |
// bootstrap file module | |
-var fs = {}; | |
-requireFake( | |
- "sandbox", | |
- system.prefix + "/lib/file-bootstrap.js", | |
- {"file" : fs, "system": system} | |
-); | |
-// override generic bootstrapping methods with those provided | |
-// by the engine bootstrap system.fs object | |
-for (var name in system.fs) { | |
- if (Object.prototype.hasOwnProperty.call(system.fs, name)) { | |
- fs[name] = system.fs[name]; | |
- } | |
-} | |
-system.fs = fs; | |
+requireFake("file", system.prefix + "/lib/file-bootstrap.js", "force"); | |
+ | |
system.enginePrefix = system.enginePrefix || system.prefix + '/engines/' + system.engines[0]; | |
+ | |
// construct the initial paths | |
var paths = []; | |
// XXX system.packagePrefixes deprecated in favor of system.prefixes | |
@@ -70,7 +68,7 @@ for (var i = 0; i < prefixes.length; i++) { | |
} | |
// create the primary Loader and Sandbox: | |
-var loader = sandbox.MultiLoader({ | |
+var loader = multiLoader.MultiLoader({ | |
paths: paths, | |
debug: system.verbose | |
}); | |
@@ -78,8 +76,7 @@ if (system.loaders) { | |
loader.loaders.unshift.apply(loader.loaders, system.loaders); | |
delete system.loaders; | |
} | |
-var modules = {system: system, sandbox: sandbox}; | |
-global.require = sandbox.Sandbox({ | |
+var require = global.require = sandbox.Sandbox({ | |
loader: loader, | |
modules: modules, | |
debug: system.verbose | |
@@ -90,11 +87,13 @@ global.require = sandbox.Sandbox({ | |
try { | |
require("global"); | |
} catch (e) { | |
- system.log.error("Couldn't load global/primordial patches ("+e+")"); | |
+ system.print("Couldn't load global/primordial patches ("+e+")"); | |
} | |
// load the complete system module | |
-global.require.force("system"); | |
+require.force("system"); | |
+require.force("file"); | |
+require.force("file-engine"); | |
// augment the path search array with those provided in | |
// environment variables | |
@@ -116,13 +115,24 @@ if (options.verbose !== undefined) { | |
require.verbose = system.verbose; | |
} | |
+if (system.fs) { | |
+ delete system.fs; | |
+ if (options.verbose) { | |
+ system.print( | |
+ "WARNING: this version of the " + system.engine + " engine \n" + | |
+ " is deprecated because it injects the system module \n" + | |
+ " instead of a modules memo in the narwhal bootstrap system." | |
+ ); | |
+ } | |
+} | |
+ | |
// enable loader tracing | |
global.require.debug = options.verbose; | |
// in verbose mode, list all the modules that are | |
// already loaded | |
if (!wasVerbose && system.verbose) { | |
Object.keys(modules).forEach(function (name) { | |
- print("| " + name); | |
+ system.print("| " + name); | |
}); | |
} | |
@@ -130,15 +140,15 @@ if (!wasVerbose && system.verbose) { | |
var program; | |
if (system.args.length && !options.interactive && !options.main) { | |
if (!program) | |
- program = system.fs.path(system.args[0]).canonical(); | |
+ program = file.path(system.args[0]).canonical(); | |
// add package prefixes for all of the packages | |
// containing the program, from specific to general | |
- var parts = system.fs.split(program); | |
+ var parts = file.split(program); | |
for (var i = 0; i < parts.length; i++) { | |
- var path = system.fs.join.apply(null, parts.slice(0, i)); | |
- var packageJson = system.fs.join(path, "package.json"); | |
- if (system.fs.isFile(packageJson)) | |
+ var path = file.join.apply(null, parts.slice(0, i)); | |
+ var packageJson = file.join(path, "package.json"); | |
+ if (file.isFile(packageJson)) | |
system.prefixes.unshift(path); | |
} | |
@@ -188,7 +198,7 @@ options.todo.forEach(function (item) { | |
if (paths.indexOf(path) < 0) | |
paths.push(path); | |
} | |
- print(paths.join(value)); | |
+ system.print(paths.join(value)); | |
} | |
}); | |
diff --git a/tests/all-tests.js b/tests/all-tests.js | |
index 5ec0df7..1ed7bdb 100644 | |
--- a/tests/all-tests.js | |
+++ b/tests/all-tests.js | |
@@ -12,6 +12,6 @@ exports.testGlobal = require("./global"); | |
exports.testCommonjs = require("./commonjs/all-tests"); | |
-if (require.main === module.id) | |
+if (require.main == module) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/args.js b/tests/args.js | |
index 83671ef..838e4c3 100644 | |
--- a/tests/args.js | |
+++ b/tests/args.js | |
@@ -26,6 +26,6 @@ exports.testOptions = require("./args/options"); | |
exports.testDomain = require("./args/domain"); | |
exports.testShifting = require("./args/shifting"); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/args/domain.js b/tests/args/domain.js | |
index d4abdb9..933a9a7 100644 | |
--- a/tests/args/domain.js | |
+++ b/tests/args/domain.js | |
@@ -210,6 +210,6 @@ exports.testNoActionForOptionError = function () { | |
}, args.ConfigurationError); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/args/options.js b/tests/args/options.js | |
index ff66c0d..7308818 100644 | |
--- a/tests/args/options.js | |
+++ b/tests/args/options.js | |
@@ -32,5 +32,5 @@ exports.testLongOptionSet = function () { | |
assert.eq(["args", "command", "option"], Object.keys(options)); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/args/shifting.js b/tests/args/shifting.js | |
index 346c3fd..e3b05e9 100644 | |
--- a/tests/args/shifting.js | |
+++ b/tests/args/shifting.js | |
@@ -87,6 +87,6 @@ exports.testNoSuchOption = function () { | |
}, test.Exit) | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/args/validation.js b/tests/args/validation.js | |
index bc4c2c2..8eb9645 100644 | |
--- a/tests/args/validation.js | |
+++ b/tests/args/validation.js | |
@@ -26,6 +26,6 @@ exports.testValidatorChain = function () { | |
}) | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/base64.js b/tests/base64.js | |
index 09bcd34..620eb86 100644 | |
--- a/tests/base64.js | |
+++ b/tests/base64.js | |
@@ -18,6 +18,6 @@ exports.testEncodeDecode = function () { | |
assert.eq(base64.decode(base64.encode(raw)), raw, 'encode decode identity'); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/all-tests.js b/tests/commonjs/all-tests.js | |
index ab1c2e9..150c973 100644 | |
--- a/tests/commonjs/all-tests.js | |
+++ b/tests/commonjs/all-tests.js | |
@@ -6,5 +6,5 @@ exports.testByteArrayEncodings = require("./bytearray-encodings-tests"); | |
exports.testByteStringEncodings = require("./bytestring-encodings-tests"); | |
exports.testFile = require("./file-tests"); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/bytearray-encodings-tests.js b/tests/commonjs/bytearray-encodings-tests.js | |
index 47fa50d..b91f80f 100644 | |
--- a/tests/commonjs/bytearray-encodings-tests.js | |
+++ b/tests/commonjs/bytearray-encodings-tests.js | |
@@ -65,5 +65,5 @@ exports.testDecodeToString = function() { | |
assert.isEqual("\u10ABCD", new ByteArray("\u10ABCD", "UTF-16").decodeToString("UTF-16")); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/bytearray-tests.js b/tests/commonjs/bytearray-tests.js | |
index 9bf76aa..61d7ca9 100644 | |
--- a/tests/commonjs/bytearray-tests.js | |
+++ b/tests/commonjs/bytearray-tests.js | |
@@ -320,5 +320,5 @@ exports.testByteArrayConcat = function() { | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/bytestring-encodings-tests.js b/tests/commonjs/bytestring-encodings-tests.js | |
index 9e871d4..b0f787f 100644 | |
--- a/tests/commonjs/bytestring-encodings-tests.js | |
+++ b/tests/commonjs/bytestring-encodings-tests.js | |
@@ -85,5 +85,5 @@ exports.testStringToByteString = function() { | |
assert.isEqual("I ♥ JS", "I ♥ JS".toByteString("UTF-8").decodeToString("UTF-8")); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/bytestring-tests.js b/tests/commonjs/bytestring-tests.js | |
index b62db2c..f03a8d4 100644 | |
--- a/tests/commonjs/bytestring-tests.js | |
+++ b/tests/commonjs/bytestring-tests.js | |
@@ -258,6 +258,6 @@ exports.testByteStringNewless = function () { | |
assert.isEqual(2, ByteString([0, 1], 0, 2).length); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file-tests.js b/tests/commonjs/file-tests.js | |
index f2bfcd8..a47f072 100644 | |
--- a/tests/commonjs/file-tests.js | |
+++ b/tests/commonjs/file-tests.js | |
@@ -279,6 +279,6 @@ exports.testNormal = require('./file/normal'); | |
exports.testDirname = require('./file/dirname'); | |
exports.testIsAbsolute = require('./file/is-absolute'); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/dirname.js b/tests/commonjs/file/dirname.js | |
index 2a075ce..3545f0d 100644 | |
--- a/tests/commonjs/file/dirname.js | |
+++ b/tests/commonjs/file/dirname.js | |
@@ -26,6 +26,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/extension.js b/tests/commonjs/file/extension.js | |
index 00e5959..1aa74d5 100644 | |
--- a/tests/commonjs/file/extension.js | |
+++ b/tests/commonjs/file/extension.js | |
@@ -40,6 +40,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/is-absolute.js b/tests/commonjs/file/is-absolute.js | |
index 89691eb..3dc93d7 100644 | |
--- a/tests/commonjs/file/is-absolute.js | |
+++ b/tests/commonjs/file/is-absolute.js | |
@@ -6,6 +6,6 @@ exports.testIsAbsolute = function () { | |
assert.eq(true, fs.isAbsolute(fs.absolute(module.path)), 'absolute module path is absolute'); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/iterator.js b/tests/commonjs/file/iterator.js | |
index 603bb51..e2c88b4 100644 | |
--- a/tests/commonjs/file/iterator.js | |
+++ b/tests/commonjs/file/iterator.js | |
@@ -96,6 +96,6 @@ exports.testIterator = Test(function (path) { | |
}); | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/normal.js b/tests/commonjs/file/normal.js | |
index 8314b1d..56a4dfc 100644 | |
--- a/tests/commonjs/file/normal.js | |
+++ b/tests/commonjs/file/normal.js | |
@@ -22,6 +22,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/relative.js b/tests/commonjs/file/relative.js | |
index c9102fc..6db5aba 100644 | |
--- a/tests/commonjs/file/relative.js | |
+++ b/tests/commonjs/file/relative.js | |
@@ -37,6 +37,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/commonjs/file/resolve.js b/tests/commonjs/file/resolve.js | |
index dbd33f0..c12e8ff 100644 | |
--- a/tests/commonjs/file/resolve.js | |
+++ b/tests/commonjs/file/resolve.js | |
@@ -40,5 +40,5 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/file/all-tests.js b/tests/file/all-tests.js | |
index 93bcf1f..cc7cd3a 100644 | |
--- a/tests/file/all-tests.js | |
+++ b/tests/file/all-tests.js | |
@@ -65,5 +65,5 @@ exports.testGlobStarStar = function () { | |
exports.testGlobDotDotDot = function () { | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/file/match.js b/tests/file/match.js | |
index a6d3822..a9b977f 100644 | |
--- a/tests/file/match.js | |
+++ b/tests/file/match.js | |
@@ -97,6 +97,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/global.js b/tests/global.js | |
index 56bbc55..597958b 100644 | |
--- a/tests/global.js | |
+++ b/tests/global.js | |
@@ -1,6 +1,6 @@ | |
exports.testArray = require("./global/array"); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/global/array.js b/tests/global/array.js | |
index 814d3b7..fce531a 100644 | |
--- a/tests/global/array.js | |
+++ b/tests/global/array.js | |
@@ -14,6 +14,6 @@ exports.testIsArrayNegativeObject = function () { | |
assert.isFalse(Array.isArray({"length": 0})); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/hashes.js b/tests/hashes.js | |
index fc64848..0039bb5 100644 | |
--- a/tests/hashes.js | |
+++ b/tests/hashes.js | |
@@ -89,6 +89,6 @@ util.forEachApply([ | |
exports['testConsistency' + name] = consistency(algorithm); | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/io/stringio.js b/tests/io/stringio.js | |
index fb71139..9490b30 100644 | |
--- a/tests/io/stringio.js | |
+++ b/tests/io/stringio.js | |
@@ -17,5 +17,5 @@ exports.testStringIODelimiterForEach = function () { | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/os/all-tests.js b/tests/os/all-tests.js | |
index f99df4b..890ad1c 100644 | |
--- a/tests/os/all-tests.js | |
+++ b/tests/os/all-tests.js | |
@@ -1,3 +1,3 @@ | |
exports.testPopen = require("./popen"); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/os/popen.js b/tests/os/popen.js | |
index 882d701..28b8312 100644 | |
--- a/tests/os/popen.js | |
+++ b/tests/os/popen.js | |
@@ -36,6 +36,6 @@ exports.testCommunicateStdin = function () { | |
assert.eq("", os.popen("exit 0").communicate("hi").stdin.read()); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
os.exit(require("test/runner").run(exports)); | |
diff --git a/tests/printf.js b/tests/printf.js | |
index 6bec048..d14cf02 100644 | |
--- a/tests/printf.js | |
+++ b/tests/printf.js | |
@@ -118,6 +118,6 @@ exports.testPrintfU = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/query-string.js b/tests/query-string.js | |
index 8ea8243..d3d178d 100644 | |
--- a/tests/query-string.js | |
+++ b/tests/query-string.js | |
@@ -70,6 +70,7 @@ exports.testParseQuery = function() { | |
assert.isSame(testCase[2], QueryString.parseQuery(testCase[1])); | |
}); | |
} | |
+ | |
/* | |
exports.testToQueryString = function () { | |
qsTestCases.forEach(function (testCase) { | |
@@ -83,5 +84,6 @@ exports.testToQueryString = function () { | |
}); | |
}; | |
*/ | |
-if (require.main === module.id) | |
+ | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/sandbox/reload.js b/tests/sandbox/reload.js | |
index e89ac2d..b847cbc 100644 | |
--- a/tests/sandbox/reload.js | |
+++ b/tests/sandbox/reload.js | |
@@ -74,6 +74,6 @@ exports.test = function () { | |
} | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/string.js b/tests/string.js | |
index 416dd63..24a54ea 100644 | |
--- a/tests/string.js | |
+++ b/tests/string.js | |
@@ -30,6 +30,6 @@ exports.testEnds = function() { | |
assert.isTrue("Hello".ends("Hello")); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/uri.js b/tests/uri.js | |
index 544988a..b7002c8 100644 | |
--- a/tests/uri.js | |
+++ b/tests/uri.js | |
@@ -36,6 +36,6 @@ util.forEachApply([ | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/all-tests.js b/tests/util/all-tests.js | |
index f66a3e2..2d7b0cd 100644 | |
--- a/tests/util/all-tests.js | |
+++ b/tests/util/all-tests.js | |
@@ -73,6 +73,6 @@ exports.testCompare = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/array.js b/tests/util/array.js | |
index 8aff5f7..59bb591 100644 | |
--- a/tests/util/array.js | |
+++ b/tests/util/array.js | |
@@ -202,6 +202,6 @@ exports.testSorted = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/array/is-arguments.js b/tests/util/array/is-arguments.js | |
index e1c9b65..bdf4a05 100644 | |
--- a/tests/util/array/is-arguments.js | |
+++ b/tests/util/array/is-arguments.js | |
@@ -24,6 +24,6 @@ exports.testNegativeDuckType = function () { | |
})); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/array/is-array-like.js b/tests/util/array/is-array-like.js | |
index 5d96fed..0c8b7be 100644 | |
--- a/tests/util/array/is-array-like.js | |
+++ b/tests/util/array/is-array-like.js | |
@@ -24,6 +24,6 @@ exports.testNegativeDuckType = function () { | |
})); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/case.js b/tests/util/case.js | |
index beaa506..28c6f89 100644 | |
--- a/tests/util/case.js | |
+++ b/tests/util/case.js | |
@@ -4,6 +4,6 @@ var util = require("util"); | |
/* upper, lower, camel, title, splitName, joinName */ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/collection.js b/tests/util/collection.js | |
index 2baf777..6ab29e4 100644 | |
--- a/tests/util/collection.js | |
+++ b/tests/util/collection.js | |
@@ -99,6 +99,6 @@ exports.testComplete = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/eq.js b/tests/util/eq.js | |
index 9c17aa0..15ec941 100644 | |
--- a/tests/util/eq.js | |
+++ b/tests/util/eq.js | |
@@ -52,6 +52,6 @@ exports.testCurry = function () { | |
assert.isFalse(util.eq(10)(20)); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/expand.js b/tests/util/expand.js | |
index f26f450..f7663e6 100644 | |
--- a/tests/util/expand.js | |
+++ b/tests/util/expand.js | |
@@ -40,6 +40,6 @@ util.forEach(inputs, function (input) { | |
}; | |
}); | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/object.js b/tests/util/object.js | |
index b626c96..1675b88 100644 | |
--- a/tests/util/object.js | |
+++ b/tests/util/object.js | |
@@ -121,5 +121,5 @@ exports.testRepr = function () { | |
assert.eq('{"a": 10}', util.repr({"a": 10})); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/repr.js b/tests/util/repr.js | |
index c9ec9a2..1006822 100644 | |
--- a/tests/util/repr.js | |
+++ b/tests/util/repr.js | |
@@ -21,6 +21,6 @@ exports.testType = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/string.js b/tests/util/string.js | |
index 0fc5c06..5cb4d56 100644 | |
--- a/tests/util/string.js | |
+++ b/tests/util/string.js | |
@@ -29,6 +29,6 @@ exports.testPadEnd = function () { | |
}; | |
*/ | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
diff --git a/tests/util/unique.js b/tests/util/unique.js | |
index 0ac0ef0..995f269 100644 | |
--- a/tests/util/unique.js | |
+++ b/tests/util/unique.js | |
@@ -7,6 +7,6 @@ exports.test = function () { | |
assert.eq(['toString', 'hasOwnProperty'], util.unique(['toString', 'hasOwnProperty'])); | |
}; | |
-if (require.main === module.id) | |
+if (require.main == module.id) | |
require("os").exit(require("test/runner").run(exports)); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment