From 89a26bd2ce09a39f52952c4fbbf76dfd212522b4 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 20 Aug 2025 13:30:26 +0200 Subject: [PATCH] fix: handle missing parser --- .../matchers/matcher-pattern-query.spec.ts | 105 ++++++++++++++++++ .../matchers/matcher-pattern-query.ts | 14 ++- 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.spec.ts b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.spec.ts index b5e31f18..9c8b63e7 100644 --- a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.spec.ts +++ b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.spec.ts @@ -400,4 +400,109 @@ describe('MatcherPatternQueryParam', () => { expect(matcher.match({ other: 'value' })).toEqual({ missing: 'default' }) }) }) + + describe('defaultValue', () => { + describe('match', () => { + it('should fallback to PARAM_PARSER_DEFAULTS.get when parser.get is undefined', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'value', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.get which returns value ?? null + expect(matcher.match({ test_param: 'value' })).toEqual({ + test: 'value', + }) + expect(matcher.match({ test_param: null })).toEqual({ test: null }) + expect(matcher.match({})).toEqual({ test: undefined }) + }) + + it('should handle array format with missing get method', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'array', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.get which returns value ?? null + expect(matcher.match({ test_param: ['a', 'b'] })).toEqual({ + test: ['a', 'b'], + }) + expect(matcher.match({ test_param: 'single' })).toEqual({ + test: ['single'], + }) + }) + + it('should handle both format with missing get method', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'both', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.get which returns value ?? null + expect(matcher.match({ test_param: 'value' })).toEqual({ + test: 'value', + }) + expect(matcher.match({ test_param: ['a', 'b'] })).toEqual({ + test: ['a', 'b'], + }) + }) + }) + + describe('build', () => { + it('should fallback to PARAM_PARSER_DEFAULTS.set when parser.set is undefined', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'value', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.set which converts to string + expect(matcher.build({ test: 'value' })).toEqual({ + test_param: 'value', + }) + expect(matcher.build({ test: 123 })).toEqual({ test_param: '123' }) + expect(matcher.build({ test: true })).toEqual({ test_param: 'true' }) + expect(matcher.build({ test: null })).toEqual({ test_param: null }) + expect(matcher.build({ test: undefined })).toEqual({}) + }) + + it('should handle array values with missing set method', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'array', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.set which handles arrays + expect(matcher.build({ test: ['a', 'b'] })).toEqual({ + test_param: ['a', 'b'], + }) + expect(matcher.build({ test: [1, 2] })).toEqual({ + test_param: ['1', '2'], + }) + expect(matcher.build({ test: [1, true] })).toEqual({ + test_param: ['1', 'true'], + }) + }) + + it('should handle both format with missing set method', () => { + const matcher = new MatcherPatternQueryParam( + 'test', + 'test_param', + 'both', + {} + ) + // Should use PARAM_PARSER_DEFAULTS.set + expect(matcher.build({ test: 'value' })).toEqual({ + test_param: 'value', + }) + expect(matcher.build({ test: ['a', 'b'] })).toEqual({ + test_param: ['a', 'b'], + }) + }) + }) + }) }) diff --git a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.ts b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.ts index 7d1b4cd1..530a1c58 100644 --- a/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.ts +++ b/packages/router/src/experimental/route-resolver/matchers/matcher-pattern-query.ts @@ -5,7 +5,7 @@ import { MatcherPattern, MatcherQueryParams, } from './matcher-pattern' -import { ParamParser } from './param-parsers' +import { ParamParser, PARAM_PARSER_DEFAULTS } from './param-parsers' /** * Handles the `query` part of a URL. It can transform a query object into an @@ -55,7 +55,7 @@ export class MatcherPatternQueryParam try { ;(value as unknown[]).push( // for ts errors - this.parser.get!(v) + (this.parser.get ?? PARAM_PARSER_DEFAULTS.get)(v) as T ) } catch (error) { // we skip the invalid value unless there is no defaultValue @@ -75,12 +75,13 @@ export class MatcherPatternQueryParam } } else { try { - // FIXME: fallback to default getter value = // non existing query param should falll back to defaultValue valueBeforeParse === undefined ? valueBeforeParse - : this.parser.get!(valueBeforeParse) + : ((this.parser.get ?? PARAM_PARSER_DEFAULTS.get)( + valueBeforeParse + ) as T) } catch (error) { if (this.defaultValue === undefined) { throw error @@ -103,8 +104,9 @@ export class MatcherPatternQueryParam } return { - // FIXME: default setter - [this.queryKey]: this.parser.set!(paramValue), + [this.queryKey]: (this.parser.set ?? PARAM_PARSER_DEFAULTS.set)( + paramValue as any + ), } } } -- 2.47.3