0

我正在编写一系列用于进行数学运算的咖啡脚本文件,我需要编写一些测试。我认为摩卡和柴是要走的路。目前,我使用命名空间方法将所有单独的函数组合在一起以保持整洁:

namespace = (target, name, block) ->
  [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
  top    = target
  target = target[item] or= {} for item in name.split '.'
  block target, top

exports? exports.namespace = namespace

我现在想测试的是我的矩阵类,它看起来有点像这样:

namespace "CoffeeMath", (exports) ->

  class exports.Matrix4
    for name in ['add', 'subtract', 'multiply', 'divide', 'addScalar', 'subtractScalar', 'multiplyScalar', 'divideScalar', 'translate']
        do (name) ->
          Matrix4[name] = (a,b) ->
          a.copy()[name](b)

    Matrix4.DIM = 4

    # Take a list in column major format
    constructor: (@a=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]) ->
      # etc etc ...

现在用可爱的coffeescript编译器编译所有这些都很好。我有一个这样的测试:

chai = require 'chai'
chai.should()

{namespace} = require '../src/aname'
{Matrix4} = require '../src/math'

describe 'Matrix4 tests', ->
  m = null
  it 'should be the identity matrix', ->
    m  = new exports.Matrix4()
    m.a.should.equal '[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]'

问题是,我收到以下错误:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
ReferenceError: namespace is not defined
    at Object.<anonymous> (/Users/oni/Projects/Saito.js/src/math.coffee:3:3)
    at Object.<anonymous> (/Users/oni/Projects/Saito.js/src/math.coffee:631:4)
    at Module._compile (module.js:441:26)

我相信应该包含 aname 并且导出命名空间函数,所以我看不出为什么没有定义命名空间。有什么想法吗?

4

1 回答 1

1

来自精美手册

要导出对象,请添加到特殊exports对象。

然后,exports由返回require

module.exports是作为require调用结果实际返回的对象。

所以,当你这样说时:

namespace = require '../src/aname'

namespace.namespace在你的测试中有空。

CoffeeScript 将每个文件包装在一个函数包装器中,以避免污染全局命名空间:

所有 CoffeeScript 输出都包装在一个匿名函数中: (function(){ ... })();这个安全包装器与var关键字的自动生成相结合,使得意外污染全局命名空间变得极其困难。

这意味着你在编译的 JavaScript 中有这样的东西:

(function() {
    exports.namespace = ...
})();
(function() {
    # Matrix4 definition which uses the 'namespace' function
})();
(function() {
    var namespace = ...
})();

结果是自测试以来namespace在您定义的地方不可见,并且存在于单独的函数中,因此存在于单独的范围中。Matrix4Matrix4

如果你想namespace在你的数学文件中使用它,那么你必须在require那里而不是在require你的数学文件的代码中。

于 2012-05-12T17:16:30.243 回答