Skip to content

Commit

Permalink
Merge pull request #83 from bbuck/coerceInt_fix
Browse files Browse the repository at this point in the history
Add other integer values to the coerceInt function
  • Loading branch information
chris-ramon committed Dec 15, 2015
2 parents d594ffe + 7d159a0 commit 285e047
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 20 deletions.
2 changes: 1 addition & 1 deletion definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ func (gt *Enum) Name() string {
return gt.PrivateName
}
func (gt *Enum) Description() string {
return ""
return gt.PrivateDescription
}
func (gt *Enum) String() string {
return gt.PrivateName
Expand Down
63 changes: 45 additions & 18 deletions scalars.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,72 @@ package graphql

import (
"fmt"
"math"
"strconv"

"github.com/graphql-go/graphql/language/ast"
)

var (
MaxInt = 9007199254740991
MinInt = -9007199254740991
)

func coerceInt(value interface{}) interface{} {
switch value := value.(type) {
case bool:
if value == true {
return int(1)
return 1
}
return int(0)
return 0
case int:
return value
case int8:
return int(value)
case int16:
return int(value)
case int32:
return int(value)
case int64:
if value < int64(math.MinInt32) || value > int64(math.MaxInt32) {
return nil
}
return int(value)
case uint:
return int(value)
case uint8:
return int(value)
case uint16:
return int(value)
case uint32:
if value > uint32(math.MaxInt32) {
return nil
}
return int(value)
case uint64:
if value > uint64(math.MaxInt32) {
return nil
}
return int(value)
case float32:
return intOrNil(int(value))
if value < float32(math.MinInt32) || value > float32(math.MaxInt32) {
return nil
}
return int(value)
case float64:
return intOrNil(int(value))
if value < float64(math.MinInt32) || value > float64(math.MaxInt32) {
return nil
}
return int(value)
case string:
val, err := strconv.ParseFloat(value, 0)
if err != nil {
return nil
}
return coerceInt(val)
}
return int(0)
}

// Integers are only safe when between -(2^53 - 1) and 2^53 - 1 due to being
// encoded in JavaScript and represented in JSON as double-precision floating
// point numbers, as specified by IEEE 754.
func intOrNil(value int) interface{} {
if value <= MaxInt && value >= MinInt {
return value
}
// If the value cannot be transformed into an int, return nil instead of '0'
// to denote 'no integer found'
return nil
}

// Int is the GraphQL Integer type definition.
var Int *Scalar = NewScalar(ScalarConfig{
Name: "Int",
Serialize: coerceInt,
Expand Down Expand Up @@ -83,6 +106,7 @@ func coerceFloat32(value interface{}) interface{} {
return float32(0)
}

// Float is the GraphQL float type definition.
var Float *Scalar = NewScalar(ScalarConfig{
Name: "Float",
Serialize: coerceFloat32,
Expand All @@ -106,6 +130,7 @@ func coerceString(value interface{}) interface{} {
return fmt.Sprintf("%v", value)
}

// String is the GraphQL string type definition
var String *Scalar = NewScalar(ScalarConfig{
Name: "String",
Serialize: coerceString,
Expand Down Expand Up @@ -148,6 +173,7 @@ func coerceBool(value interface{}) interface{} {
return false
}

// Boolean is the GraphQL boolean type definition
var Boolean *Scalar = NewScalar(ScalarConfig{
Name: "Boolean",
Serialize: coerceBool,
Expand All @@ -161,6 +187,7 @@ var Boolean *Scalar = NewScalar(ScalarConfig{
},
})

// ID is the GraphQL id type definition
var ID *Scalar = NewScalar(ScalarConfig{
Name: "ID",
Serialize: coerceString,
Expand Down
23 changes: 22 additions & 1 deletion scalars_serialization_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphql_test

import (
"math"
"reflect"
"testing"

Expand Down Expand Up @@ -34,7 +35,9 @@ func TestTypeSystem_Scalar_SerializesOutputInt(t *testing.T) {
{float32(0.1), 0},
{float32(1.1), 1},
{float32(-1.1), -1},
{float32(1e5), 100000}, // Bigger than 2^32, but still representable as an Int
// Bigger than 2^32, but still representable as an Int
{float32(1e5), 100000},
{float32(math.MaxFloat32), nil},
{9876504321, 9876504321},
{-9876504321, -9876504321},
{float64(1e100), nil},
Expand All @@ -43,6 +46,24 @@ func TestTypeSystem_Scalar_SerializesOutputInt(t *testing.T) {
{"one", nil},
{false, 0},
{true, 1},
{int8(1), 1},
{int16(1), 1},
{int32(1), 1},
{int64(1), 1},
{uint(1), 1},
{uint8(1), 1},
{uint16(1), 1},
{uint32(1), 1},
{uint32(math.MaxUint32), nil},
{uint64(1), 1},
{uint64(math.MaxInt32), math.MaxInt32},
{int64(math.MaxInt32) + int64(1), nil},
{int64(math.MinInt32) - int64(1), nil},
{uint64(math.MaxInt64) + uint64(1), nil},
{byte(127), 127},
{'世', int('世')},
// testing types that don't match a value in the array.
{[]int{}, nil},
}

for _, test := range tests {
Expand Down

0 comments on commit 285e047

Please sign in to comment.