我正在编写一系列用于进行数学运算的coffeescript文件,我需要编写一些测试。我认为mocha和chai是要走的路。目前,我使用命名空间方法将所有单独的函数组合在一起,以保持整洁:
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我相信并导出命名空间函数,所以我不明白为什么没有定义命名空间。有什么想法吗?
答案 0 :(得分:1)
来自fine manual:
要导出对象,请添加到特殊的
exports
对象。
然后,exports
is returned by require
:
module.exports
是require
调用后实际返回的对象。
所以,当你这样说时:
namespace = require '../src/aname'
您的测试中有namespace.namespace
。
CoffeeScript将每个文件包装在function wrapper中,以避免污染全局命名空间:
所有CoffeeScript输出都包含在一个匿名函数中:
(function(){ ... })();
此安全包装器与var
关键字的自动生成相结合,使得非常难以意外地污染全局命名空间。
这意味着你在编译的JavaScript中有这样的东西:
(function() {
exports.namespace = ...
})();
(function() {
# Matrix4 definition which uses the 'namespace' function
})();
(function() {
var namespace = ...
})();
结果是namespace
在您定义Matrix4
的位置不可见,因为测试和Matrix4
存在于单独的函数中,因此存在单独的范围。
如果你想在数学文件中使用namespace
,那么你必须在那里require
而不是require
你的数学文件的代码。