Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

fix: Fix PathTemplate custom verb logic matching and instantiating #244

Merged
merged 2 commits into from Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Expand Up @@ -32,6 +32,10 @@ project.version = "1.10.5-SNAPSHOT" // {x-version-update:api-common:current}
sourceCompatibility = 1.7
targetCompatibility = 1.7

jacoco {
toolVersion = "0.8.7"
}

// Dependencies
// ------------

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/com/google/api/pathtemplate/PathTemplate.java
Expand Up @@ -664,7 +664,8 @@ private boolean match(
switch (segments.get(i).kind()) {
case BINDING:
case END_BINDING:
// skip
case CUSTOM_VERB:
// These segments do not actually consume any input.
continue;
default:
segsToMatch++;
Expand Down Expand Up @@ -746,7 +747,8 @@ private String instantiate(Map<String, String> values, boolean allowPartial) {
while (iterator.hasNext()) {
Segment seg = iterator.next();
if (!skip && !continueLast) {
String separator = prevSeparator.isEmpty() ? seg.separator() : prevSeparator;
String separator =
prevSeparator.isEmpty() || !iterator.hasNext() ? seg.separator() : prevSeparator;
result.append(separator);
prevSeparator = seg.complexSeparator().isEmpty() ? seg.separator() : seg.complexSeparator();
}
Expand Down
70 changes: 70 additions & 0 deletions src/test/java/com/google/api/pathtemplate/PathTemplateTest.java
Expand Up @@ -114,6 +114,7 @@ public void pathWildcards_matchZeroOrMoreSegments() {
PathTemplate start = PathTemplate.create("{glob=**}/b");
PathTemplate middle = PathTemplate.create("a/{glob=**}/b");
PathTemplate end = PathTemplate.create("a/{glob=**}");
PathTemplate endWithCustomVerb = PathTemplate.create("a/{glob=**}:foo");

Truth.assertThat(start.match("b").get("glob")).isEmpty();
Truth.assertThat(start.match("/b").get("glob")).isEmpty();
Expand All @@ -129,6 +130,10 @@ public void pathWildcards_matchZeroOrMoreSegments() {
Truth.assertThat(end.match("a/").get("glob")).isEmpty();
Truth.assertThat(end.match("a/b").get("glob")).isEqualTo("b");
Truth.assertThat(end.match("a/b/b/b").get("glob")).isEqualTo("b/b/b");

Truth.assertThat(endWithCustomVerb.match("a/:foo").get("glob")).isEmpty();
Truth.assertThat(endWithCustomVerb.match("a/b:foo").get("glob")).isEqualTo("b");
Truth.assertThat(endWithCustomVerb.match("a/b/b:foo").get("glob")).isEqualTo("b/b");
}

@Test
Expand Down Expand Up @@ -173,6 +178,12 @@ public void matchWithUnboundInMiddle() {
assertPositionalMatch(template.match("bar/foo/foo/foo/bar"), "foo/foo", "bar");
}

@Test
public void matchWithCustomVerbs() {
PathTemplate template = PathTemplate.create("**:foo");
assertPositionalMatch(template.match("a/b/c:foo"), "a/b/c");
}

// Complex Resource ID Segments.
// ========

Expand Down Expand Up @@ -215,6 +226,45 @@ public void complexResourceIdBasicCases() {
Truth.assertThat(match.get("zone_b")).isEqualTo("us-east3-a");
}

@Test
public void complexResourceIdCustomVerb() {
// Separate by "~".
PathTemplate template = PathTemplate.create("projects/{project}/zones/{zone_a}~{zone_b}:hello");
Map<String, String> match =
template.match(
"https://www.googleapis.com/compute/v1/projects/project-123/zones/europe-west3-c~us-east3-a:hello");
Truth.assertThat(match).isNotNull();
Truth.assertThat(match.get(PathTemplate.HOSTNAME_VAR)).isEqualTo("https://www.googleapis.com");
Truth.assertThat(match.get("project")).isEqualTo("project-123");
Truth.assertThat(match.get("zone_a}~{zone_b")).isNull();
Truth.assertThat(match.get("zone_a")).isEqualTo("europe-west3-c");
Truth.assertThat(match.get("zone_b")).isEqualTo("us-east3-a");

// Separate by "-".
template = PathTemplate.create("projects/{project}/zones/{zone_a}-{zone_b}:hello");
match = template.match("projects/project-123/zones/europe-west3-c~us-east3-a:hello");
Truth.assertThat(match).isNotNull();
Truth.assertThat(match.get("project")).isEqualTo("project-123");
Truth.assertThat(match.get("zone_a")).isEqualTo("europe");
Truth.assertThat(match.get("zone_b")).isEqualTo("west3-c~us-east3-a");

// Separate by ".".
template = PathTemplate.create("projects/{project}/zones/{zone_a}.{zone_b}:hello");
match = template.match("projects/project-123/zones/europe-west3-c.us-east3-a:hello");
Truth.assertThat(match).isNotNull();
Truth.assertThat(match.get("project")).isEqualTo("project-123");
Truth.assertThat(match.get("zone_a")).isEqualTo("europe-west3-c");
Truth.assertThat(match.get("zone_b")).isEqualTo("us-east3-a");

// Separate by "_".
template = PathTemplate.create("projects/{project}/zones/{zone_a}_{zone_b}:hello");
match = template.match("projects/project-123/zones/europe-west3-c_us-east3-a:hello");
Truth.assertThat(match).isNotNull();
Truth.assertThat(match.get("project")).isEqualTo("project-123");
Truth.assertThat(match.get("zone_a")).isEqualTo("europe-west3-c");
Truth.assertThat(match.get("zone_b")).isEqualTo("us-east3-a");
}

@Test
public void complexResourceIdEqualsWildcard() {
PathTemplate template = PathTemplate.create("projects/{project=*}/zones/{zone_a=*}~{zone_b=*}");
Expand Down Expand Up @@ -604,6 +654,18 @@ public void instantiateWithComplexResourceId_basic() {
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc/zones/apple~baseball");
}

@Test
public void instantiateWithComplexResourceId_customVerb() {
PathTemplate template = PathTemplate.create("projects/{project}/zones/{zone_a}~{zone_b}:hello");
String instance =
template.instantiate("project", "a/b/c", "zone_a", "apple", "zone_b", "baseball");
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc/zones/apple~baseball:hello");

template = PathTemplate.create("projects/{project}/zones/{zone_a}~{zone_b}/stuff:hello");
instance = template.instantiate("project", "a/b/c", "zone_a", "apple", "zone_b", "baseball");
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc/zones/apple~baseball/stuff:hello");
}

@Test
public void instantiateWithComplexResourceId_mixedSeparators() {
PathTemplate template =
Expand Down Expand Up @@ -647,6 +709,14 @@ public void instantiateWithComplexResourceId_mixedSeparatorsInParent() {
Truth.assertThat(instance).isEqualTo("projects/a%2Fb%2Fc~foo.bar/zones/apple~baseball");
}

@Test
public void instantiateWithCustomVerbs() {
PathTemplate template = PathTemplate.create("/v1/{name=operations/**}:cancel");
String templateInstance = template.instantiate("name", "operations/3373707");
Truth.assertThat(templateInstance).isEqualTo("v1/operations/3373707:cancel");
Truth.assertThat(template.matches(templateInstance));
}

// Other
// =====

Expand Down