UNPKG

regexgen

Version:

Generate regular expressions that match a set of strings

139 lines (112 loc) 5.03 kB
const assert = require('assert'); const regexgen = require('../'); describe('regexgen', function () { it('should generate a char class', function () { assert.deepEqual(regexgen(['a', 'b', 'c']), /[a-c]/); }); it('should generate an alternation', function () { assert.deepEqual(regexgen(['abc', '123']), /123|abc/); }); it('should extract common prefixes at the start', function () { assert.deepEqual(regexgen(['foobar', 'foozap']), /foo(?:zap|bar)/); }); it('should extract common prefixes at the end', function () { assert.deepEqual(regexgen(['barfoo', 'zapfoo']), /(?:zap|bar)foo/); }); it('should extract common prefixes at the start and end', function () { assert.deepEqual(regexgen(['foobarfoo', 'foozapfoo']), /foo(?:zap|bar)foo/); }); it('should generate an optional group', function () { assert.deepEqual(regexgen(['foo', 'foobar']), /foo(?:bar)?/); }); it('should generate multiple optional groups', function () { assert.deepEqual(regexgen(['f', 'fo', 'fox']), /f(?:ox?)?/); }); it('should escape meta characters', function () { assert.deepEqual(regexgen(['foo|bar[test]+']), /foo\|bar\[test\]\+/); assert.deepEqual(regexgen(['u{}\\iu']), /u\{\}\\iu/); }); it('should escape non-ascii characters', function () { assert.deepEqual(regexgen(['🎉']), /\uD83C\uDF89/); }); it('should support regex flags', function () { assert.deepEqual(regexgen(['a', 'b', 'c'], 'g'), /[a-c]/g); }); it('should support using the Trie class directly', function () { let t = new regexgen.Trie; t.add('foobar'); t.add('foobaz'); assert.deepEqual(t.toString(), 'fooba[rz]'); assert.deepEqual(t.toRegExp(), /fooba[rz]/); let t2 = new regexgen.Trie; t2.addAll(['foobar', 'foobaz']); assert.deepEqual(t2.toString(), 'fooba[rz]'); assert.deepEqual(t2.toRegExp(), /fooba[rz]/); }); it('should work with optional groups', function () { assert.deepEqual(regexgen(['a', 'abc']), /a(?:bc)?/); }); it('should wrap optional character classes in parens if they contain non-BMP codepoints', function () { assert.deepEqual(regexgen(['\u261D', '\u261D\u{1f3fb}', '\u261D\u{1f3fc}']), /\u261D(?:\uD83C[\uDFFB\uDFFC])?/); }); it('should wrap optional literals in parens if they contain more than one code unit', function () { assert.deepEqual(regexgen(['\u261D', '\u261D\u{1f3fb}']), /\u261D(?:\uD83C\uDFFB)?/); }); it('should retain non-BMP codepoints when the Unicode flag is passed', function () { assert.deepEqual(regexgen(['\u261D', '\u261D\u{1f3fb}'], 'u'), /\u261D\u{1F3FB}?/u); assert.deepEqual( regexgen(['\u{1F3F4}', '\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}', '\u{1F3F4}\u{E0067}\u{E0062}\u{E0077}\u{E006C}\u{E0073}', '\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}'], 'u'), /\u{1F3F4}(?:\u{E0067}\u{E0062}(?:\u{E0073}\u{E0063}\u{E0074}|\u{E0077}\u{E006C}\u{E0073}|\u{E0065}\u{E006E}\u{E0067}))?/u ); }); it('should handle non-BMP codepoint ranges correctly', function() { assert.deepEqual( regexgen(['\u{1F311}', '\u{1F312}', '\u{1F313}', '\u{1F314}', '\u{1F315}', '\u{1F316}', '\u{1F317}', '\u{1F318}'], 'u'), /[\u{1F311}-\u{1F318}]/u ); }); it('should correctly extract common prefix from multiple alternations', function () { assert.deepEqual(regexgen(['abjv', 'abxcjv', 'abydjv', 'abzejv']), /ab(?:ze|yd|xc)?jv/); }); it('should sort alternation options correctly (#10)', function () { let s = '\uD83C\uDFCA\uD83C\uDFFD\u200D\u2640\uFE0F'; let r = regexgen([ '\uD83C\uDDF7\uD83C\uDDFC', '\uD83C\uDDF8\uD83C\uDDE6', '\uD83C\uDFCA\uD83C\uDFFD', s ]); assert.deepEqual(s.match(r)[0], s); }); it('should sort non-BMP alternation options correctly', function () { let r = regexgen( [ // shrug emoji '\u{1F937}\u200D', // shrug emoji with fitzpatrick modifiers '\u{1F937}\u{1F3FB}\u200D', '\u{1F937}\u{1F3FC}\u200D', '\u{1F937}\u{1F3FD}\u200D', '\u{1F937}\u{1F3FE}\u200D', '\u{1F937}\u{1F3FF}\u200D', // shrug emoji with gender modifier '\u{1F937}\u200D\u2640\uFE0F', // shrug emoji with gender and fitzpatrick modifiers '\u{1F937}\u{1F3FB}\u200D\u2640\uFE0F', '\u{1F937}\u{1F3FC}\u200D\u2640\uFE0F', '\u{1F937}\u{1F3FD}\u200D\u2640\uFE0F', '\u{1F937}\u{1F3FE}\u200D\u2640\uFE0F', '\u{1F937}\u{1F3FF}\u200D\u2640\uFE0F' ], 'u' ); assert.deepEqual(r, /\u{1F937}[\u{1F3FB}-\u{1F3FF}]?\u200D(?:\u2640\uFE0F)?/u); assert.deepEqual('\u{1F937}\u{1F3FB}\u200D\u2640\uFE0F'.match(r)[0], '\u{1F937}\u{1F3FB}\u200D\u2640\uFE0F'); }); it('should sort alternations of alternations correctly', function () { let r = regexgen(['aef', 'aghz', 'ayz', 'abcdz', 'abcd']); let s = 'abcdz'; assert.deepEqual(s.match(r)[0], s); assert.deepEqual(r, /a(?:(?:bcd|gh|y)z|bcd|ef)/); }); });