import { QueryString, isQueryString, isURLSearchParams } from "@/utils/net/query-string"; describe("QueryString", () => { describe("constructor", () => { test("creates a new QueryString instance", () => { const queryString = new QueryString(); expect(queryString.size).toBe(0); }); test("creates a new QueryString instance from a query string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("creates a new QueryString instance from a query string that starts with '?'", () => { const params = "?key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("creates a new QueryString instance from an iterable", () => { const params = [["key1", "value1"], ["key2", "value2"]] as Iterable<[string, string]>; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("creates a new QueryString instance from a record", () => { const params = { key1: "value1", key2: "value2" }; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("filters out null and undefined parameters from an iterable", () => { const params = [["key1", "value1"], ["key2", null], ["key3", undefined]] as Iterable<[string, string]>; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.has("key2")).toBe(false); expect(queryString.has("key3")).toBe(false); }); test("filters out null and undefined parameters from a record", () => { const params = { key1: "value1", key2: null, key3: undefined }; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.has("key2")).toBe(false); expect(queryString.has("key3")).toBe(false); }); test("stringifies all values in an iterable", () => { const params = [["key1", "value1"], ["key2", 42], ["key3", true]] as Iterable<[string, unknown]>; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("42"); expect(queryString.get("key3")).toBe("true"); }); test("stringifies all values in a record", () => { const params = { key1: "value1", key2: 42, key3: true }; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("42"); expect(queryString.get("key3")).toBe("true"); }); }); describe("parse", () => { test("creates a new QueryString instance from a query string", () => { const params = "key1=value1&key2=value2"; const queryString = QueryString.parse(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("creates a new QueryString instance from a query string that starts with '?'", () => { const params = "?key1=value1&key2=value2"; const queryString = QueryString.parse(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); }); describe("size", () => { test("returns the number of key-value pairs in the query string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.size).toBe(2); }); test("returns 0 when the query string is empty", () => { const queryString = new QueryString(); expect(queryString.size).toBe(0); }); test("returns the correct size after adding a key-value pair", () => { const queryString = new QueryString(); queryString.append("key1", "value1"); expect(queryString.size).toBe(1); }); test("returns the correct size after removing a key-value pair", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); queryString.delete("key1"); expect(queryString.size).toBe(1); }); test("returns the correct size after clearing the query string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); queryString.clear(); expect(queryString.size).toBe(0); }); }); describe("get", () => { test("returns the value of the first key/value pair with the given key", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); test("returns undefined if there is no key/value pair with the given key", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.get("key3")).toBeUndefined(); }); test("returns undefined if the query string is empty", () => { const queryString = new QueryString(); expect(queryString.get("key1")).toBeUndefined(); }); }); describe("append", () => { test("appends a new key/value pair to the query string", () => { const queryString = new QueryString(); queryString.append("key1", "value1"); expect(queryString.get("key1")).toBe("value1"); }); test("appends multiple values to the same key", () => { const queryString = new QueryString(); queryString.append("key1", "value1"); queryString.append("key1", "value2"); expect(queryString.getAll("key1")).toEqual(["value1", "value2"]); }); }); describe("set", () => { test("sets a single value associated with the specified key, replacing any existing values", () => { const queryString = new QueryString("key1=value1"); queryString.set("key1", "newValue1"); expect(queryString.get("key1")).toBe("newValue1"); }); test("sets a single value associated with the specified key when no previous value exists", () => { const queryString = new QueryString(); queryString.set("key1", "value1"); expect(queryString.get("key1")).toBe("value1"); }); }); describe("delete", () => { test("removes the entry with the specified key from the query string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); const result = queryString.delete("key1"); expect(result).toBe(true); expect(queryString.get("key1")).toBeUndefined(); expect(queryString.get("key2")).toBe("value2"); }); test("returns false if no entry with the specified key was found", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); const result = queryString.delete("key3"); expect(result).toBe(false); expect(queryString.get("key1")).toBe("value1"); expect(queryString.get("key2")).toBe("value2"); }); }); describe("clear", () => { test("removes all key/value pairs from the query string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); queryString.clear(); expect(queryString.size).toBe(0); expect(queryString.has("key1")).toBe(false); expect(queryString.has("key2")).toBe(false); }); test("does nothing when the query string is already empty", () => { const queryString = new QueryString(); queryString.clear(); expect(queryString.size).toBe(0); }); }); describe("getString", () => { test("returns the value of the parameter as a string", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.getString("key1")).toBe("value1"); expect(queryString.getString("key2")).toBe("value2"); }); test("returns undefined if the parameter is not found", () => { const queryString = new QueryString(); expect(queryString.getString("key1")).toBeUndefined(); }); }); describe("getBoolean", () => { test("returns the value of the parameter as a boolean when the value is a boolean string", () => { const params = "key1=true&key2=false"; const queryString = new QueryString(params); expect(queryString.getBoolean("key1")).toBe(true); expect(queryString.getBoolean("key2")).toBe(false); }); test("returns undefined when the parameter is not found", () => { const queryString = new QueryString(); expect(queryString.getBoolean("key1")).toBeUndefined(); }); test("returns undefined when the value of the parameter cannot be converted to a boolean", () => { const params = "key1=value1"; const queryString = new QueryString(params); expect(queryString.getBoolean("key1")).toBeUndefined(); }); test("returns true when the value of the parameter is an empty string", () => { const params = "key1="; const queryString = new QueryString(params); expect(queryString.getBoolean("key1")).toBe(true); }); }); describe("getNumber", () => { test("returns the value of the parameter as a number", () => { const params = "key1=42"; const queryString = new QueryString(params); expect(queryString.getNumber("key1")).toBe(42); }); test("returns undefined if the parameter is not found", () => { const queryString = new QueryString(); expect(queryString.getNumber("key1")).toBeUndefined(); }); test("returns undefined if the parameter cannot be converted to a number", () => { const params = "key1=value1"; const queryString = new QueryString(params); expect(queryString.getNumber("key1")).toBeUndefined(); }); test("returns the value of the parameter as a number even if it's a float", () => { const params = "key1=42.42"; const queryString = new QueryString(params); expect(queryString.getNumber("key1")).toBe(42.42); }); }); describe("getDate", () => { test("returns the value of the parameter as a date", () => { const params = "date=2022-12-31"; const queryString = new QueryString(params); expect(queryString.getDate("date")).toEqual(new Date("2022-12-31")); }); test("returns undefined if the parameter is not found", () => { const queryString = new QueryString(); expect(queryString.getDate("date")).toBeUndefined(); }); test("returns undefined if the parameter cannot be converted to a date", () => { const params = "date=not-a-date"; const queryString = new QueryString(params); expect(queryString.getDate("date")).toBeUndefined(); }); }); describe("getRegExp", () => { test("returns the value of the parameter as a RegExp", () => { const params = "key1=/^value1$/g&key2=/^value2$/g"; const queryString = new QueryString(params); expect(queryString.getRegExp("key1")).toEqual(/^value1$/g); expect(queryString.getRegExp("key2")).toEqual(/^value2$/g); }); test("returns undefined if the parameter is not found", () => { const queryString = new QueryString(); expect(queryString.getRegExp("key1")).toBeUndefined(); }); test("returns undefined if the parameter cannot be converted to a RegExp", () => { const params = "key1=value1&key2=value2"; const queryString = new QueryString(params); expect(queryString.getRegExp("key1")).toBeUndefined(); expect(queryString.getRegExp("key2")).toBeUndefined(); }); }); describe("forEach", () => { test("calls the specified callback function for each element in the query string", () => { const params = "key1=value1&key2=value2"; const callback = jest.fn(); const queryString = new QueryString(params); queryString.forEach(callback); expect(callback).toHaveBeenCalledTimes(2); expect(callback).toHaveBeenNthCalledWith(1, "value1", "key1", queryString); expect(callback).toHaveBeenNthCalledWith(2, "value2", "key2", queryString); }); test("uses the provided thisArg as `this` when executing the callback function", () => { const params = "key1=value1"; const thisArg = {}; const callback = jest.fn(function(this: unknown) { expect(this).toBe(thisArg); }); const queryString = new QueryString(params); queryString.forEach(callback, thisArg); expect(callback).toHaveBeenCalledTimes(1); expect(callback).toHaveBeenNthCalledWith(1, "value1", "key1", queryString); }); test("does not call the callback function if the query string is empty", () => { const callback = jest.fn(); const queryString = new QueryString(); queryString.forEach(callback); expect(callback).not.toHaveBeenCalled(); }); }); describe("[Symbol.toStringTag]", () => { test("returns the same string tag as URLSearchParams", () => { const urlSearchParams = new URLSearchParams(); const queryString = new QueryString(); expect(queryString[Symbol.toStringTag]).toBe(urlSearchParams[Symbol.toStringTag]); }); }); }); describe("isURLSearchParams", () => { test("returns true when the object is an instance of URLSearchParams", () => { expect(isURLSearchParams(new URLSearchParams())).toBe(true); expect(isURLSearchParams(new QueryString())).toBe(true); }); test("returns false when the object is not an instance of URLSearchParams", () => { expect(isURLSearchParams({})).toBe(false); }); test("returns false when the object is null", () => { expect(isURLSearchParams(null)).toBe(false); }); test("returns false when the object is undefined", () => { expect(isURLSearchParams(undefined)).toBe(false); }); }); describe("isQueryString", () => { test("returns true when the object is an instance of QueryString", () => { expect(isQueryString(new QueryString())).toBe(true); }); test("returns false when the object is not an instance of QueryString", () => { expect(isQueryString(new URLSearchParams())).toBe(false); expect(isQueryString({})).toBe(false); }); test("returns false when the object is null", () => { expect(isQueryString(null)).toBe(false); }); test("returns false when the object is undefined", () => { expect(isQueryString(undefined)).toBe(false); }); });