Skip to content

Commit

Permalink
feat: improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
zr87 committed Aug 21, 2024
1 parent b7dd541 commit ec8541f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 18 deletions.
48 changes: 32 additions & 16 deletions src/accentFolding.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,47 @@ class AccentFolding {
}

replace(text) {
if (typeof text !== 'string') {
throw new TypeError('Input must be a string');
}
return [...text].map((char) => this.#accentMap.get(char) || char).join('');
}

highlightMatch(str, fragment, wrapTag = 'b') {
if (!fragment) return str;
try {
if (!fragment) return str;

const escapedFragment = fragment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const strFolded = this.#fold(str).toLowerCase();
const fragmentFolded = this.#fold(escapedFragment).toLowerCase();
if (typeof str !== 'string' || typeof fragment !== 'string') {
throw new TypeError('Both str and fragment must be strings');
}

const re = new RegExp(fragmentFolded, 'g');
let result = '';
let lastIndex = 0;
let hasMatch = false;
if (typeof wrapTag !== 'string') {
throw new TypeError('wrapTag must be a string');
}

strFolded.replace(re, (match, index) => {
hasMatch = true;
result += this.#escapeHtml(str.slice(lastIndex, index));
result += `<${wrapTag}>${this.#escapeHtml(str.slice(index, index + match.length))}</${wrapTag}>`;
lastIndex = index + match.length;
});
const escapedFragment = fragment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const strFolded = this.#fold(str).toLowerCase();
const fragmentFolded = this.#fold(escapedFragment).toLowerCase();

result += this.#escapeHtml(str.slice(lastIndex));
const re = new RegExp(fragmentFolded, 'g');
let result = '';
let lastIndex = 0;
let hasMatch = false;

return hasMatch ? result : str;
strFolded.replace(re, (match, index) => {
hasMatch = true;
result += this.#escapeHtml(str.slice(lastIndex, index));
result += `<${wrapTag}>${this.#escapeHtml(str.slice(index, index + match.length))}</${wrapTag}>`;
lastIndex = index + match.length;
});

result += this.#escapeHtml(str.slice(lastIndex));

return hasMatch ? result : str;
} catch (error) {
console.error('Error in highlightMatch:', error.message);
throw error; // Return original string if there's an error
}
}

#escapeHtml(unsafe) {
Expand Down
36 changes: 34 additions & 2 deletions src/accentFolding.js.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
import { expect, describe, it } from 'vitest';
import { expect, describe, it, beforeEach } from 'vitest';
import AccentFolding from './accentFolding.js';
import accentMap from './accentMap.json';

describe('AccentFolding', () => {
const accentFolder = new AccentFolding();
let accentFolder;

beforeEach(() => {
accentFolder = new AccentFolding();
});

describe('highlightMatch', () => {
it('should throw TypeError if str is not a string', () => {
expect(() => accentFolder.highlightMatch(123, 'test')).toThrow(TypeError);
expect(() => accentFolder.highlightMatch(123, 'test')).toThrow(
'Both str and fragment must be strings'
);
});

it('should throw TypeError if fragment is not a string', () => {
expect(() => accentFolder.highlightMatch('test', 123)).toThrow(TypeError);
expect(() => accentFolder.highlightMatch('test', 123)).toThrow(
'Both str and fragment must be strings'
);
});

it('should throw TypeError if wrapTag is not a string', () => {
expect(() => accentFolder.highlightMatch('test', 'es', 123)).toThrow(
TypeError
);
expect(() => accentFolder.highlightMatch('test', 'es', 123)).toThrow(
'wrapTag must be a string'
);
});

it('should recognize simple accents', () => {
expect(accentFolder.highlightMatch('Fulanilo López', 'lo')).toBe(
'Fulani<b>lo</b> <b>Ló</b>pez'
Expand Down Expand Up @@ -63,6 +90,11 @@ describe('AccentFolding', () => {
});

describe('replace', () => {
it('should throw TypeError if input is not a string', () => {
expect(() => accentFolder.replace(123)).toThrow(TypeError);
expect(() => accentFolder.replace(123)).toThrow('Input must be a string');
});

it.each(Object.entries(accentMap))(
'should replace %s with %s',
(accentedChar, expectedChar) => {
Expand Down

0 comments on commit ec8541f

Please sign in to comment.