【问题标题】:Browser test setup: How to make already global SystemJS module available to require('systemjs') of tested code?浏览器测试设置:如何使已经全局 SystemJS 模块可用于测试代码的 require('systemjs')?
【发布时间】:2017-05-15 15:51:31
【问题描述】:

我的代码完全独立于系统,并且在 node.js 或浏览器上运行的代码行很少。我已经设法设置了基于 mocha 的测试,以便它可以在这两种环境中工作,使用相同的测试和相同的代码模块。我还管理了浏览器测试环境,以自动交换那些极少数依赖于系统的包的调用,这些包总是将 node.js 版本调用为浏览器版本。

所以一切都运行了,包括 mocha 和 sinon 以及所有测试。

直到我决定使用 SystemJS 不仅用于运行测试,还用于代码本身。

node.js 部分仍然有效,包括测试。当我运行浏览器测试时出现问题。

对于那些我使用运行测试的 index.html 文件,下面是完整的。

请注意,这与任何以后的生产浏览器环境无关,在这个早期阶段,我只想测试代码(纯粹基于网络和存储,没有任何 GUI 东西,在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 “运行”它,因此 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>

【问题讨论】:

    标签: javascript systemjs


    【解决方案1】:

    我自己解决了:

    我不得不去 SystemJS 的源代码寻找答案。问题似乎在于SystemJS 符号不像通常那样只是一个普通对象,其中方法是直接位于该对象内部的属性。相反,SystemJS 是一个实例,方法在原型上。

    最终起作用的是 SystemJS 如何在内部使用newModule,而最终起作用的命令是

    SystemJS.registry.set(
        'systemjs',
        SystemJS.newModule({default: SystemJS, __useDefault: true})
    );
    

    这将替换上述index.html 测试运行器文件中// THIS DOES NOT WORK: 下的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-28
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 2016-08-28
      相关资源
      最近更新 更多