Skip to content

Commit

Permalink
ensure checking for duplicate params is extended to hash
Browse files Browse the repository at this point in the history
  • Loading branch information
stackoverfloweth committed Jan 27, 2025
1 parent 698c9ae commit 9706e12
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 6 deletions.
32 changes: 32 additions & 0 deletions src/services/combineHash.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, test } from 'vitest'
import { DuplicateParamsError } from '@/errors/duplicateParamsError'
import { combineHash } from '@/services/combineHash'
import { withParams } from '@/services/withParams'

test('given 2 hash, returns new Hash joined together', () => {
const aHash = withParams('/foo', {})
const bHash = withParams('/bar', {})

const response = combineHash(aHash, bHash)

expect(response.value).toBe('/foo/bar')
})

test('given 2 hash with params, returns new Hash joined together with params', () => {
const aHash = withParams('/[foz]', { foz: String })
const bHash = withParams('/[?baz]', { baz: Number })

const response = combineHash(aHash, bHash)

expect(response.value).toBe('/[foz]/[?baz]')
expect(Object.keys(response.params)).toMatchObject(['foz', '?baz'])
})

test('given 2 hash with params that include duplicates, throws DuplicateParamsError', () => {
const aHash = withParams('/[foz]', { foz: String })
const bHash = withParams('/[foz]', { foz: String })

const action: () => void = () => combineHash(aHash, bHash)

expect(action).toThrow(DuplicateParamsError)
})
75 changes: 75 additions & 0 deletions src/services/createExternalRoute.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { expect, test } from 'vitest'
import { createExternalRoute } from '@/services/createExternalRoute'
import { DuplicateParamsError } from '@/errors/duplicateParamsError'
import { withParams } from '@/services/withParams'

test('given parent, path is combined', () => {
const parent = createExternalRoute({
host: 'https://kitbag.dev',
path: '/parent',
})

const child = createExternalRoute({
parent: parent,
path: withParams('/child/[id]', { id: Number }),
})

expect(child.path).toMatchObject({
value: '/parent/child/[id]',
params: {
id: Number,
},
})
})

test('given parent, query is combined', () => {
const parent = createExternalRoute({
host: 'https://kitbag.dev',
query: 'static=123',
})

const child = createExternalRoute({
parent: parent,
query: withParams('sort=[sort]', { sort: Boolean }),
})

expect(child.query).toMatchObject({
value: 'static=123&sort=[sort]',
params: {
sort: Boolean,
},
})
})

test('given parent and child without meta, meta matches parent', () => {
const parent = createExternalRoute({
host: 'https://kitbag.dev',
meta: {
foo: 123,
},
})

const child = createExternalRoute({
parent: parent,
})

expect(child.meta).toMatchObject({
foo: 123,
})
})

test.each([
['https://[foo].dev', '/[foo]', 'foo=[zoo]', '[bar]'],
['https://[zoo].dev', '/[foo]', 'foo=[bar]', '[foo]'],
['https://[zoo].dev', '/[bar]', 'foo=[foo]', '[foo]'],
['https://[zoo].dev', '/[bar]', 'foo=[foo]', '[foo]'],
])('given duplicate params across different parts of the route, throws DuplicateParamsError', (host, path, query, hash) => {
const action: () => void = () => createExternalRoute({
host,
path,
query,
hash,
})

expect(action).toThrow(DuplicateParamsError)
})
2 changes: 1 addition & 1 deletion src/services/createExternalRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function createExternalRoute(options: CreateRouteOptions): Route {

const merged = isWithParent(options) ? combineRoutes(options.parent, route) : route

checkDuplicateParams(merged.path.params, merged.query.params, merged.host.params)
checkDuplicateParams(merged.path.params, merged.query.params, merged.host.params, merged.hash.params)

return merged
}
18 changes: 17 additions & 1 deletion src/services/createRoute.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { expect, test, vi } from 'vitest'
import { createRoute } from '@/services/createRoute'
import { createRouter, withParams } from '@/main'
import { component } from '@/utilities/testHelpers'
import { createRouter } from '@/services/createRouter'
import { DuplicateParamsError } from '@/errors/duplicateParamsError'
import { withParams } from '@/services/withParams'

test('given parent, path is combined', () => {
const parent = createRoute({
Expand Down Expand Up @@ -263,3 +265,17 @@ test('async parent props with multiple views are passed to child props', async (

expect(spy).toHaveBeenCalledWith({ value1: 123, value2: 456 })
})

test.each([
['/[foo]', 'foo=[foo]', '[bar]'],
['/[foo]', 'foo=[bar]', '[foo]'],
['/[bar]', 'foo=[foo]', '[foo]'],
])('given duplicate params across different parts of the route, throws DuplicateParamsError', (path, query, hash) => {
const action: () => void = () => createRoute({
path,
query,
hash,
})

expect(action).toThrow(DuplicateParamsError)
})
2 changes: 1 addition & 1 deletion src/services/createRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function createRoute(options: CreateRouteOptions, props?: CreateRouteProp

const merged = isWithParent(options) ? combineRoutes(options.parent, route) : route

checkDuplicateParams(merged.path.params, merged.query.params)
checkDuplicateParams(merged.path.params, merged.query.params, merged.hash.params)

return merged
}
4 changes: 2 additions & 2 deletions src/types/props.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Route } from '@/main'
import { CallbackContext } from '@/services/createCallbackContext'
import { PropsGetter } from './createRouteOptions'
import { PropsGetter } from '@/types/createRouteOptions'
import { Route } from '@/types/route'

/**
* Context provided to props callback functions
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/checkDuplicateNames.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, test } from 'vitest'
import { DuplicateNamesError } from '@/errors/duplicateNamesError'
import { createRoute } from '@/main'
import { checkDuplicateNames } from '@/utilities/checkDuplicateNames'
import { createRoute } from '@/services/createRoute'

test('given a single array without duplicates, does nothing', () => {
const routes = [
Expand Down

0 comments on commit 9706e12

Please sign in to comment.