From 94525fce5299f3417801f0152a475892e1edac30 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Wed, 7 May 2025 12:28:51 +0200 Subject: [PATCH] test(utils): add unit tests for parseQuery function - Introduce comprehensive tests for the parseQuery utility. - Validate handling of single and multi-value query parameters. - Ensure empty query strings return an empty object. - Confirm repeated keys are grouped into arrays. Signed-off-by: Max P. --- src/Utils/__tests__/parseQuery.test.ts | 49 ++++++++++++++++++++++++++ src/Utils/parseQuery.ts | 30 ++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/Utils/__tests__/parseQuery.test.ts create mode 100644 src/Utils/parseQuery.ts diff --git a/src/Utils/__tests__/parseQuery.test.ts b/src/Utils/__tests__/parseQuery.test.ts new file mode 100644 index 0000000..9c4924e --- /dev/null +++ b/src/Utils/__tests__/parseQuery.test.ts @@ -0,0 +1,49 @@ +import { assertEquals } from 'https://deno.land/std/assert/mod.ts'; +import { parseQuery } from '../parseQuery.ts'; + +Deno.test('parseQuery: single-value parameters are parsed as strings', () => { + const url = new URL('http://localhost?foo=bar&limit=10'); + const result = parseQuery(url.searchParams); + + assertEquals(result, { + foo: 'bar', + limit: '10', + }); +}); + +Deno.test('parseQuery: multi-value parameters are parsed as string arrays', () => { + const url = new URL('http://localhost?tag=ts&tag=deno&tag=web'); + const result = parseQuery(url.searchParams); + + assertEquals(result, { + tag: ['ts', 'deno', 'web'], + }); +}); + +Deno.test('parseQuery: mixed single and multi-value parameters', () => { + const url = new URL( + 'http://localhost?sort=asc&filter=active&filter=pending', + ); + const result = parseQuery(url.searchParams); + + assertEquals(result, { + sort: 'asc', + filter: ['active', 'pending'], + }); +}); + +Deno.test('parseQuery: empty query string returns empty object', () => { + const url = new URL('http://localhost'); + const result = parseQuery(url.searchParams); + + assertEquals(result, {}); +}); + +Deno.test('parseQuery: repeated single-value keys are grouped', () => { + const url = new URL('http://localhost?a=1&a=2&a=3'); + const result = parseQuery(url.searchParams); + + assertEquals(result, { + a: ['1', '2', '3'], + }); +}); diff --git a/src/Utils/parseQuery.ts b/src/Utils/parseQuery.ts new file mode 100644 index 0000000..5125f52 --- /dev/null +++ b/src/Utils/parseQuery.ts @@ -0,0 +1,30 @@ +import { Query } from '../Types/Query.ts'; + +/** + * Parses a `URLSearchParams` object into an `IQuery` structure + * that preserves both single and multi-value semantics. + * + * For each query parameter key, this function checks how often the key appears: + * - If the key occurs once, the value is stored as a string. + * - If the key occurs multiple times, the values are stored as a string array. + * + * This ensures compatibility with the `IQuery` type definition, + * which allows both `string` and `string[]` as value types. + * + * Example: + * - ?tag=deno&tag=ts → { tag: ["deno", "ts"] } + * - ?page=2 → { page: "2" } + * + * @param searchParams - The `URLSearchParams` instance from a parsed URL. + * @returns An object conforming to `IQuery`, with normalized parameter values. + */ +export function parseQuery(searchParams: URLSearchParams): Query { + const query: Query = {}; + + for (const key of new Set(searchParams.keys())) { + const values = searchParams.getAll(key); + query[key] = values.length > 1 ? values : values[0]; + } + + return query; +}