Skip to content

Commit

Permalink
support regexp config (flyteorg#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
honnix authored Jun 4, 2020
1 parent ea65c0f commit 8c7e01b
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
41 changes: 41 additions & 0 deletions config/regexp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package config

import (
"encoding/json"
"errors"
"regexp"
)

// A regexp.Regexp wrapper that can marshal and unmarshal into simple regexp string.
type Regexp struct {
regexp.Regexp
}

func (r Regexp) MarshalJSON() ([]byte, error) {
return json.Marshal(r.String())
}

func (r *Regexp) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
r.Regexp = regexp.Regexp{}
return nil
}

var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}

switch value := v.(type) {
case string:
rc, err := regexp.Compile(value)
if err != nil {
return err
}

r.Regexp = *rc
return nil
default:
return errors.New("invalid regexp")
}
}
62 changes: 62 additions & 0 deletions config/regexp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package config

import (
"encoding/json"
"fmt"
"reflect"
"testing"

"github.com/lyft/flytestdlib/internal/utils"

"github.com/stretchr/testify/assert"
)

func TestRegexp_MarshalJSON(t *testing.T) {
validRegexps := []string{
"",
".*",
"^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$",
}

for i, validRegexp := range validRegexps {
t.Run(fmt.Sprintf("Valid %v", i), func(t *testing.T) {
expected := Regexp{Regexp: utils.MustCompileRegexp(validRegexp)}

b, err := expected.MarshalJSON()
assert.NoError(t, err)

actual := Regexp{}
err = actual.UnmarshalJSON(b)
assert.NoError(t, err)

assert.True(t, reflect.DeepEqual(expected, actual))
})
}
}

func TestRegexp_UnmarshalJSON(t *testing.T) {
invalidValues := []interface{}{
"^(",
123,
true,
}
for i, invalidRegexp := range invalidValues {
t.Run(fmt.Sprintf("Invalid %v", i), func(t *testing.T) {
raw, err := json.Marshal(invalidRegexp)
assert.NoError(t, err)

actual := Regexp{}
err = actual.UnmarshalJSON(raw)
assert.Error(t, err)
})
}

t.Run("Empty regexp", func(t *testing.T) {
expected := Regexp{}

actual := Regexp{}
err := actual.UnmarshalJSON([]byte{})
assert.NoError(t, err)
assert.True(t, reflect.DeepEqual(expected, actual))
})
}
11 changes: 11 additions & 0 deletions internal/utils/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"net/url"
"regexp"
)

// A utility function to be used in tests. It parses urlString as url.URL or panics if it's invalid.
Expand All @@ -18,3 +19,13 @@ func MustParseURL(urlString string) url.URL {
func RefInt(val int) *int {
return &val
}

// A utility function to be used in tests. It compiles regexpString as regexp.Regexp or panics if it's invalid.
func MustCompileRegexp(regexpString string) regexp.Regexp {
r, err := regexp.Compile(regexpString)
if err != nil {
panic(err)
}

return *r
}
12 changes: 12 additions & 0 deletions internal/utils/parsers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,15 @@ func TestRefUint32(t *testing.T) {
res := RefInt(input)
assert.Equal(t, input, *res)
}

func TestMustCompileRegexp(t *testing.T) {
t.Run("Valid regexp", func(t *testing.T) {
MustCompileRegexp("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$")
})

t.Run("Invalid regexp", func(t *testing.T) {
assert.Panics(t, func() {
MustCompileRegexp("^(")
})
})
}

0 comments on commit 8c7e01b

Please sign in to comment.