mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(router): Update pre/post wildcard matching to retain 0 or more segment match meaning
Prior to the change to support defining required segments before and after the wildcard, the meaning of the wildcard path was '0 or more' so path: foo with a child of ** will still match the ** route when the URL is only 'foo'. If developers want to _require_ something, they can still use path: foo/:anyRequired/**/bar
This commit is contained in:
committed by
Andrew Scott
parent
058377ed55
commit
7f16902a72
@@ -193,16 +193,6 @@ export function defaultUrlMatcher(
|
||||
// The actual URL is shorter than the config, no match
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
// If the wildcard is not at the end of the path, it must match at least one segment.
|
||||
// e.g. `foo/**/bar` does not match `foo/bar`.
|
||||
wildcardIndex > -1 &&
|
||||
pre.length > 0 &&
|
||||
post.length > 0 &&
|
||||
pre.length + post.length === segments.length
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (route.pathMatch === 'full' && segmentGroup.hasChildren() && route.path !== '**') {
|
||||
// The config is longer than the actual URL but we are looking for a full match, return null
|
||||
|
||||
@@ -650,14 +650,49 @@ describe('recognize', () => {
|
||||
const s = await recognizer('foo/a/b/c/bar');
|
||||
checkActivatedRoute(s.root.firstChild!, 'foo/a/b/c/bar', {}, ComponentA);
|
||||
});
|
||||
it('does not match a url with no segments for the wildcard', async () => {
|
||||
await expectAsync(recognizer('foo/bar')).toBeRejected();
|
||||
it('matches a url with no segments for the wildcard', async () => {
|
||||
const s = await recognizer('foo/bar');
|
||||
checkActivatedRoute(s.root.firstChild!, 'foo/bar', {}, ComponentA);
|
||||
});
|
||||
|
||||
it('does not match a url with a wrong suffix', async () => {
|
||||
await expectAsync(recognizer('foo/a/b/baz')).toBeRejected();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with prefix', () => {
|
||||
const recognizer = (url: string) => {
|
||||
const config = [{path: 'foo/**', component: ComponentA}];
|
||||
return recognize(config, url);
|
||||
};
|
||||
|
||||
it('matches a url with segments after the prefix', async () => {
|
||||
const s = await recognizer('foo/a/b');
|
||||
checkActivatedRoute(s.root.firstChild!, 'foo/a/b', {}, ComponentA);
|
||||
});
|
||||
|
||||
it('matches a url with no segments after the prefix', async () => {
|
||||
const s = await recognizer('foo');
|
||||
checkActivatedRoute(s.root.firstChild!, 'foo', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with suffix', () => {
|
||||
const recognizer = (url: string) => {
|
||||
const config = [{path: '**/bar', component: ComponentA}];
|
||||
return recognize(config, url);
|
||||
};
|
||||
|
||||
it('matches a url with segments before the suffix', async () => {
|
||||
const s = await recognizer('a/b/bar');
|
||||
checkActivatedRoute(s.root.firstChild!, 'a/b/bar', {}, ComponentA);
|
||||
});
|
||||
|
||||
it('matches a url with no segments before the suffix', async () => {
|
||||
const s = await recognizer('bar');
|
||||
checkActivatedRoute(s.root.firstChild!, 'bar', {}, ComponentA);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('componentless routes', () => {
|
||||
@@ -877,6 +912,52 @@ describe('recognize', () => {
|
||||
expect(s.root.firstChild!.data['id']).toEqual('b');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with required param before wildcard', () => {
|
||||
const recognizer = (url: string) => {
|
||||
const config = [
|
||||
{
|
||||
path: 'foo/:anyRequired/**/bar',
|
||||
component: ComponentA,
|
||||
},
|
||||
];
|
||||
return recognize(config, url);
|
||||
};
|
||||
|
||||
it('matches with one segment for wildcard', async () => {
|
||||
const s = await recognizer('foo/required/a/bar');
|
||||
checkActivatedRoute(
|
||||
s.root.firstChild!,
|
||||
'foo/required/a/bar',
|
||||
{anyRequired: 'required'},
|
||||
ComponentA,
|
||||
);
|
||||
});
|
||||
|
||||
it('matches with multiple segments for wildcard', async () => {
|
||||
const s = await recognizer('foo/required/a/b/c/bar');
|
||||
checkActivatedRoute(
|
||||
s.root.firstChild!,
|
||||
'foo/required/a/b/c/bar',
|
||||
{anyRequired: 'required'},
|
||||
ComponentA,
|
||||
);
|
||||
});
|
||||
|
||||
it('matches with no segments for wildcard', async () => {
|
||||
const s = await recognizer('foo/required/bar');
|
||||
checkActivatedRoute(
|
||||
s.root.firstChild!,
|
||||
'foo/required/bar',
|
||||
{anyRequired: 'required'},
|
||||
ComponentA,
|
||||
);
|
||||
});
|
||||
|
||||
it('does not match without the required segment', async () => {
|
||||
await expectAsync(recognizer('foo/bar')).toBeRejected();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function recognize(
|
||||
|
||||
Reference in New Issue
Block a user