Skip to content

Commit

Permalink
feat: Add support of []url.URL (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
obalunenko committed Mar 27, 2023
1 parent 01357aa commit 8bcac8d
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/obalunenko/getenv.svg)](https://pkg.go.dev/github.com/obalunenko/getenv)
[![Go Report Card](https://goreportcard.com/badge/github.com/obalunenko/getenv)](https://goreportcard.com/report/github.com/obalunenko/getenv)
[![codecov](https://codecov.io/gh/obalunenko/getenv/branch/master/graph/badge.svg)](https://codecov.io/gh/obalunenko/getenv)
![coverbadger-tag-do-not-edit](https://img.shields.io/badge/coverage-97.73%25-brightgreen?longCache=true&style=flat)
![coverbadger-tag-do-not-edit](https://img.shields.io/badge/coverage-97.58%25-brightgreen?longCache=true&style=flat)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=obalunenko_getenv&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=obalunenko_getenv)

# getenv
Expand Down Expand Up @@ -42,6 +42,7 @@ Types supported:
- []time.Duration
- bool
- url.URL
- []url.URL
- net.IP

## Examples
Expand Down
1 change: 1 addition & 0 deletions getenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
// - []time.Duration
// - bool
// - url.URL
// - []url.URL
// - net.IP
package getenv

Expand Down
83 changes: 83 additions & 0 deletions getenv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3049,3 +3049,86 @@ func TestIPOrDefault(t *testing.T) {
})
}
}

func TestURLSliceOrDefault(t *testing.T) {
type args struct {
key string
defaultVal []url.URL
separator string
}

type expected struct {
val []url.URL
}

var tests = []struct {
name string
precond precondition
args args
expected expected
}{
{
name: "env not set - default returned",
precond: precondition{
setenv: setenv{
isSet: false,
val: "https://google.com,https://github.com",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{getURL(t, "https://bing.com")},
},
},
{
name: "env set - env value returned",
precond: precondition{
setenv: setenv{
isSet: true,
val: "https://google.com,https://github.com",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{
getURL(t, "https://google.com"),
getURL(t, "https://github.com"),
},
},
},
{
name: "empty env value set - default returned",
precond: precondition{
setenv: setenv{
isSet: true,
val: "",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{getURL(t, "https://bing.com")},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.precond.maybeSetEnv(t, tt.args.key)

got := getenv.EnvOrDefault(tt.args.key, tt.args.defaultVal, option.WithSeparator(","))
assert.Equal(t, tt.expected.val, got)
})
}
}
2 changes: 1 addition & 1 deletion internal/constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
type (
// EnvParsable is a constraint for supported environment variable types parsers.
EnvParsable interface {
String | Int | Uint | Float | Time | bool | url.URL | net.IP
String | Int | Uint | Float | Time | bool | url.URL | []url.URL | net.IP
}

// String is a constraint for strings and slice of strings.
Expand Down
12 changes: 12 additions & 0 deletions internal/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ func NewEnvParser(v any) EnvParser {
p = newTimeParser(t)
case url.URL:
p = urlParser(t)
case []url.URL:
p = urlSliceParser(t)
case net.IP:
p = ipParser(t)
default:
Expand Down Expand Up @@ -429,6 +431,16 @@ func (t urlParser) ParseEnv(key string, defaltVal any, _ Parameters) any {
return val
}

type urlSliceParser []url.URL

func (t urlSliceParser) ParseEnv(key string, defaltVal any, opts Parameters) any {
separator := opts.Separator

val := urlSliceOrDefault(key, defaltVal.([]url.URL), separator)

return val
}

type ipParser net.IP

func (t ipParser) ParseEnv(key string, defaltVal any, _ Parameters) any {
Expand Down
34 changes: 32 additions & 2 deletions internal/iface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,14 @@ func TestNewEnvParser(t *testing.T) {
want: urlParser(url.URL{}),
wantPanic: assert.NotPanics,
},
{
name: "[]url.URL",
args: args{
v: []url.URL{},
},
want: urlSliceParser([]url.URL{}),
wantPanic: assert.NotPanics,
},
{
name: "net.IP",
args: args{
Expand Down Expand Up @@ -917,7 +925,7 @@ func Test_ParseEnv(t *testing.T) {
precond: precondition{
setenv: setenv{
isSet: true,
val: "https.google.com",
val: "https://google.com",
},
},
args: args{
Expand All @@ -928,7 +936,29 @@ func Test_ParseEnv(t *testing.T) {
Layout: time.DateOnly,
},
},
want: getURL(t, "https.google.com"),
want: getURL(t, "https://google.com"),
},
{
name: "urlSliceParser",
s: urlSliceParser([]url.URL{}),
precond: precondition{
setenv: setenv{
isSet: true,
val: "https://google.com,https://bing.com",
},
},
args: args{
key: testEnvKey,
defaltVal: []url.URL{},
in2: Parameters{
Separator: ",",
Layout: time.DateOnly,
},
},
want: []url.URL{
getURL(t, "https://google.com"),
getURL(t, "https://bing.com"),
},
},
{
name: "ipParser",
Expand Down
23 changes: 23 additions & 0 deletions internal/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,29 @@ func urlOrDefault(key string, defaultVal url.URL) url.URL {
return *val
}

// urlSliceOrDefault retrieves the url.URL slice value of the environment variable named
// by the key and separated by sep.
// If variable not set or value is empty - defaultVal will be returned.
func urlSliceOrDefault(key string, defaultVal []url.URL, sep string) []url.URL {
valraw := stringSliceOrDefault(key, nil, sep)
if valraw == nil {
return defaultVal
}

val := make([]url.URL, 0, len(valraw))

for _, s := range valraw {
v, err := url.Parse(s)
if err != nil {
return defaultVal
}

val = append(val, *v)
}

return val
}

// ipOrDefault retrieves the net.IP value of the environment variable named
// by the key represented by layout.
// If variable not set or value is empty - defaultVal will be returned.
Expand Down
83 changes: 83 additions & 0 deletions internal/parsers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3199,3 +3199,86 @@ func Test_ipOrDefault(t *testing.T) {
})
}
}

func Test_urlSliceOrDefault(t *testing.T) {
type args struct {
key string
defaultVal []url.URL
separator string
}

type expected struct {
val []url.URL
}

var tests = []struct {
name string
precond precondition
args args
expected expected
}{
{
name: "env not set - default returned",
precond: precondition{
setenv: setenv{
isSet: false,
val: "https://google.com,https://github.com",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{getURL(t, "https://bing.com")},
},
},
{
name: "env set - env value returned",
precond: precondition{
setenv: setenv{
isSet: true,
val: "https://google.com,https://github.com",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{
getURL(t, "https://google.com"),
getURL(t, "https://github.com"),
},
},
},
{
name: "empty env value set - default returned",
precond: precondition{
setenv: setenv{
isSet: true,
val: "",
},
},
args: args{
key: testEnvKey,
defaultVal: []url.URL{getURL(t, "https://bing.com")},
separator: ",",
},
expected: expected{
val: []url.URL{getURL(t, "https://bing.com")},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.precond.maybeSetEnv(t, tt.args.key)

got := urlSliceOrDefault(tt.args.key, tt.args.defaultVal, ",")
assert.Equal(t, tt.expected.val, got)
})
}
}

0 comments on commit 8bcac8d

Please sign in to comment.