JS:如何测试正则表达式的转义函数

时间:2017-02-25 20:00:54

标签: javascript regex unit-testing mocha

我正在使用此转义函数进行正则表达式:

escapeRegExp = (str) => {
    return String(str).replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')
}

现在我想为这个函数编写一个简单的测试。所以我想出了这个:

it('escapes a regular expression string', () => {
    const   input = '/path/to/resource.html?search=query',
            result = '\\/path\\/to\\/resource\\.html\\?search\\=query'

    expect(escapeRegExp(input)).to.equal(result)
})

但是这不会涵盖函数中包含的所有转义选项。

如何才能获得更好的测试?

1 个答案:

答案 0 :(得分:0)

在不同的库中有很多这种方法的实现。

这是一个这样的库:https://github.com/ljharb/regexp.escape

如果你需要测试自己的,那么测试所有场景将需要相当多的测试 - 因为函数存在,人们必须已经为它编写了测试 - 例如原型有以下测试:

assert.equal('word', RegExp.escape('word'));
assert.equal('\\/slashes\\/', RegExp.escape('/slashes/'));
assert.equal('\\\\backslashes\\\\', RegExp.escape('\\backslashes\\'));
assert.equal('\\\\border of word', RegExp.escape('\\border of word'));

assert.equal('\\(\\?\\:non-capturing\\)', RegExp.escape('(?:non-capturing)'));
assert.equal('non-capturing', new RegExp(RegExp.escape('(?:') + '([^)]+)').exec('(?:non-capturing)')[1]);

assert.equal('\\(\\?\\=positive-lookahead\\)', RegExp.escape('(?=positive-lookahead)'));
assert.equal('positive-lookahead', new RegExp(RegExp.escape('(?=') + '([^)]+)').exec('(?=positive-lookahead)')[1]);

assert.equal('\\(\\?<\\=positive-lookbehind\\)', RegExp.escape('(?<=positive-lookbehind)'));
assert.equal('positive-lookbehind', new RegExp(RegExp.escape('(?<=') + '([^)]+)').exec('(?<=positive-lookbehind)')[1]);

assert.equal('\\(\\?\\!negative-lookahead\\)', RegExp.escape('(?!negative-lookahead)'));
assert.equal('negative-lookahead', new RegExp(RegExp.escape('(?!') + '([^)]+)').exec('(?!negative-lookahead)')[1]);

assert.equal('\\(\\?<\\!negative-lookbehind\\)', RegExp.escape('(?<!negative-lookbehind)'));
assert.equal('negative-lookbehind', new RegExp(RegExp.escape('(?<!') + '([^)]+)').exec('(?<!negative-lookbehind)')[1]);

assert.equal('\\[\\\\w\\]\\+', RegExp.escape('[\\w]+'));
assert.equal('character class', new RegExp(RegExp.escape('[') + '([^\\]]+)').exec('[character class]')[1]);

assert.equal('<div>', new RegExp(RegExp.escape('<div>')).exec('<td><div></td>')[0]);

assert.equal('false', RegExp.escape(false));
assert.equal('undefined', RegExp.escape());
assert.equal('null', RegExp.escape(null));
assert.equal('42', RegExp.escape(42));

assert.equal('\\\\n\\\\r\\\\t', RegExp.escape('\\n\\r\\t'));
assert.equal('\n\r\t', RegExp.escape('\n\r\t'));
assert.equal('\\{5,2\\}', RegExp.escape('{5,2}'));

assert.equal(
    '\\/\\(\\[\\.\\*\\+\\?\\^\\=\\!\\:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\\/\\\\\\\\\\]\\)\\/g',
    RegExp.escape('/([.*+?^=!:${}()|[\\]\\/\\\\])/g')
);h
  

https://github.com/sstephenson/prototype/blob/master/test/unit/tests/regexp.test.js

有一个ES7提案来标准化这种方法:https://github.com/benjamingr/RegExp.escape