You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.1 KiB
150 lines
4.1 KiB
import { describe, it, expect } from "vitest";
|
|
import { parseTextToArray } from "@/utils/arrayParser";
|
|
|
|
describe("parseTextToArray", () => {
|
|
it("splits by delimiter and trims/removes empty by default flags", () => {
|
|
const result = parseTextToArray(" one * two * * three ", {
|
|
splitMode: "delimiter",
|
|
delimiter: "*",
|
|
regexPattern: "",
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.error).toBeNull();
|
|
expect(result.items).toEqual(["one", "two", "three"]);
|
|
});
|
|
|
|
it("splits by newline", () => {
|
|
const result = parseTextToArray("a\nb\r\nc", {
|
|
splitMode: "newline",
|
|
delimiter: "*",
|
|
regexPattern: "",
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.items).toEqual(["a", "b", "c"]);
|
|
});
|
|
|
|
it("splits by regex pattern", () => {
|
|
const result = parseTextToArray("a1b2c3", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: "\\d",
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.error).toBeNull();
|
|
expect(result.items).toEqual(["a", "b", "c"]);
|
|
});
|
|
|
|
it("returns a single item when delimiter is empty", () => {
|
|
const result = parseTextToArray("keep as one", {
|
|
splitMode: "delimiter",
|
|
delimiter: "",
|
|
regexPattern: "",
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.items).toEqual(["keep as one"]);
|
|
});
|
|
|
|
it("returns error for invalid regex", () => {
|
|
const result = parseTextToArray("a,b,c", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: "(",
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.items).toEqual([]);
|
|
expect(result.error).toBeTruthy();
|
|
});
|
|
|
|
it("rejects nested quantifier patterns (ReDoS)", () => {
|
|
const dangerousPatterns = ["(a+)+", "(a*)*", "(a+)*", "/(a+)+/g", "(x*)+"];
|
|
for (const pattern of dangerousPatterns) {
|
|
const result = parseTextToArray("test", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: pattern,
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
expect(result.items).toEqual([]);
|
|
expect(result.error).toContain("nested quantifiers");
|
|
}
|
|
});
|
|
|
|
it("rejects deeply nested quantifier patterns that bypass simple regex checks", () => {
|
|
const deeplyNestedPatterns = ["((a+))+", "((a*)+)", "(((x+))+)+"];
|
|
for (const pattern of deeplyNestedPatterns) {
|
|
const result = parseTextToArray("test", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: pattern,
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
expect(result.items).toEqual([]);
|
|
expect(result.error).toContain("nested quantifiers");
|
|
}
|
|
});
|
|
|
|
it("allows safe regex patterns", () => {
|
|
const safePatterns = ["\\d+", "[,;]+", "\\s+", "(a|b)"];
|
|
for (const pattern of safePatterns) {
|
|
const result = parseTextToArray("a1b2c", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: pattern,
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
expect(result.error).toBeNull();
|
|
expect(result.items.length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it("rejects input exceeding max length in regex mode", () => {
|
|
const longInput = "a".repeat(100_001);
|
|
const result = parseTextToArray(longInput, {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: "\\d",
|
|
trimItems: false,
|
|
removeEmpty: false,
|
|
});
|
|
expect(result.items).toEqual([]);
|
|
expect(result.error).toContain("Input too long");
|
|
});
|
|
|
|
it("allows input at max length in regex mode", () => {
|
|
const input = "a".repeat(100_000);
|
|
const result = parseTextToArray(input, {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: "\\d",
|
|
trimItems: false,
|
|
removeEmpty: false,
|
|
});
|
|
expect(result.error).toBeNull();
|
|
});
|
|
|
|
it("returns error when regex pattern is too long", () => {
|
|
const result = parseTextToArray("a,b,c", {
|
|
splitMode: "regex",
|
|
delimiter: "*",
|
|
regexPattern: "a".repeat(101),
|
|
trimItems: true,
|
|
removeEmpty: true,
|
|
});
|
|
|
|
expect(result.items).toEqual([]);
|
|
expect(result.error).toContain("Regex pattern too long");
|
|
});
|
|
});
|
|
|