2011-04-18 123 views
3

我搞亂QUnit,有一件事我偶然發現。爲什麼QUnit RegExp測試失敗?

我試着在Chrome這個簡單的測試:

deepEqual(new RegExp(), /(?:)/); 

我以爲它會通過,因爲new RegExp()回報/(?:)/在開發者控制檯。似乎不可能'只是'new RegExp() === /(?:)/RegExp s,但toString()函數返回相同和相等。

我認爲文字/非文字符號會有所作爲,但由於本次測試通過,可並非如此:

deepEqual(new RegExp(" "),//); 

所以,從下面的測試第一失敗:

test("test", function() { 
    deepEqual(new RegExp(), /(?:)/); // fail 
    deepEqual(new RegExp(" "),//); // pass 
    equal(new RegExp().toString(), /(?:)/.toString()); // pass 
}); 

因此,有人可以指出我正確的方向爲什麼第一次測試失敗嗎?

回答

3

簡短的回答:在source屬性的值是正則表達式字面/(?:)/和你new RegExp()獲取對象不同。在文字的情況下它是/(?:)/,而在對象的情況下,它是一個空字符串。當您執行/ /new RegExp(" ")時,source屬性的值是相同的(都是具有一個空格字符的字符串)。

龍回答:如果你看一下Qunit的源代碼,你會看到這段代碼:

"regexp": function (b, a) { 
    return QUnit.objectType(b) === "regexp" && 
     a.source === b.source && // the regex itself 
     a.global === b.global && // and its modifers (gmi) ... 
     a.ignoreCase === b.ignoreCase && 
     a.multiline === b.multiline; 
}; 

你可以看到源參數是如何使用該代碼的不同(它只是輸出特性每個正則表達式的參數,並將其測試平等)的:

function eq(x, y) { 
    console.log("x.source:", "'" + x.source + "'", "y.source:", "'" + y.source + "'", "===:", x.source === y.source); 
    console.log("x.global:", x.global, "y.global:", y.global, "===:", x.global === y.global); 
    console.log("x.ignoreCase:", x.ignoreCase, "y.ignoreCase:", y.ignoreCase, "===:", x.ignoreCase === y.ignoreCase); 
    console.log("x.multiline:", x.multiline, "y.multiline:", y.multiline, "===:", x.multiline === y.multiline); 
} 

當你調用此方法eq(/(?:)/, new RegExp());,您可以:

x.source: '(?:)' y.source: '' ===: false 
x.global: false y.global: false ===: true 
x.ignoreCase: false y.ignoreCase: false ===: true 
x.multiline: false y.multiline: false ===: true 

當你eq(/ /, new RegExp(" "));叫它鑑於你:

x.source: ' ' y.source: ' ' ===: true 
x.global: false y.global: false ===: true 
x.ignoreCase: false y.ignoreCase: false ===: true 
x.multiline: false y.multiline: false ===: true 
+0

感謝。你的解釋非常清楚。 – pimvdb 2011-04-18 20:32:27

+0

@pimvdb不客氣! :) – 2011-04-18 20:34:48