【问题标题】:Why does this QUnit RegExp test fail?为什么这个 QUnit RegExp 测试会失败?
【发布时间】:2011-04-18 18:41:05
【问题描述】:

我在搞乱 QUnit,我偶然发现了一件事。

我在 Chrome 上尝试了这个简单的测试:

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

我认为它会通过,因为 new RegExp() 在开发者控制台中返回 /(?:)/。似乎不可能为RegExps '仅仅' 做new RegExp() === /(?:)/,但两者的toString() 函数返回相同并且相等。

我认为文字/非文字符号会有所不同,但事实并非如此,因为此测试通过了:

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

因此,从以下测试来看,第一个失败:

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

因此,请有人指出我为什么第一次测试失败的正确方向吗?

【问题讨论】:

    标签: javascript regex unit-testing qunit


    【解决方案1】:

    简短回答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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      相关资源
      最近更新 更多