浏览器测试设置:如何使已经全局的 SystemJS 模块可用于 require('systemjs') 测试代码?
Browser test setup: How to make already global SystemJS module available to require('systemjs') of tested code?
我的代码相当独立于系统,并且在 node.js 或浏览器上只有很少的系统相关代码行 运行s。我已经设法设置了基于 mocha 的测试,以便它可以在这两种环境中工作,使用相同的测试和相同的代码模块。我还管理浏览器测试环境以自动交换对那些总是调用浏览器版本的 node.js 版本的极少数系统依赖包的调用。
所以一切 运行s,包括 mocha 和 sinon 以及所有测试。
直到我决定不仅将 SystemJS 用于 运行 测试,而且还用于代码本身。
node.js 部分仍然有效,包括测试。当我 运行 浏览器测试时出现问题。
对于那些我使用 index.html 文件的 运行 测试,下面是完整的文件。
请注意,这与任何后来的生产浏览器环境无关,在这个早期阶段,我只想测试代码 (纯粹基于网络和存储,没有任何 GUI 的东西,在浏览器上使用 IndexedDB,在 node.js 和浏览器上使用 websockets) 我已经对浏览器使用了。
关键是线路 - 唯一的线路是新的,其他一切都已经工作了几个月
SystemJS.set('systemjs', SystemJS.newModule(SystemJS));
sinon
的一个类似方法已经运行了几个月,我希望我可以使用完全相同的方法使已经可用的 SystemJS
在模块使用 require('systemjs')
时可用。但是没用。
这是模块在 require
:
之后看到的
实际的 SystemJS 模块内容在 Symbol(): tt
.
下面
我确定答案非常简单,但是 SystemJS 的文档对我没有帮助,当然这很可能完全是我自己的错,但那是到底是怎么回事,我问了两个小时后没有结果。我也花了一些时间来完成当前的设置,包括必须阅读 SystemJS 源代码,我自己弄明白了这一切,但我认为这个微小且非常具体的问题对于 SO 问题来说可能是合理的?
只是为了完成设置的描述(对于那些好奇的人):我 运行 这一切都来自 WebStorm,目录设置是一个通常的 node.js 项目 ./test/
、./src/
、./lib/
,当然还有 ./node_modules/
。 html 文件是 ./test/index.html
,我告诉 WebStorm "run" 它,所以 WS 充当测试的网络服务器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Browser Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/v3.4.1/mocha.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/mochajs/mocha/v3.4.1/mocha.js"></script>
<script src="http://sinonjs.org/releases/sinon-2.2.0.js"></script>
<script src="../node_modules/systemjs/dist/system.js"></script>
<style>
#errors pre {
width: 50em;
margin: 2em 4em;
padding: 1em;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="errors"></div>
<div id="mocha"></div>
<script>
/*global SystemJS */
mocha.setup('bdd');
// This hack switches the system-dependent components so that require()
// statements for modules with node.js specific code are exchanged for their
// browser versions.
const resolveOrig = SystemJS.constructor.prototype.resolve;
SystemJS.constructor.prototype.resolve = function (key, parents) {
return resolveOrig.call(SystemJS, key.replace('-nodejs.js', '-browser.js'), parents);
};
// ======================================================
// RELEVANT SECTION (what I tried)
// THIS WORKS:
SystemJS.set('sinon', SystemJS.newModule(sinon));
// THIS DOES NOT WORK:
SystemJS.set('systemjs', SystemJS.newModule(SystemJS));
// ======================================================
// These are the test scripts in ./test/ that I want to run in the browser
const mochaTestScripts = [
// ... ABRIDGED LIST ....
'crypto-helpers',
'map-query',
'object-helpers',
'storage'
];
SystemJS.config({
map: {
'chai': '../node_modules/chai/chai.js',
'chai-as-promised': '../node_modules/chai-as-promised/lib/chai-as-promised.js',
// dependency of chai-as-promised
'check-error': '../node_modules/check-error/check-error.js',
'js-sha256': '../node_modules/js-sha256/build/sha256.min.js'
}
});
Promise.all(
mochaTestScripts.map(testScript =>
SystemJS.import('./' + testScript + '-test.js')
.catch(err => {
const div = document.getElementById('errors');
const pre = document.createElement('pre');
pre.appendChild(document.createTextNode('Test: ' + testScript + '\n\n' + err));
div.appendChild(pre);
})
)
)
.then(() => {
mocha.checkLeaks();
mocha.globals([]);
mocha.run();
})
.catch(err => {
const div = document.getElementById('errors');
const pre = document.createElement('pre');
pre.appendChild(document.createTextNode('GLOBAL ERROR\n' + err));
div.appendChild(pre);
});
</script>
</body>
</html>
我自己解决了:
我不得不去SystemJS的源代码中寻找答案。问题似乎是 SystemJS
符号不像通常那样只是一个普通对象,其中方法是直接在此对象内的属性。相反,SystemJS
是一个实例,方法在原型上。
最终起作用的是 SystemJS 在内部使用 newModule
的方式,最终起作用的命令是
SystemJS.registry.set(
'systemjs',
SystemJS.newModule({default: SystemJS, __useDefault: true})
);
这将替换上述 index.html
测试运行程序文件中 // THIS DOES NOT WORK:
下的行。
我的代码相当独立于系统,并且在 node.js 或浏览器上只有很少的系统相关代码行 运行s。我已经设法设置了基于 mocha 的测试,以便它可以在这两种环境中工作,使用相同的测试和相同的代码模块。我还管理浏览器测试环境以自动交换对那些总是调用浏览器版本的 node.js 版本的极少数系统依赖包的调用。
所以一切 运行s,包括 mocha 和 sinon 以及所有测试。
直到我决定不仅将 SystemJS 用于 运行 测试,而且还用于代码本身。
node.js 部分仍然有效,包括测试。当我 运行 浏览器测试时出现问题。
对于那些我使用 index.html 文件的 运行 测试,下面是完整的文件。
请注意,这与任何后来的生产浏览器环境无关,在这个早期阶段,我只想测试代码 (纯粹基于网络和存储,没有任何 GUI 的东西,在浏览器上使用 IndexedDB,在 node.js 和浏览器上使用 websockets) 我已经对浏览器使用了。
关键是线路 - 唯一的线路是新的,其他一切都已经工作了几个月
SystemJS.set('systemjs', SystemJS.newModule(SystemJS));
sinon
的一个类似方法已经运行了几个月,我希望我可以使用完全相同的方法使已经可用的 SystemJS
在模块使用 require('systemjs')
时可用。但是没用。
这是模块在 require
:
实际的 SystemJS 模块内容在 Symbol(): tt
.
我确定答案非常简单,但是 SystemJS 的文档对我没有帮助,当然这很可能完全是我自己的错,但那是到底是怎么回事,我问了两个小时后没有结果。我也花了一些时间来完成当前的设置,包括必须阅读 SystemJS 源代码,我自己弄明白了这一切,但我认为这个微小且非常具体的问题对于 SO 问题来说可能是合理的?
只是为了完成设置的描述(对于那些好奇的人):我 运行 这一切都来自 WebStorm,目录设置是一个通常的 node.js 项目 ./test/
、./src/
、./lib/
,当然还有 ./node_modules/
。 html 文件是 ./test/index.html
,我告诉 WebStorm "run" 它,所以 WS 充当测试的网络服务器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Browser Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/v3.4.1/mocha.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/mochajs/mocha/v3.4.1/mocha.js"></script>
<script src="http://sinonjs.org/releases/sinon-2.2.0.js"></script>
<script src="../node_modules/systemjs/dist/system.js"></script>
<style>
#errors pre {
width: 50em;
margin: 2em 4em;
padding: 1em;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="errors"></div>
<div id="mocha"></div>
<script>
/*global SystemJS */
mocha.setup('bdd');
// This hack switches the system-dependent components so that require()
// statements for modules with node.js specific code are exchanged for their
// browser versions.
const resolveOrig = SystemJS.constructor.prototype.resolve;
SystemJS.constructor.prototype.resolve = function (key, parents) {
return resolveOrig.call(SystemJS, key.replace('-nodejs.js', '-browser.js'), parents);
};
// ======================================================
// RELEVANT SECTION (what I tried)
// THIS WORKS:
SystemJS.set('sinon', SystemJS.newModule(sinon));
// THIS DOES NOT WORK:
SystemJS.set('systemjs', SystemJS.newModule(SystemJS));
// ======================================================
// These are the test scripts in ./test/ that I want to run in the browser
const mochaTestScripts = [
// ... ABRIDGED LIST ....
'crypto-helpers',
'map-query',
'object-helpers',
'storage'
];
SystemJS.config({
map: {
'chai': '../node_modules/chai/chai.js',
'chai-as-promised': '../node_modules/chai-as-promised/lib/chai-as-promised.js',
// dependency of chai-as-promised
'check-error': '../node_modules/check-error/check-error.js',
'js-sha256': '../node_modules/js-sha256/build/sha256.min.js'
}
});
Promise.all(
mochaTestScripts.map(testScript =>
SystemJS.import('./' + testScript + '-test.js')
.catch(err => {
const div = document.getElementById('errors');
const pre = document.createElement('pre');
pre.appendChild(document.createTextNode('Test: ' + testScript + '\n\n' + err));
div.appendChild(pre);
})
)
)
.then(() => {
mocha.checkLeaks();
mocha.globals([]);
mocha.run();
})
.catch(err => {
const div = document.getElementById('errors');
const pre = document.createElement('pre');
pre.appendChild(document.createTextNode('GLOBAL ERROR\n' + err));
div.appendChild(pre);
});
</script>
</body>
</html>
我自己解决了:
我不得不去SystemJS的源代码中寻找答案。问题似乎是 SystemJS
符号不像通常那样只是一个普通对象,其中方法是直接在此对象内的属性。相反,SystemJS
是一个实例,方法在原型上。
最终起作用的是 SystemJS 在内部使用 newModule
的方式,最终起作用的命令是
SystemJS.registry.set(
'systemjs',
SystemJS.newModule({default: SystemJS, __useDefault: true})
);
这将替换上述 index.html
测试运行程序文件中 // THIS DOES NOT WORK:
下的行。