Почему этот тест QUnit RegExp не проходит? - PullRequest
3 голосов
/ 18 апреля 2011

Я возиться с QUnit, и я наткнулся на одну вещь.

Я попробовал этот простой тест на Chrome:

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

Я предполагал, что он пройдет, так как new RegExp() возвращает /(?:)/ в консоли разработчика.Кажется невозможным «просто» сделать new RegExp() === /(?:)/ для RegExp с, но функция toString() обоих возвращает одинаковое значение, а равны .

Я думал, что буквальное/ Нелитеральная запись будет иметь значение, но это не может иметь место, так как этот тест проходит:

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

Итак, из следующих тестов первый не пройден:

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

ПоэтомуМожет кто-нибудь указать мне правильное направление, почему первый тест не прошел, пожалуйста?

1 Ответ

3 голосов
/ 19 апреля 2011

Краткий ответ : Значение свойства 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
...