Merge branch 'master' of github.com:shwoodard/jsonapi

* 'master' of github.com:shwoodard/jsonapi:
  make utility function to output embedded records
  explicitly check for float64
  Add test for set id
This commit is contained in:
Sam Woodard 2015-07-08 16:48:19 -07:00
commit 6f271d2ac7
3 changed files with 74 additions and 30 deletions

View File

@ -106,7 +106,7 @@ func unmarshalJsonApiNode(data *JsonApiNode, model reflect.Value) error {
return false
}
if fieldValue.Kind() == reflect.Int && v.Kind() != reflect.Int {
if fieldValue.Kind() == reflect.Int && v.Kind() == reflect.Float64 {
fieldValue.Set(reflect.ValueOf(int(v.Interface().(float64))))
} else {
fieldValue.Set(reflect.ValueOf(val))

View File

@ -26,18 +26,18 @@ func TestMalformedTag(t *testing.T) {
}
}
//func TestUnmarshalSetsId(t *testing.T) {
//in := samplePayload()
//out := new(Blog)
func TestUnmarshalSetsId(t *testing.T) {
in := samplePayloadWithId()
out := new(Blog)
//if err := UnmarshalJsonApiPayload(in, out); err != nil {
//t.Fatal(err)
//}
if err := UnmarshalJsonApiPayload(in, out); err != nil {
t.Fatal(err)
}
//if out.Id != 0 {
//t.Fatalf("Did not set Id on dst interface")
//}
//}
if out.Id != 2 {
t.Fatalf("Did not set Id on dst interface")
}
}
func TestUnmarshalSetsAttrs(t *testing.T) {
out, err := unmarshalSamplePayload()
@ -173,3 +173,23 @@ func samplePayload() io.Reader {
return out
}
func samplePayloadWithId() io.Reader {
payload := &JsonApiOnePayload{
Data: &JsonApiNode{
Id: "2",
Type: "blogs",
Attributes: map[string]interface{}{
"title": "New blog",
"created_at": 1436216820,
"view_count": 1000,
},
},
}
out := bytes.NewBuffer(nil)
json.NewEncoder(out).Encode(payload)
return out
}

View File

@ -15,7 +15,7 @@ func MarshalJsonApiManyPayload(models Models) (*JsonApiManyPayload, error) {
incl := make([]*JsonApiNode, 0)
for _, model := range d {
node, included, err := visitModelNode(model)
node, included, err := visitModelNode(model, true)
if err != nil {
return nil, err
}
@ -40,8 +40,20 @@ func MarshalJsonApiManyPayload(models Models) (*JsonApiManyPayload, error) {
}, nil
}
func MarshalJsonApiOnePayloadEmbedded(model interface{}) (*JsonApiOnePayload, error) {
rootNode, _, err := visitModelNode(model, false)
if err != nil {
return nil, err
}
resp := &JsonApiOnePayload{Data: rootNode}
return resp, nil
}
func MarshalJsonApiOnePayload(model interface{}) (*JsonApiOnePayload, error) {
rootNode, included, err := visitModelNode(model)
rootNode, included, err := visitModelNode(model, true)
if err != nil {
return nil, err
}
@ -64,7 +76,7 @@ func MarshalJsonApiOnePayload(model interface{}) (*JsonApiOnePayload, error) {
return resp, nil
}
func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
func visitModelNode(model interface{}, sideload bool) (*JsonApiNode, []*JsonApiNode, error) {
node := new(JsonApiNode)
var er error
@ -82,6 +94,10 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
tag := structField.Tag.Get("jsonapi")
if tag == "" {
return false
}
args := strings.Split(tag, ",")
if len(args) != 2 {
@ -134,10 +150,11 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
}
if isSlice {
relationship, err := visitModelNodeRelationships(args[1], fieldValue)
relationship, err := visitModelNodeRelationships(args[1], fieldValue, sideload)
d := relationship[args[1]].Data
if err == nil {
if sideload {
shallowNodes := make([]*JsonApiNode, 0)
for _, node := range d {
included = append(included, node)
@ -149,19 +166,26 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
}
node.Relationships[args[1]] = &JsonApiRelationshipManyNode{Data: shallowNodes}
} else {
node.Relationships[args[1]] = &JsonApiRelationshipManyNode{Data: d}
}
} else {
er = err
return false
}
} else {
relationship, _, err := visitModelNode(fieldValue.Interface())
relationship, _, err := visitModelNode(fieldValue.Interface(), sideload)
if err == nil {
if sideload {
shallowNode := *relationship
shallowNode.Attributes = nil
included = append(included, relationship)
node.Relationships[args[1]] = &JsonApiRelationshipOneNode{Data: &shallowNode}
} else {
node.Relationships[args[1]] = &JsonApiRelationshipOneNode{Data: relationship}
}
} else {
er = err
return false
@ -184,12 +208,12 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
return node, included, nil
}
func visitModelNodeRelationships(relationName string, models reflect.Value) (map[string]*JsonApiRelationshipManyNode, error) {
func visitModelNodeRelationships(relationName string, models reflect.Value, sideload bool) (map[string]*JsonApiRelationshipManyNode, error) {
m := make(map[string]*JsonApiRelationshipManyNode)
nodes := make([]*JsonApiNode, 0)
for i := 0; i < models.Len(); i++ {
node, _, err := visitModelNode(models.Index(i).Interface())
node, _, err := visitModelNode(models.Index(i).Interface(), sideload)
if err != nil {
return nil, err
}