Skip to content

Commit

Permalink
fix: fix match logic for path template (#834)
Browse files Browse the repository at this point in the history
* fix logix

* fix logic

* clean up
  • Loading branch information
xiaozhenliu-gg5 authored May 28, 2020
1 parent 4449426 commit d0d5782
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 23 deletions.
50 changes: 28 additions & 22 deletions src/pathTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,35 @@ export class PathTemplate {
} else {
let segment = this.segments[index];
const variable = segment.match(/(?<={)[$0-9a-zA-Z_]+(?==.*})/g) || [];
if (this.segments[index].includes('**')) {
if (segment.includes('**')) {
bindings[variable[0]] = pathSegments[0] + '/' + pathSegments[1];
pathSegments = pathSegments.slice(2);
} else {
// segment: {blurb_id=*}.{legacy_user=*} to match pathSegments: ['bar.user2']
// split the match pathSegments[0] -> value: ['bar', 'user2']
// compare the length of two arrays, and compare array items
const value = pathSegments[0].split(/[-_.~]/);
if (value.length !== variable!.length) {
throw new Error(
`segment ${segment} does not match ${pathSegments[0]}`
);
}
for (const v of variable) {
bindings[v] = value[0];
segment = segment.replace(`{${v}=*}`, `${value[0]}`);
value.shift();
}
// segment: {blurb_id=*}.{legacy_user=*} matching pathSegments: ['bar~user2'] should fail
if (variable.length > 1 && segment !== pathSegments[0]) {
throw new TypeError(
`non slash resource pattern ${this.segments[index]} and ${pathSegments[0]} should have same separator`
);
// atomic resource
if (variable.length === 1) {
bindings[variable[0]] = pathSegments[0];
} else {
// non-slash resource
// segment: {blurb_id=*}.{legacy_user=*} to match pathSegments: ['bar.user2']
// split the match pathSegments[0] -> value: ['bar', 'user2']
// compare the length of two arrays, and compare array items
const value = pathSegments[0].split(/[-_.~]/);
if (value.length !== variable!.length) {
throw new Error(
`segment ${segment} does not match ${pathSegments[0]}`
);
}
for (const v of variable) {
bindings[v] = value[0];
segment = segment.replace(`{${v}=*}`, `${value[0]}`);
value.shift();
}
// segment: {blurb_id=*}.{legacy_user=*} matching pathSegments: ['bar~user2'] should fail
if (segment !== pathSegments[0]) {
throw new TypeError(
`non slash resource pattern ${this.segments[index]} and ${pathSegments[0]} should have same separator`
);
}
}
pathSegments.shift();
}
Expand Down Expand Up @@ -197,8 +203,8 @@ export class PathTemplate {
}
// {project} / {project=*} -> segments.push('{project=*}');
// -> bindings['project'] = '*'
else if (segment.match(/(?<={)[0-9a-zA-Z-.~_]+(=\*)?(?=})/)) {
const variable = segment.match(/(?<={)[0-9a-zA-Z-.~_]+(=\*)?(?=})/);
else if (segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*)?})/)) {
const variable = segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*)?})/);
this.bindings[variable![0]] = '*';
segments.push(`{${variable![0]}=*}`);
}
Expand Down
2 changes: 1 addition & 1 deletion test/unit/pagedIteration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ describe('paged iteration', () => {
});
});

it.only('cooperates with google-cloud-node usage', done => {
it('cooperates with google-cloud-node usage', done => {
let stream;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const output = streamEvents((pumpify as any).obj()) as pumpify;
Expand Down
15 changes: 15 additions & 0 deletions test/unit/pathTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ describe('PathTemplate', () => {
hello: 'world',
},
},
{
path: 'buckets/long-door-651',
template: 'buckets/{project}',
want: {
project: 'long-door-651',
},
},
];
tests.forEach(t => {
const template = new PathTemplate(t.template);
Expand Down Expand Up @@ -145,6 +152,14 @@ describe('PathTemplate', () => {
const want = 'buckets/f/o/o/objects/google.com:a-b';
assert.strictEqual(template.render(params), want);
});
it('should render atomic resource', () => {
const template = new PathTemplate('buckets/{project=*}');
const params = {
project: 'long-project-name',
};
const want = 'buckets/long-project-name';
assert.strictEqual(template.render(params), want);
});

it('should fail when there are too few variables', () => {
const template = new PathTemplate('buckets/*/*/*/objects/*');
Expand Down

0 comments on commit d0d5782

Please sign in to comment.