mirror of https://github.com/knative/pkg.git
Add utility methods for api.URL (#785)
* Add IsEmpty and HTTP/HTTPS constructors, simplify tests. * Simplify remaining construction of URLs in tests with struct initialization. * Reverse `nonEmpty` since most cases are now non-empty. * Update initial tests. Also fix a bug in URL.String() and update test.
This commit is contained in:
parent
5dcae770a9
commit
ea367c1342
27
apis/url.go
27
apis/url.go
|
@ -41,6 +41,30 @@ func ParseURL(u string) (*URL, error) {
|
|||
return (*URL)(pu), nil
|
||||
}
|
||||
|
||||
// HTTP creates an http:// URL pointing to a known domain.
|
||||
func HTTP(domain string) *URL {
|
||||
return &URL{
|
||||
Scheme: "http",
|
||||
Host: domain,
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPS creates an https:// URL pointing to a known domain.
|
||||
func HTTPS(domain string) *URL {
|
||||
return &URL{
|
||||
Scheme: "https",
|
||||
Host: domain,
|
||||
}
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the URL is `nil` or represents an empty URL.
|
||||
func (u *URL) IsEmpty() bool {
|
||||
if u == nil {
|
||||
return true
|
||||
}
|
||||
return *u == URL{}
|
||||
}
|
||||
|
||||
// MarshalJSON implements a custom json marshal method used when this type is
|
||||
// marshaled using json.Marshal.
|
||||
// json.Marshaler impl
|
||||
|
@ -79,6 +103,9 @@ func (u *URL) String() string {
|
|||
|
||||
// URL returns the URL as a url.URL.
|
||||
func (u *URL) URL() *url.URL {
|
||||
if u == nil {
|
||||
return &url.URL{}
|
||||
}
|
||||
url := url.URL(*u)
|
||||
return &url
|
||||
}
|
||||
|
|
169
apis/url_test.go
169
apis/url_test.go
|
@ -17,7 +17,6 @@ package apis
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
@ -25,37 +24,42 @@ import (
|
|||
|
||||
func TestParseURL(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
t string
|
||||
want *URL
|
||||
wantErr bool
|
||||
t string
|
||||
want *URL
|
||||
wantEmpty bool
|
||||
wantErr bool
|
||||
}{
|
||||
"empty": {
|
||||
want: nil,
|
||||
},
|
||||
"empty string": {
|
||||
t: "",
|
||||
want: nil,
|
||||
want: nil,
|
||||
wantEmpty: true,
|
||||
},
|
||||
"invalid format": {
|
||||
t: "💩://error",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
t: "💩://error",
|
||||
want: nil,
|
||||
wantEmpty: true,
|
||||
wantErr: true,
|
||||
},
|
||||
"relative": {
|
||||
t: "/path/to/something",
|
||||
want: func() *URL {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &u
|
||||
}(),
|
||||
want: &URL{
|
||||
Path: "/path/to/something",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
t: "http://path/to/something",
|
||||
want: func() *URL {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &u
|
||||
}(),
|
||||
want: &URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
},
|
||||
},
|
||||
"simplehttp": {
|
||||
t: "http://foo",
|
||||
want: HTTP("foo"),
|
||||
},
|
||||
"simplehttps": {
|
||||
t: "https://foo",
|
||||
want: HTTPS("foo"),
|
||||
},
|
||||
}
|
||||
for n, tc := range testCases {
|
||||
|
@ -71,6 +75,10 @@ func TestParseURL(t *testing.T) {
|
|||
t.Fatalf("ParseURL() = %v, wanted error", got)
|
||||
}
|
||||
|
||||
if tc.wantEmpty != got.IsEmpty() {
|
||||
t.Errorf("IsEmpty(%v) = %t, wanted %t", got, got.IsEmpty(), tc.wantEmpty)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Errorf("unexpected object (-want, +got) = %v", diff)
|
||||
}
|
||||
|
@ -131,19 +139,17 @@ func TestJsonUnmarshalURL(t *testing.T) {
|
|||
},
|
||||
"relative": {
|
||||
b: []byte(`"/path/to/something"`),
|
||||
want: func() *URL {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &u
|
||||
}(),
|
||||
want: &URL{
|
||||
Path: "/path/to/something",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
b: []byte(`"http://path/to/something"`),
|
||||
want: func() *URL {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &u
|
||||
}(),
|
||||
want: &URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
},
|
||||
},
|
||||
}
|
||||
for n, tc := range testCases {
|
||||
|
@ -189,19 +195,15 @@ func TestJsonMarshalURLAsMember(t *testing.T) {
|
|||
want: []byte(`{"url":""}`),
|
||||
},
|
||||
"relative": {
|
||||
obj: func() *objectType {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: u}
|
||||
}(),
|
||||
obj: &objectType{URL: URL{Path: "/path/to/something"}},
|
||||
want: []byte(`{"url":"/path/to/something"}`),
|
||||
},
|
||||
"url": {
|
||||
obj: func() *objectType {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: u}
|
||||
}(),
|
||||
obj: &objectType{URL: URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
}},
|
||||
want: []byte(`{"url":"http://path/to/something"}`),
|
||||
},
|
||||
"empty url": {
|
||||
|
@ -252,19 +254,15 @@ func TestJsonMarshalURLAsPointerMember(t *testing.T) {
|
|||
want: []byte(`{}`),
|
||||
},
|
||||
"relative": {
|
||||
obj: func() *objectType {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: &u}
|
||||
}(),
|
||||
obj: &objectType{URL: &URL{Path: "/path/to/something"}},
|
||||
want: []byte(`{"url":"/path/to/something"}`),
|
||||
},
|
||||
"url": {
|
||||
obj: func() *objectType {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: &u}
|
||||
}(),
|
||||
obj: &objectType{URL: &URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
}},
|
||||
want: []byte(`{"url":"http://path/to/something"}`),
|
||||
},
|
||||
"empty url": {
|
||||
|
@ -319,20 +317,16 @@ func TestJsonUnmarshalURLAsMember(t *testing.T) {
|
|||
wantErr: `parse %: invalid URL escape "%"`,
|
||||
},
|
||||
"relative": {
|
||||
b: []byte(`{"url":"/path/to/something"}`),
|
||||
want: func() *objectType {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: u}
|
||||
}(),
|
||||
b: []byte(`{"url":"/path/to/something"}`),
|
||||
want: &objectType{URL: URL{Path: "/path/to/something"}},
|
||||
},
|
||||
"url": {
|
||||
b: []byte(`{"url":"http://path/to/something"}`),
|
||||
want: func() *objectType {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: u}
|
||||
}(),
|
||||
want: &objectType{URL: URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
}},
|
||||
},
|
||||
"empty url": {
|
||||
b: []byte(`{"url":""}`),
|
||||
|
@ -386,20 +380,16 @@ func TestJsonUnmarshalURLAsMemberPointer(t *testing.T) {
|
|||
wantErr: `parse %: invalid URL escape "%"`,
|
||||
},
|
||||
"relative": {
|
||||
b: []byte(`{"url":"/path/to/something"}`),
|
||||
want: func() *objectType {
|
||||
uu, _ := url.Parse("/path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: &u}
|
||||
}(),
|
||||
b: []byte(`{"url":"/path/to/something"}`),
|
||||
want: &objectType{URL: &URL{Path: "/path/to/something"}},
|
||||
},
|
||||
"url": {
|
||||
b: []byte(`{"url":"http://path/to/something"}`),
|
||||
want: func() *objectType {
|
||||
uu, _ := url.Parse("http://path/to/something")
|
||||
u := URL(*uu)
|
||||
return &objectType{URL: &u}
|
||||
}(),
|
||||
want: &objectType{URL: &URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
}},
|
||||
},
|
||||
"empty url": {
|
||||
b: []byte(`{"url":""}`),
|
||||
|
@ -432,34 +422,41 @@ func TestJsonUnmarshalURLAsMemberPointer(t *testing.T) {
|
|||
|
||||
func TestURLString(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
t string
|
||||
t *URL
|
||||
want string
|
||||
}{
|
||||
"nil": {},
|
||||
"empty": {
|
||||
t: &URL{},
|
||||
want: "",
|
||||
},
|
||||
"relative": {
|
||||
t: "/path/to/something",
|
||||
t: &URL{Path: "/path/to/something"},
|
||||
want: "/path/to/something",
|
||||
},
|
||||
"url": {
|
||||
t: "http://path/to/something",
|
||||
"nopath": {
|
||||
t: HTTPS("foo"),
|
||||
want:"https://foo",
|
||||
},
|
||||
"absolute": {
|
||||
t: &URL{
|
||||
Scheme: "http",
|
||||
Host: "path",
|
||||
Path: "/to/something",
|
||||
},
|
||||
want: "http://path/to/something",
|
||||
},
|
||||
}
|
||||
for n, tc := range testCases {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
got := tc.t
|
||||
|
||||
tt, err := ParseURL(tc.t)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseURL() = %v", err)
|
||||
}
|
||||
got := tt.String()
|
||||
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Logf("got: %s", string(got))
|
||||
if diff := cmp.Diff(tc.want, got.String()); diff != "" {
|
||||
t.Errorf("unexpected string (-want, +got) = %v", diff)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.URL().String()); diff != "" {
|
||||
t.Errorf("unexpected URL (-want, +got) = %v", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue