mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2025-01-01 03:14:49 -05:00
Implemented default equality comparers for strings
This commit is contained in:
parent
c6214a811a
commit
ef099bc69f
2 changed files with 192 additions and 0 deletions
78
src/utils/comparison/string-equality-comparer.ts
Normal file
78
src/utils/comparison/string-equality-comparer.ts
Normal file
|
@ -0,0 +1,78 @@
|
|||
import { IS_LETTER_OR_DIGIT_REGEX } from "@/utils/string-utils";
|
||||
import { createDefaultEqualityComparer, createEqualityComparer } from "./equality-comparer";
|
||||
import { IGNORE_CASE_COMPARER } from "./string-comparer";
|
||||
|
||||
/**
|
||||
* A string comparer that performs a case-sensitive ordinal string comparison.
|
||||
*/
|
||||
export const ORDINAL_EQUALITY_COMPARER = createDefaultEqualityComparer<string>();
|
||||
|
||||
/**
|
||||
* A string comparer that ignores case differences.
|
||||
*/
|
||||
export const IGNORE_CASE_EQUALITY_COMPARER = IGNORE_CASE_COMPARER.asEqualityComparer();
|
||||
|
||||
/**
|
||||
* An equality comparer that compares two strings ignoring non-word characters (e.g. spaces, punctuation).
|
||||
*/
|
||||
export const IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER = createEqualityComparer<string>(
|
||||
(x, y) => compareStringsIgnoreNonWordCharacters(x, y, false)
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates an equality comparer that compares two strings ignoring non-word characters (e.g. spaces, punctuation) and case sensitivity.
|
||||
*/
|
||||
export const IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER = createEqualityComparer<string>(
|
||||
(x, y) => compareStringsIgnoreNonWordCharacters(x, y, true)
|
||||
);
|
||||
|
||||
/**
|
||||
* A comparer function that compares two strings ignoring non-word characters (e.g. spaces, punctuation).
|
||||
*
|
||||
* @param x - The first string to compare.
|
||||
* @param y - The second string to compare.
|
||||
* @param ignoreCase - A flag indicating whether to ignore case during comparison.
|
||||
*
|
||||
* @returns `true` if the two strings are equal; otherwise, `false`.
|
||||
*/
|
||||
function compareStringsIgnoreNonWordCharacters(x: string, y: string, ignoreCase?: boolean): boolean {
|
||||
if (x === null || x === undefined || y === null || y === undefined) {
|
||||
return x === y;
|
||||
}
|
||||
|
||||
const sensitivity = ignoreCase ? "accent" : "variant";
|
||||
|
||||
let xI = 0;
|
||||
let yI = 0;
|
||||
while (xI < x.length && yI < y.length) {
|
||||
let xChar = x.charAt(xI);
|
||||
let yChar = y.charAt(yI);
|
||||
if (xChar === yChar) {
|
||||
++xI;
|
||||
++yI;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (xI < x.length && !IS_LETTER_OR_DIGIT_REGEX.test(xChar)) {
|
||||
xChar = x.charAt(++xI);
|
||||
}
|
||||
while (yI < y.length && !IS_LETTER_OR_DIGIT_REGEX.test(yChar)) {
|
||||
yChar = y.charAt(++yI);
|
||||
}
|
||||
|
||||
if (xChar.localeCompare(yChar, undefined, { sensitivity }) !== 0) {
|
||||
return false;
|
||||
}
|
||||
++xI;
|
||||
++yI;
|
||||
}
|
||||
|
||||
while (xI < x.length && !IS_LETTER_OR_DIGIT_REGEX.test(x.charAt(xI))) {
|
||||
++xI;
|
||||
}
|
||||
while (yI < y.length && !IS_LETTER_OR_DIGIT_REGEX.test(y.charAt(yI))) {
|
||||
++yI;
|
||||
}
|
||||
|
||||
return xI >= x.length && yI >= y.length;
|
||||
}
|
114
tests/unit/utils/comparison/string-equality-comparer.spec.ts
Normal file
114
tests/unit/utils/comparison/string-equality-comparer.spec.ts
Normal file
|
@ -0,0 +1,114 @@
|
|||
import {
|
||||
ORDINAL_EQUALITY_COMPARER,
|
||||
IGNORE_CASE_EQUALITY_COMPARER,
|
||||
IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER,
|
||||
IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER,
|
||||
} from "@/utils/comparison/string-equality-comparer";
|
||||
|
||||
describe("ORDINAL_EQUALITY_COMPARER", () => {
|
||||
test("returns true for identical strings", () => {
|
||||
expect(ORDINAL_EQUALITY_COMPARER("Test", "Test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for different strings", () => {
|
||||
expect(ORDINAL_EQUALITY_COMPARER("Test", "Other")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns false for strings differing only by case", () => {
|
||||
expect(ORDINAL_EQUALITY_COMPARER("Test", "test")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns false when one string is null or undefined", () => {
|
||||
expect(ORDINAL_EQUALITY_COMPARER(null, "Test")).toBe(false);
|
||||
expect(ORDINAL_EQUALITY_COMPARER("Test", undefined)).toBe(false);
|
||||
expect(ORDINAL_EQUALITY_COMPARER(null, undefined)).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true when both strings are null, or both strings are undefined", () => {
|
||||
expect(ORDINAL_EQUALITY_COMPARER(null, null)).toBe(true);
|
||||
expect(ORDINAL_EQUALITY_COMPARER(undefined, undefined)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("IGNORE_CASE_EQUALITY_COMPARER", () => {
|
||||
test("returns true for identical strings", () => {
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER("Test", "Test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for different strings", () => {
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER("Test", "Other")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true for strings differing only by case", () => {
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER("Test", "test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false when one string is null or undefined", () => {
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER(null, "Test")).toBe(false);
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER("Test", undefined)).toBe(false);
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER(null, undefined)).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true when both strings are null, or both strings are undefined", () => {
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER(null, null)).toBe(true);
|
||||
expect(IGNORE_CASE_EQUALITY_COMPARER(undefined, undefined)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER", () => {
|
||||
test("returns true for identical strings", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "Test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for different strings", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "Other")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns false for strings differing only by case", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "test")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true for strings differing only be non-word characters", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "T.e_s-t")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false when one string is null or undefined", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, "Test")).toBe(false);
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", undefined)).toBe(false);
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, undefined)).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true when both strings are null, or both strings undefined", () => {
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, null)).toBe(true);
|
||||
expect(IGNORE_NON_WORD_CHARACTERS_EQUALITY_COMPARER(undefined, undefined)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER", () => {
|
||||
test("returns true for identical strings", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "Test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for different strings", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "Other")).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true for strings differing only by case", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "test")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns true for strings differing only by non-word characters and cases", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", "t.e_s-t")).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false when one string is null or undefined", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, "Test")).toBe(false);
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER("Test", undefined)).toBe(false);
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, undefined)).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true when both strings are null, or both strings are undefined", () => {
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER(null, null)).toBe(true);
|
||||
expect(IGNORE_CASE_AND_NON_WORD_CHARACTERS_EQUALITY_COMPARER(undefined, undefined)).toBe(true);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue