From 9bc8c4b47fd036eadba820848246be41d5ee7eb9 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 30 Jun 2026 08:49:54 -0400 Subject: [PATCH] test: add suite for utils/regex (sanitizeForRegex, URL/EMAIL/JUMBO_EMOJI) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second pure-logic suite — another zero-import module. 4 tests covering regex metacharacter escaping (with round-trip), the http(s) URL pattern, email validation, and the jumbo-emoji matcher. Total suite now 19 tests. Co-Authored-By: Claude Opus 4.8 --- src/app/utils/regex.test.ts | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/app/utils/regex.test.ts diff --git a/src/app/utils/regex.test.ts b/src/app/utils/regex.test.ts new file mode 100644 index 000000000..98677fea4 --- /dev/null +++ b/src/app/utils/regex.test.ts @@ -0,0 +1,39 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { sanitizeForRegex, HTTP_URL_PATTERN, URL_REG, EMAIL_REGEX, JUMBO_EMOJI_REG } from './regex'; + +test('sanitizeForRegex escapes regex metacharacters', () => { + assert.equal(sanitizeForRegex('a.b'), 'a\\.b'); + assert.equal(sanitizeForRegex('a+b'), 'a\\+b'); + assert.equal(sanitizeForRegex('(grp)'), '\\(grp\\)'); + // hyphen is escaped as a hex code (safe inside character classes) + assert.equal(sanitizeForRegex('a-b'), 'a\\x2db'); + // round-trip: the escaped form matches the literal, not as a metacharacter + assert.equal(new RegExp(`^${sanitizeForRegex('a.b')}$`).test('a.b'), true); + assert.equal(new RegExp(`^${sanitizeForRegex('a.b')}$`).test('axb'), false); +}); + +test('URL pattern matches http(s) urls', () => { + const urlRe = new RegExp(HTTP_URL_PATTERN); // fresh, non-global for stateless .test + assert.equal(urlRe.test('https://example.com'), true); + assert.equal(urlRe.test('http://www.foo.com/path?q=1'), true); + assert.equal(urlRe.test('just some text'), false); + assert.ok(URL_REG instanceof RegExp); + assert.equal(URL_REG.global, true); // used with matchAll elsewhere +}); + +test('EMAIL_REGEX', () => { + assert.equal(EMAIL_REGEX.test('a@b.com'), true); + assert.equal(EMAIL_REGEX.test('john.doe@example.co'), true); + assert.equal(EMAIL_REGEX.test('nope'), false); + assert.equal(EMAIL_REGEX.test('a@b'), false); // no TLD + assert.equal(EMAIL_REGEX.test('@b.com'), false); // empty local part +}); + +test('JUMBO_EMOJI_REG matches 1-10 emoji / custom emoji only', () => { + assert.equal(JUMBO_EMOJI_REG.test('😀'), true); + assert.equal(JUMBO_EMOJI_REG.test('😀😀😀'), true); + assert.equal(JUMBO_EMOJI_REG.test(':custom_emoji:'), true); + assert.equal(JUMBO_EMOJI_REG.test('hello'), false); + assert.equal(JUMBO_EMOJI_REG.test('hi 😀'), false); // leading text disqualifies +});