Skip to content

Commit

Permalink
feat(resourcename): add Join function
Browse files Browse the repository at this point in the history
Join combines resource names, separating them by slashes.

Currently supports leading slashes on each resource names, discussion on
that to be held in [#258].

[#258]: #258
  • Loading branch information
radhus committed Oct 23, 2023
1 parent 1d60af5 commit ee11a61
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
33 changes: 33 additions & 0 deletions resourcename/join.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package resourcename

import (
"fmt"
"strings"
)

// Join combines resource names, separating them by slashes.
func Join(elems ...string) string {
segments := make([]string, 0, len(elems))
for elemIndex, elem := range elems {
var sc Scanner
sc.Init(elem)

for sc.Scan() {
if elemIndex == 0 && len(segments) == 0 && sc.Full() {
segments = append(segments, fmt.Sprintf("//%s", sc.ServiceName()))
}

segment := sc.Segment()
if segment == "" {
continue
}
segments = append(segments, string(segment))
}
}

if len(segments) == 0 {
return "/"
}

return strings.Join(segments, "/")
}
179 changes: 179 additions & 0 deletions resourcename/join_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package resourcename

import (
"testing"

"gotest.tools/v3/assert"
)

func TestJoin(t *testing.T) {
t.Parallel()
for _, tt := range []struct {
name string
input []string
expected string
}{
{
name: "zero",
input: []string{},
expected: "/",
},
{
name: "one",
input: []string{"parent/1"},
expected: "parent/1",
},
{
name: "two",
input: []string{
"parent/1",
"child/2",
},
expected: "parent/1/child/2",
},
{
name: "root first",
input: []string{
"/",
"child/2",
},
expected: "child/2",
},
{
name: "root last",
input: []string{
"parent/1",
"/",
},
expected: "parent/1",
},
{
name: "root second",
input: []string{
"parent/1",
"/",
"child/2",
},
expected: "parent/1/child/2",
},
{
name: "root first and last",
input: []string{
"/",
"child/1",
"/",
},
expected: "child/1",
},
{
name: "only roots",
input: []string{
"/",
"/",
},
expected: "/",
},
{
name: "empty first",
input: []string{
"",
"child/2",
},
expected: "child/2",
},
{
name: "empty second",
input: []string{
"parent/1",
"",
"child/2",
},
expected: "parent/1/child/2",
},
{
name: "invalid first suffix",
input: []string{
"parent/1/",
"child/2",
},
expected: "parent/1/child/2",
},
{
name: "invalid last suffix",
input: []string{
"parent/1",
"child/2/",
},
expected: "parent/1/child/2",
},

{
name: "fully qualified first",
input: []string{
"//foo.example.com/foo/1",
"bar/2",
},
expected: "//foo.example.com/foo/1/bar/2",
},
{
name: "fully qualified second",
input: []string{
"foo/1",
"//foo.example.com/bar/2",
},
expected: "foo/1/bar/2",
},
{
name: "fully qualified both",
input: []string{
"//foo.example.com/foo/1",
"//bar.example.com/bar/2",
},
expected: "//foo.example.com/foo/1/bar/2",
},

// TODO: Should these be disallowed?
// See https://github.com/einride/aip-go/pull/258
{
name: "first slash prefix",
input: []string{
"/parent/1",
"child/2",
},
expected: "parent/1/child/2",
},
{
name: "second slash prefix",
input: []string{
"parent/1",
"/child/2",
},
expected: "parent/1/child/2",
},
{
name: "thirds slash prefix",
input: []string{
"parent/1",
"child/2",
"/extra/3",
},
expected: "parent/1/child/2/extra/3",
},
{
name: "all slash prefix",
input: []string{
"/parent/1",
"/child/2",
"/extra/3",
},
expected: "parent/1/child/2/extra/3",
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
actual := Join(tt.input...)
assert.Equal(t, actual, tt.expected)
})
}
}

0 comments on commit ee11a61

Please sign in to comment.