New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(router): add url hash support #27105
Changes from all commits
75d5e91
803327e
abaaec4
7b75458
a4891da
3fcfe3b
795168c
5b631cd
91df673
16a1092
9aa2f0a
851d47f
0f27456
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import React, { Text } from 'react-native'; | ||
|
||
import { router } from '../exports'; | ||
import { store } from '../global-state/router-store'; | ||
import { act, renderRouter, screen } from '../testing-library'; | ||
|
||
it('can push a hash url', () => { | ||
renderRouter({ | ||
index: () => <Text testID="index" />, | ||
test: () => <Text testID="test" />, | ||
}); | ||
|
||
expect(screen).toHavePathname('/'); | ||
expect(screen.getByTestId('index')).toBeOnTheScreen(); | ||
|
||
act(() => router.push('/test#a')); | ||
expect(screen.getByTestId('test')).toBeOnTheScreen(); | ||
|
||
act(() => router.push('/test#b')); | ||
act(() => router.push('/test#b')); | ||
act(() => router.push('/test#c')); | ||
|
||
expect(store.rootStateSnapshot()).toStrictEqual({ | ||
index: 4, | ||
key: expect.any(String), | ||
routeNames: ['index', 'test', '_sitemap', '+not-found'], | ||
routes: [ | ||
{ | ||
key: expect.any(String), | ||
name: 'index', | ||
params: undefined, | ||
path: '/', | ||
}, | ||
{ | ||
key: expect.any(String), | ||
name: 'test', | ||
params: { | ||
'#': 'a', | ||
}, | ||
path: undefined, | ||
}, | ||
{ | ||
key: expect.any(String), | ||
name: 'test', | ||
params: { | ||
'#': 'b', | ||
}, | ||
path: undefined, | ||
}, | ||
{ | ||
key: expect.any(String), | ||
name: 'test', | ||
params: { | ||
'#': 'b', | ||
}, | ||
path: undefined, | ||
}, | ||
{ | ||
key: expect.any(String), | ||
name: 'test', | ||
params: { | ||
'#': 'c', | ||
}, | ||
path: undefined, | ||
}, | ||
], | ||
stale: false, | ||
type: 'stack', | ||
}); | ||
}); | ||
|
||
it('works alongside with search params', () => { | ||
renderRouter({ | ||
index: () => <Text testID="index" />, | ||
test: () => <Text testID="test" />, | ||
}); | ||
|
||
expect(screen).toHavePathname('/'); | ||
expect(screen.getByTestId('index')).toBeOnTheScreen(); | ||
|
||
// Add a hash | ||
act(() => router.navigate('/test?a=1#hash1')); | ||
expect(screen.getByTestId('test')).toBeOnTheScreen(); | ||
expect(screen).toHaveSegments(['test']); | ||
expect(screen).toHavePathname('/test'); | ||
expect(screen).toHavePathnameWithParams('/test?a=1#hash1'); | ||
expect(screen).toHaveSearchParams({ a: '1', '#': 'hash1' }); | ||
|
||
act(() => router.navigate('/test?a=2#hash2')); | ||
expect(screen).toHaveSegments(['test']); | ||
expect(screen).toHavePathname('/test'); | ||
expect(screen).toHavePathnameWithParams('/test?a=2#hash2'); | ||
expect(screen).toHaveSearchParams({ a: '2', '#': 'hash2' }); | ||
|
||
act(() => router.navigate('/test?a=3')); | ||
expect(screen).toHaveSegments(['test']); | ||
expect(screen).toHavePathname('/test'); | ||
expect(screen).toHavePathnameWithParams('/test?a=3'); | ||
expect(screen).toHaveSearchParams({ a: '3' }); | ||
}); | ||
|
||
it('navigating to the same route with a hash will only rerender the screen', () => { | ||
renderRouter({ | ||
index: () => <Text testID="index" />, | ||
}); | ||
|
||
expect(store.rootStateSnapshot()).toStrictEqual({ | ||
routes: [ | ||
{ | ||
name: 'index', | ||
path: '/', | ||
}, | ||
], | ||
stale: true, | ||
}); | ||
|
||
act(() => router.navigate('/?#hash1')); | ||
|
||
expect(store.rootStateSnapshot()).toStrictEqual({ | ||
index: 0, | ||
key: expect.any(String), | ||
routeNames: ['index', '_sitemap', '+not-found'], | ||
routes: [ | ||
{ | ||
name: 'index', | ||
key: expect.any(String), | ||
path: '/', | ||
params: { | ||
'#': 'hash1', | ||
}, | ||
}, | ||
], | ||
stale: false, | ||
type: 'stack', | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import getPathFromState from '../getPathFromState'; | ||
|
||
describe('hash support', () => { | ||
it('appends hash to the path', () => { | ||
const state = { | ||
index: 0, | ||
key: 'key', | ||
routes: [ | ||
{ | ||
name: 'index', | ||
path: '/', | ||
params: { | ||
'#': 'hash1', | ||
}, | ||
}, | ||
], | ||
stale: true, | ||
type: 'stack', | ||
}; | ||
|
||
const config = { | ||
screens: { | ||
index: '', | ||
_sitemap: '_sitemap', | ||
}, | ||
}; | ||
|
||
expect(getPathFromState(state, config)).toBe('/#hash1'); | ||
}); | ||
|
||
it('works with nested state, existing router and path params', () => { | ||
const state = { | ||
index: 1, | ||
key: 'key', | ||
routeNames: ['index', '[test]', '_sitemap', '+not-found'], | ||
routes: [ | ||
{ | ||
key: 'key', | ||
name: 'index', | ||
params: undefined, | ||
path: '/', | ||
}, | ||
{ | ||
key: 'key', | ||
name: '[test]', | ||
params: { | ||
test: 'hello-world', | ||
query: 'true', | ||
'#': 'a', | ||
}, | ||
path: undefined, | ||
}, | ||
], | ||
stale: false, | ||
type: 'stack', | ||
}; | ||
|
||
const config = { | ||
screens: { | ||
'[test]': ':test', | ||
index: '', | ||
_sitemap: '_sitemap', | ||
}, | ||
}; | ||
|
||
expect(getPathFromState(state, config)).toBe('/hello-world?query=true#a'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.