QUnit +咖啡脚本范围

发布于 2024-11-17 08:41:06 字数 1922 浏览 7 评论 0原文

在 Javascript 中,污染全局命名空间通常被认为是一件坏事。这就是为什么 Coffeescript 将所有 Javascript 包装在 (function() {}).call(this); 包装器中。

然而,我已经开始为我的 Coffeescript 代码编写 QUnit 测试,而 QUnit 抱怨它找不到我的函数。

1. Died on test #1: getGoodNamePart is not defined
getGoodNamePart is not defined at Object.<anonymous> (file:///Users/kevin/Documents/docs/code/chrome/tests.js:2:10) at Object.run 

我想在不污染全局命名空间的情况下测试变量。有什么好的方法可以做到这一点?

这是我想要测试的生成的 Javascript:

(function() {
getGoodNamePart = function(str) {
    if (str.charAt(0) === '"') {
      str.replace(/" <[^>]+>$"/g, "");
      str.replace(/"/g, "");
      return str;
    } else if (str.charAt(0) === '<') {
      str.replace(/<|>/g, "");
      return str;
    } else {
      return str;
    }
  };
}).call(this);

我的 test.js 文件是:

test('getGoodNamePart()', function() {
  equals(getGoodNamePart("\"Kev Burke\" <[email protected]>"), "Kev Burke", "\"name\" <email> works");
  equals(getGoodNamePart("", "", "empty string works"));
  equals(getGoodNamePart("[email protected]", "[email protected]", "raw email works"));
  return equals(getGoodNamePart("<[email protected]>", "[email protected]", "email inside carets -> carets get stripped"));
});

谢谢, 凯文

In Javascript polluting the global namespace is generally regarded as a bad thing. This is why Coffeescript wraps all of your Javascript in a (function() {}).call(this); wrapper.

However, I've begun writing QUnit tests for my Coffeescript code, and QUnit complains that it can't find my functions.

1. Died on test #1: getGoodNamePart is not defined
getGoodNamePart is not defined at Object.<anonymous> (file:///Users/kevin/Documents/docs/code/chrome/tests.js:2:10) at Object.run 

I'd like to test the variables without polluting the global namespace. What's a good way to do this?

Here's the generated Javascript I want to test:

(function() {
getGoodNamePart = function(str) {
    if (str.charAt(0) === '"') {
      str.replace(/" <[^>]+>$"/g, "");
      str.replace(/"/g, "");
      return str;
    } else if (str.charAt(0) === '<') {
      str.replace(/<|>/g, "");
      return str;
    } else {
      return str;
    }
  };
}).call(this);

and my test.js file is:

test('getGoodNamePart()', function() {
  equals(getGoodNamePart("\"Kev Burke\" <[email protected]>"), "Kev Burke", "\"name\" <email> works");
  equals(getGoodNamePart("", "", "empty string works"));
  equals(getGoodNamePart("[email protected]", "[email protected]", "raw email works"));
  return equals(getGoodNamePart("<[email protected]>", "[email protected]", "email inside carets -> carets get stripped"));
});

Thanks,
Kevin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三岁铭 2024-11-24 08:41:06

因此,您说您想在不污染全局命名空间的情况下测试 getGoodNamePart 。但是,CoffeeScript 会自动模块化每个文件(有充分的理由 - 请参阅我的回答 ),这意味着跨文件访问函数的唯一方法是将它们附加到某个全局对象。 (我假设我们在这里讨论的是浏览器,而不是 CommonJS 环境,例如 Node.js,您可以在其中使用 exports。)

为您提供了三个选项:

  1. 这 >getGoodNamePart 到窗口。这是最简单的,因为唯一需要的更改是在 getGoodNamePart 前面加上 window. (或只是 @),但这当然会最大化命名空间污染。
  2. getGoodNamePart 附加到已附加到 windowglobal 的其他内容。
  3. 将测试移到与 getGoodNamePart 相同的文件中(在 JS 世界中这是一种不寻常的做法,但值得考虑,因为它保持全局命名空间不变,并让您可以轻松地在代码和测试之间切换) 。

假设您想使用#2,导出诸如 getGoodNamePart 之类的函数纯粹用于测试。称它们为“测试目标”。在带有测试目标的每个文件的顶部,添加

window.testTargets ?= {}

并在定义 getGoodNamePart 时写入

testTargets.getGoodNamePart = getGoodNamePart = (str) ->
  ...

然后在 QUnit 测试套件的顶部写入

{getGoodNamePart} = testTargets

以获取该函数。

So, you say you want to test getGoodNamePart without polluting the global namespace. But, CoffeeScript automatically modularizes each file (with good reason—see my answer here), which means that the only way to access functions across files is to attach them to some global object. (I'm assuming that we're talking about the browser here, not a CommonJS environment, such as Node.js, where you'd use exports.)

That gives you three options:

  1. Attach getGoodNamePart to window. This is easiest, since the only change needed is prefixing getGoodNamePart with window. (or just @), but of course this maximizes namespace pollution.
  2. Attach getGoodNamePart to something else that's already attached to window or global.
  3. Move your tests inside of the same file as getGoodNamePart (an unusual practice in the JS world, but one worth considering, as it keeps the global namespace untouched and lets you easily go between your code and your tests).

Let's say that you want to go with #2, exporting functions like getGoodNamePart purely for testing. Call them "test targets." At the top of each file with a test target, add

window.testTargets ?= {}

and when you define getGoodNamePart, write

testTargets.getGoodNamePart = getGoodNamePart = (str) ->
  ...

Then at the top of your QUnit test suite, write

{getGoodNamePart} = testTargets

to get the function.

情深缘浅 2024-11-24 08:41:06

我使用 --bare 标志编译咖啡文件,用于测试目的

$ 咖啡 -c -b 你的文件

这不会模块化编译的代码

I compile the coffee file with the --bare flag, for testing purpose

$ coffee -c -b your_file

this doesn't modularize compiled code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文