Skip to content

Commit

Permalink
feat(DataWithID): revert back to: Data D <= Data *D
Browse files Browse the repository at this point in the history
  • Loading branch information
trakhimenok committed Sep 19, 2023
1 parent 4fa9aef commit 8227489
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
25 changes: 21 additions & 4 deletions record/data_with_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,33 @@ package record
import (
"fmt"
"github.com/dal-go/dalgo/dal"
"reflect"
)

type DataWithID[K comparable, D any] struct {
WithID[K]
Data *D
Data D // we can't use *D here as consumer might want to pass an interface value instead of a pointer
}

func NewDataWithID[K comparable, D any](id K, key *dal.Key, data *D) DataWithID[K, D] {
if data == nil {
panic(fmt.Sprintf("data is nil for (id=%v, key=%v)", id, key))
func NewDataWithID[K comparable, D any](id K, key *dal.Key, data D) DataWithID[K, D] {
v := reflect.ValueOf(data)
kind := v.Kind()
switch kind {
case reflect.Ptr, reflect.Interface:
if v.IsNil() {
t := reflect.TypeOf(data)
panic(fmt.Sprintf("data of type %v is nil for (id=%v, key=%v)", t.String(), id, key))
}
elemType := v.Elem().Type()
switch elemType.Kind() {
case reflect.Struct, reflect.Map:
// OK - expected types
default:
panic("data should be a pointer to a struct or map, got " + elemType.String())
}
default:
t := reflect.TypeOf(data)
panic(fmt.Sprintf("data should be a pointer or an interface, got %v (id=%v, key=%v)", t.String(), id, key))
}
return DataWithID[K, D]{
WithID: NewWithID(id, key, data),
Expand Down
41 changes: 29 additions & 12 deletions record/data_with_id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,60 @@ func TestNewDataWithID(t *testing.T) {
Title string
}

type args[K comparable, D any] struct {
type args[K comparable] struct {
id K
key *dal.Key
data D
data *data
}

type testCase[K comparable, D any] struct {
type testCase[K comparable] struct {
name string
args args[K, D]
want DataWithID[K, D]
args args[K]
want DataWithID[K, *data]
}
tests := []testCase[string, data]{
d1 := data{Title: "test"}
tests := []testCase[string]{
{
name: "should_pass",
args: args[string, data]{
args: args[string]{
id: "r1",
key: dal.NewKeyWithID("r1", "SomeCollection"),
data: data{Title: "test"},
data: &data{Title: "test"},
},
want: DataWithID[string, data]{
want: DataWithID[string, *data]{
WithID: WithID[string]{
ID: "r1",
Key: dal.NewKeyWithID("r1", "SomeCollection"),
Record: dal.NewRecordWithData(dal.NewKeyWithID("r1", "SomeCollection"), data{Title: "test"}),
Record: dal.NewRecordWithData(dal.NewKeyWithID("r1", "SomeCollection"), &d1),
},
Data: &data{Title: "test"},
Data: &d1,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NewDataWithID(tt.args.id, tt.args.key, &tt.args.data)
got := NewDataWithID(tt.args.id, tt.args.key, tt.args.data)
assert.Equal(t, tt.want.ID, got.ID)
assert.Equal(t, tt.want.Key, got.Key)
assert.Equal(t, tt.want.Data, got.Data)
got.Record.SetError(nil)
assert.Equal(t, tt.want.Data, got.Record.Data())
})
}
t.Run("should_panic_on_pointer_to_a_pointer", func(t *testing.T) {
assert.Panics(t, func() {
d1 := data{Title: "test"}
d2 := &d1
d3 := &d2
NewDataWithID("r1", dal.NewKeyWithID("r1", "SomeCollection"), d3)
})
})
t.Run("should_panic_on_pointer_to_an_interface", func(t *testing.T) {
assert.Panics(t, func() {
d1 := data{Title: "test"}
var d2 any = &d1
var d3 = &d2
NewDataWithID("r1", dal.NewKeyWithID("r1", "SomeCollection"), d3)
})
})
}

0 comments on commit 8227489

Please sign in to comment.