Commit 02f8adc1 02f8adc10bf0734a182707c7ad897bfbb01fadb1 by Nicolas Perriault

fixed #582 - allow requiring node modules

1 parent 21ef0aff
......@@ -136,7 +136,7 @@ CasperError.prototype = Object.getPrototypeOf(new Error());
fs.pathJoin = fs.joinPath;
} else if (!fs.hasOwnProperty('pathJoin')) {
fs.pathJoin = function pathJoin() {
return Array.prototype.join.call(arguments, this.separator);
return Array.prototype.join.call(arguments, '/');
};
}
return fs;
......@@ -185,31 +185,42 @@ CasperError.prototype = Object.getPrototypeOf(new Error());
if (require.patched) {
return require;
}
function resolveFile(path, dir) {
var extensions = ['js', 'coffee', 'json'];
var basenames = [path, path + '/index'];
var paths = [];
extensions.forEach(function(extension) {
basenames.forEach(function(basename) {
paths.push(fs.pathJoin(dir, [basename, extension].join('.')));
});
});
for (var i = 0; i < paths.length; i++) {
if (fs.isFile(paths[i])) {
return paths[i];
}
}
}
function getCurrentScriptRoot() {
if ((phantom.casperScriptBaseDir || "").indexOf(fs.workingDirectory) === 0) {
return phantom.casperScriptBaseDir;
}
return fs.absolute(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir));
}
function casperBuiltinPath(path) {
var absPath = fs.pathJoin(phantom.casperPath, 'modules', path + '.js');
return fs.isFile(absPath) ? absPath : undefined;
return resolveFile(path, fs.pathJoin(phantom.casperPath, 'modules'));
}
function nodeModulePath(path) {
return resolveFile(path, fs.pathJoin(getCurrentScriptRoot(), 'node_modules'));
}
function localModulePath(path) {
var baseDir = phantom.casperScriptBaseDir || fs.workingDirectory;
var paths = [
fs.absolute(fs.pathJoin(baseDir, path)),
fs.absolute(fs.pathJoin(baseDir, path + '.js'))
];
return paths.filter(function(path) {
return fs.isFile(path);
}).pop();
return resolveFile(path, phantom.casperScriptBaseDir || fs.workingDirectory);
}
var patchedRequire = function patchedRequire(path) {
var moduleFilePath = casperBuiltinPath(path);
if (moduleFilePath) {
return require(moduleFilePath);
}
moduleFilePath = localModulePath(path);
if (moduleFilePath) {
return require(moduleFilePath);
}
try {
return require(path);
return require(casperBuiltinPath(path) ||
nodeModulePath(path) ||
localModulePath(path) ||
path);
} catch (e) {
throw new CasperError("Can't find module " + path);
}
......@@ -225,11 +236,12 @@ CasperError.prototype = Object.getPrototypeOf(new Error());
* Initializes the CasperJS Command Line Interface.
*/
function initCasperCli(casperArgs) {
/* jshint maxcomplexity:99 */
var baseTestsPath = fs.pathJoin(phantom.casperPath, 'tests');
function setScriptBaseDir(scriptName) {
var dir = fs.dirname(scriptName);
if(dir === scriptName) {
if (dir === scriptName) {
dir = '.';
}
phantom.casperScriptBaseDir = dir;
......
var casper = require('casper').create();
var coffeemod = require('./sub/coffeemod');
console.log(coffeemod);
casper.exit();
var casper = require('casper').create();
var json = require('json');
console.log(json.universe);
casper.exit();
var casper = require('casper').create();
var foo = require('foo');
console.log(foo);
casper.exit();
var casper = require('casper').create();
var bar = require('bar');
console.log(bar);
casper.exit();
......@@ -10,9 +10,11 @@ TEST_ROOT = os.path.abspath(os.path.dirname(__file__))
CASPERJS_ROOT = os.path.abspath(os.path.join(TEST_ROOT, '..', '..'))
CASPER_EXEC = os.path.join(CASPERJS_ROOT, 'bin', 'casperjs')
class TimeoutException(Exception):
pass
def timeout(timeout_time):
def timeout_function(f):
def f2(*args):
......@@ -31,7 +33,8 @@ def timeout(timeout_time):
return f2
return timeout_function
class CasperExecTest(unittest.TestCase):
class CasperExecTestBase(unittest.TestCase):
def setUp(self):
with open(os.path.join(CASPERJS_ROOT, 'package.json')) as f:
self.pkg_version = json.load(f).get('version')
......@@ -46,9 +49,7 @@ class CasperExecTest(unittest.TestCase):
except subprocess.CalledProcessError as err:
if failing:
return err.output.decode('utf-8')
else:
raise IOError('Command %s exited with status %s'
% (cmd, err.errorcode))
raise IOError('Command %s exited: %s' % (cmd, err))
def assertCommandOutputEquals(self, cmd, result, **kwargs):
self.assertEqual(self.runCommand(cmd), result)
......@@ -62,6 +63,8 @@ class CasperExecTest(unittest.TestCase):
else:
self.assertIn(what, self.runCommand(cmd))
class BasicCommandsTest(CasperExecTestBase):
@timeout(20)
def test_version(self):
self.assertCommandOutputEquals('--version', self.pkg_version)
......@@ -70,16 +73,42 @@ class CasperExecTest(unittest.TestCase):
def test_help(self):
self.assertCommandOutputContains('--help', self.pkg_version)
class RequireTest(CasperExecTestBase):
@timeout(20)
def test_require(self):
def test_simple_require(self):
script_path = os.path.join(TEST_ROOT, 'modules', 'test.js')
self.assertCommandOutputEquals(script_path, 'hello, world')
@timeout(20)
def test_require_coffee(self):
script_path = os.path.join(TEST_ROOT, 'modules', 'test_coffee.js')
self.assertCommandOutputEquals(script_path, '42')
@timeout(20)
def test_node_module_require(self):
script_path = os.path.join(TEST_ROOT, 'modules', 'test_node_mod.js')
self.assertCommandOutputEquals(script_path, '42')
@timeout(20)
def test_node_module_require_index(self):
script_path = os.path.join(TEST_ROOT, 'modules', 'test_node_mod_index.js')
self.assertCommandOutputEquals(script_path, '42')
@timeout(20)
def test_node_module_require_json(self):
script_path = os.path.join(TEST_ROOT, 'modules', 'test_node_json.js')
self.assertCommandOutputEquals(script_path, '42')
class ScriptOutputTest(CasperExecTestBase):
@timeout(20)
def test_simple_script(self):
script_path = os.path.join(TEST_ROOT, 'scripts', 'script.js')
self.assertCommandOutputEquals(script_path, 'it works')
class ScriptErrorTest(CasperExecTestBase):
@timeout(20)
def test_syntax_error(self):
script_path = os.path.join(TEST_ROOT, 'error', 'syntax.js')
......@@ -94,6 +123,8 @@ class CasperExecTest(unittest.TestCase):
'SyntaxError: Parse error',
], failing=True)
class TestCommandOutputTest(CasperExecTestBase):
@timeout(20)
def test_simple_test_script(self):
script_path = os.path.join(TEST_ROOT, 'tester', 'mytest.js')
......@@ -225,5 +256,6 @@ class CasperExecTest(unittest.TestCase):
'this is my abort message',
], failing=True)
if __name__ == '__main__':
unittest.main()
......