2011-06-24 84 views
6

在JavaScript污染全局命名空間通常被認爲是一件壞事。這就是爲什麼Coffeescript將所有Javascript包裝在一個(function() {}).call(this);包裝中。QUnit + coffeescript範圍

但是,我已經開始爲我的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")); 
}); 

感謝, 凱文

+0

一些示例代碼將是有益的。 –

+0

嗨,亞倫,我加了一個例子。 –

回答

6

所以,你說你要測試getGoodNamePart而不污染全局名稱空間。但是,CoffeeScript會自動模塊化每個文件(有充分的理由參見my answer here),這意味着跨文件訪問函數的唯一方法是將它們附加到某個全局對象。 (我假設我們在這裏談論的瀏覽器,而不是一個CommonJS的環境,如Node.js的,在那裏你會使用exports。)

這就給了你三個選項:

  1. getGoodNamePartwindow。這是最簡單的,因爲所需要的唯一的變化是前綴getGoodNamePartwindow.(或只是@),但當然這最大化命名空間的污染。
  2. 附加getGoodNamePart到別的一個已經連接到windowglobal
  3. 將您的測試相同的文件getGoodNamePart內(在JS世界一個不尋常的做法,但一個值得考慮的,因爲它使全局命名空間不變,並讓您的代碼和測試之間輕鬆地去)。

比方說,你想要#2,出口像純粹用於測試的功能getGoodNamePart。稱他們爲「測試目標」。在同一個測試目標的每個文件的頂部,添加

window.testTargets ?= {} 

,當你定義getGoodNamePart,寫

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

然後在您的QUnit測試套件的頂部,寫

{getGoodNamePart} = testTargets 

獲取該功能。

+0

很好的答案,謝謝Trevor! –

2

我編譯與--bare標誌咖啡文件,用於測試目的

$ coffee -c -b your_file

這並不模塊化編譯代碼