You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
4.5 KiB

/*
* Tests for CommonJS module environment bindings and scope behavior.
*
* A module environment is isolated from the global environment. Variable
* and function declarations do not pollute the global object (although
* plain assignments do). In the current implementation a module is wrapped
* inside a temporary function which provides the scope for the module.
*/
/*===
basic bindings
modSearch: foo/bar
modSearch: foo/quux
require: function false
module: object foo/quux false false false
exports: object true
===*/
/* Check 'require', 'exports', and 'module'. */
var global_require = require;
Duktape.modSearch = function (id) {
print('modSearch:', id);
if (id === 'foo/bar') {
return 'var mod = require("./quux");\n'
}
if (id === 'foo/quux') {
return 'var pd;\n' +
'print("require:", typeof require, require === global_require);\n' +
'pd = Object.getOwnPropertyDescriptor(module, "id");\n' +
'print("module:", typeof module, module.id, pd.writable, pd.enumerable, pd.configurable);\n' +
'print("exports:", typeof exports, exports === this);\n'
;
}
throw new Error('cannot find module');
};
print('basic bindings');
function bindingTest() {
var mod = require('foo/bar');
// module.id must be a resolved absolute path so that it can be used
// to require the correct module from any other module
}
try {
bindingTest();
} catch (e) {
print(e);
}
/*===
scoping
before global require
module: global-module
exports: global-exports
myVar1: global-myVar1
myVar2: global-myVar2
myVar3: global-myVar3
foo: global-foo
mod: object [object Object]
mod.name: test1
mod.foo: bar
after global require
module: global-module
exports: global-exports
myVar1: global-myVar1
myVar2: global-myVar2
myVar3: module-myVar3
foo: global-foo
before module require
module: global-module
exports: global-exports
myVar1: global-myVar1
myVar2: global-myVar2
myVar3: global-myVar3
foo: global-foo
mod: object [object Object]
mod.name: test2
mod.foo: bar
after module require
module: global-module
exports: global-exports
myVar1: global-myVar1
myVar2: global-myVar2
myVar3: module-myVar3
foo: global-foo
===*/
/* Assignment / scope tests. */
// These shouldn't get overwritten.
var module;
var exports;
var myVar1;
var myVar2;
var foo;
// This is ovwritten because module doesn't declare a variable
var myVar3;
// Temp
var mod;
function initVars() {
module = 'global-module';
exports = 'global-exports';
myVar1 = 'global-myVar1';
myVar2 = 'global-myVar2';
myVar3 = 'global-myVar3';
foo = 'global-foo';
}
function dumpVars() {
print('module:', module);
print('exports:', exports);
print('myVar1:', myVar1);
print('myVar2:', myVar2);
print('myVar3:', myVar3);
print('foo:', foo);
}
Duktape.modSearch = function (id) {
var ret;
if (id === 'test1' || id === 'test2') {
ret = 'var myVar1;\n' + // declared inside the module
'exports.name = "' + id + '";\n' + // goes into exports
'exports = "module-exports";\n' + // overwrites module exports, not global, does not affect exports.name getting exported
'this.foo = "bar";\n' + // 'this' is bound to the original exports table, so 'foo' gets exported
'require = "module-require";\n' + // overwrite module require, not global
'myVar1 = "module-myVar1";\n' + // writes to local variable, not global
'function myVar2() {}\n' + // declared inside module
'myVar3 = "module-myVar3";\n' // not declared locally, *set to global variable*
;
//print(ret);
return ret;
}
throw new Error('cannot find module: ' + id);
};
function moduleEnvironmentTest() {
var mod;
mod = require('test2');
print('mod:', typeof mod, mod);
print('mod.name:', mod.name);
print('mod.foo:', mod.foo);
print('after module require');
dumpVars();
}
print('scoping');
/* Using a require() from a global program. */
print('before global require');
initVars();
dumpVars();
try {
mod = require('test1');
} catch (e) {
print('global require failed:', e);
print(e.stack || e);
}
print('mod:', typeof mod, mod);
print('mod.name:', mod.name);
print('mod.foo:', mod.foo);
print('after global require');
dumpVars();
initVars();
print('before module require');
dumpVars();
try {
moduleEnvironmentTest();
} catch (e) {
print(e);
}