Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsers for: float32, *int, *string, *time.Time, *float32 #1

Merged
merged 2 commits into from
Jan 19, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions assist.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,29 @@ import (
"time"

"github.com/DATA-DOG/godog/gherkin"
"github.com/rdumont/assistdog/defaults"
"github.com/cashcowpro/assistdog/defaults"
)

var defaultParsers = map[interface{}]ParseFunc{
"": defaults.ParseString,
0: defaults.ParseInt,
time.Time{}: defaults.ParseTime,
"": defaults.ParseString,
0: defaults.ParseInt,
float32(0.0): defaults.ParseFloat32,
time.Time{}: defaults.ParseTime,
defaults.NilString: defaults.ParseStringPointer,
defaults.NilInt: defaults.ParseIntPointer,
defaults.NilFloat32: defaults.ParseFloat32Pointer,
defaults.NilTime: defaults.ParseTimePointer,
}

var defaultComparers = map[interface{}]CompareFunc{
"": defaults.CompareString,
0: defaults.CompareInt,
time.Time{}: defaults.CompareTime,
"": defaults.CompareString,
0: defaults.CompareInt,
float32(0.0): defaults.CompareFloat32,
time.Time{}: defaults.CompareTime,
defaults.NilString: defaults.CompareStringPointer,
defaults.NilInt: defaults.CompareIntPointer,
defaults.NilFloat32: defaults.CompareFloat32Pointer,
defaults.NilTime: defaults.CompareTimePointer,
}

// ParseFunc parses a raw string value from a table into a given type.
Expand Down
41 changes: 39 additions & 2 deletions assist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package assistdog
import (
"reflect"
"testing"
"time"

"github.com/rdumont/assistdog/defaults"

Expand All @@ -11,8 +12,17 @@ import (
)

type person struct {
Name string
Height int
Name string
Height int
Weight float32
CreatedAt time.Time
}

type nillablePerson struct {
Name *string
Height *int
Weight *float32
CreatedAt *time.Time
}

func TestRemoveParser(t *testing.T) {
Expand All @@ -38,6 +48,8 @@ func TestCreateInstance(t *testing.T) {
table := buildTable([][]string{
{"Name", "John"},
{"Height", "182"},
{"Weight", "85.56"},
{"CreatedAt", "2018-01-19T10:41:00Z"},
})

result, err := NewDefault().CreateInstance(new(person), table)
Expand All @@ -49,6 +61,31 @@ func TestCreateInstance(t *testing.T) {
typed := result.(*person)
assert.Equal(t, "John", typed.Name)
assert.Equal(t, 182, typed.Height)
assert.Equal(t, float32(85.56), typed.Weight)
parsedTime, err := time.Parse(time.RFC3339, "2018-01-19T10:41:00Z")
assert.Nil(t, err)
assert.Equal(t, parsedTime, typed.CreatedAt)
})

t.Run("successfully for nillable attributes", func(t *testing.T) {
table := buildTable([][]string{
{"Name", "N/A"},
{"Height", "N/A"},
{"Weight", "N/A"},
{"CreatedAt", "N/A"},
})

result, err := NewDefault().CreateInstance(new(nillablePerson), table)
if err != nil {
t.Error(err)
return
}

typed := result.(*nillablePerson)
assert.Nil(t, typed.Name)
assert.Nil(t, typed.Height)
assert.Nil(t, typed.Weight)
assert.Nil(t, typed.CreatedAt)
})

t.Run("with extra field", func(t *testing.T) {
Expand Down
95 changes: 94 additions & 1 deletion defaults/comparers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"
)

// CompareString function
func CompareString(raw string, actual interface{}) error {
as, ok := actual.(string)
if !ok {
Expand All @@ -19,6 +20,7 @@ func CompareString(raw string, actual interface{}) error {
return nil
}

// CompareInt function
func CompareInt(raw string, actual interface{}) error {
ai, ok := actual.(int)
if !ok {
Expand All @@ -37,6 +39,26 @@ func CompareInt(raw string, actual interface{}) error {
return nil
}

// CompareFloat32 function
func CompareFloat32(raw string, actual interface{}) error {
as, ok := actual.(float32)
if !ok {
return fmt.Errorf("%v is not a float32", actual)
}

ei, err := strconv.ParseFloat(raw, 32)
if err != nil {
return err
}

if as != float32(ei) {
return fmt.Errorf("expected %v, but got %v", raw, as)
}

return nil
}

// CompareTime function
func CompareTime(raw string, actual interface{}) error {
at, ok := actual.(time.Time)
if !ok {
Expand All @@ -48,9 +70,80 @@ func CompareTime(raw string, actual interface{}) error {
return err
}

if et != at {
if !at.Equal(et.(time.Time)) {
return fmt.Errorf("expected %v, but got %v", et, at)
}

return nil
}

// CompareStringPointer function
func CompareStringPointer(raw string, actual interface{}) error {
val, ok := actual.(*string)

if !ok {
return fmt.Errorf("%v is not *string", actual)
}

if val == nil {
if raw == NilRawString {
return nil
}
return fmt.Errorf("expected %v, but got nil", raw)
}

return CompareString(raw, *val)
}

// CompareIntPointer function
func CompareIntPointer(raw string, actual interface{}) error {
val, ok := actual.(*int)

if !ok {
return fmt.Errorf("%v is not *int", actual)
}

if val == nil {
if raw == NilRawString {
return nil
}
return fmt.Errorf("expected %v, but got nil", raw)
}

return CompareInt(raw, *val)
}

// CompareFloat32Pointer function
func CompareFloat32Pointer(raw string, actual interface{}) error {
val, ok := actual.(*float32)

if !ok {
return fmt.Errorf("%v is not *float32", actual)
}

if val == nil {
if raw == NilRawString {
return nil
}
return fmt.Errorf("expected %v, but got nil", raw)
}

return CompareFloat32(raw, *val)
}

// CompareTimePointer function
func CompareTimePointer(raw string, actual interface{}) error {
val, ok := actual.(*time.Time)

if !ok {
return fmt.Errorf("%v is not *time.Time", actual)
}

if val == nil {
if raw == NilRawString {
return nil
}
return fmt.Errorf("expected %v, but got nil", raw)
}
return CompareTime(raw, *val)
}
74 changes: 74 additions & 0 deletions defaults/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,38 @@ var supportedTimeLayouts = []string{
time.RFC3339Nano,
}

// NilRawString used to identify "nil" values on the table
const NilRawString = "N/A"

// NilInt variable
var NilInt *int

// NilString variable
var NilString *string

// NilTime variable
var NilTime *time.Time

// NilFloat32 variable
var NilFloat32 *float32

// ParseString function
func ParseString(raw string) (interface{}, error) {
return raw, nil
}

// ParseInt function
func ParseInt(raw string) (interface{}, error) {
return strconv.Atoi(raw)
}

// ParseFloat32 function
func ParseFloat32(raw string) (interface{}, error) {
ei, err := strconv.ParseFloat(raw, 32)
return float32(ei), err
}

// ParseTime function
func ParseTime(raw string) (interface{}, error) {
var fieldTime time.Time
var err error
Expand All @@ -38,3 +62,53 @@ func ParseTime(raw string) (interface{}, error) {

return fieldTime, nil
}

// ParseStringPointer function
func ParseStringPointer(raw string) (interface{}, error) {
if raw == NilRawString {
return NilString, nil
}
return &raw, nil
}

// ParseIntPointer function
func ParseIntPointer(raw string) (interface{}, error) {
if raw == NilRawString {
return NilInt, nil
}

parsedInt, err := ParseInt(raw)
if err != nil {
return nil, err
}
time := parsedInt.(int)
return &time, nil
}

// ParseFloat32Pointer function
func ParseFloat32Pointer(raw string) (interface{}, error) {
if raw == NilRawString {
return NilFloat32, nil
}

parsedFloat32, err := ParseFloat32(raw)
if err != nil {
return nil, err
}
float32 := parsedFloat32.(float32)
return &float32, nil
}

// ParseTimePointer function
func ParseTimePointer(raw string) (interface{}, error) {
if raw == NilRawString {
return NilTime, nil
}

parsedTime, err := ParseTime(raw)
if err != nil {
return nil, err
}
time := parsedTime.(time.Time)
return &time, err
}