Skip to content

Commit

Permalink
Add support for ToBool for json fragments, deal with escaped strings
Browse files Browse the repository at this point in the history
  • Loading branch information
nicpottier committed Jun 12, 2017
1 parent 7f6ddb6 commit 1ce62e5
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 5 deletions.
35 changes: 33 additions & 2 deletions utils/conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,41 @@ func ToBool(env Environment, test interface{}) (bool, error) {
return !test.IsZero(), nil

case string:
return test != "", nil
return test != "" && strings.ToLower(test) != "false", nil

case JSONFragment:
asString, err := ToString(env, test)
if err != nil {
return false, err
}
// is this a number?
num, err := ToDecimal(env, asString)
if err == nil {
return !num.Equals(decimal.Zero), nil
}

noWhite := strings.Join(strings.Fields(asString), "")

// empty array?
if noWhite == "[]" {
return false, nil
}

// empty dict
if noWhite == "{}" {
return false, nil
}

// finally just string version
return asString != "" && strings.ToLower(asString) != "false", nil
}

asString, err := ToString(env, test)
if err != nil {
return false, err
}

return false, fmt.Errorf("ToBool unknown type '%s' with value '%+v'", reflect.TypeOf(test), test)
return ToBool(env, asString)
}

// XType is an an enumeration of the possible types we can deal with
Expand Down
51 changes: 51 additions & 0 deletions utils/conversions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,57 @@ func TestToDecimal(t *testing.T) {
}
}

func TestToBool(t *testing.T) {
testResolver := &resolver{"155"}

var tests = []struct {
input interface{}
expected bool
hasError bool
}{
{nil, false, false},
{fmt.Errorf("Error"), false, true},
{decimal.NewFromFloat(42), true, false},
{int(0), false, false},
{int(15), true, false},
{int32(15), true, false},
{int64(15), true, false},
{float32(15.5), true, false},
{float64(15.5), true, false},
{"15.5", true, false},
{"lO.5", true, false},
{"", false, false},
{testResolver, true, false},
{NewJSONFragment([]byte(`false`)), false, false},
{NewJSONFragment([]byte(`true`)), true, false},
{NewJSONFragment([]byte(`[]`)), false, false},
{NewJSONFragment([]byte(`15.5`)), true, false},
{NewJSONFragment([]byte(`0`)), false, false},
{NewJSONFragment([]byte(`[5]`)), true, false},
{NewJSONFragment([]byte("{\n}")), false, false},
{NewJSONFragment([]byte(`{"one": "two"}`)), true, false},
{struct{}{}, false, true},
}

env := NewDefaultEnvironment()

for _, test := range tests {
result, err := ToBool(env, test.input)

if err != nil && !test.hasError {
t.Errorf("Unexpected error calling ToBool on '%v': %s", test.input, err)
}

if err == nil && test.hasError {
t.Errorf("Did not receive expected error calling ToBool on '%v': %s", test.input, err)
}

if result != test.expected {
t.Errorf("Unexpected result calling ToBool on '%v', got: %s expected: %s", test.input, result, test.expected)
}
}
}

func TestToJSON(t *testing.T) {
strMap := make(map[string]string)
strMap["one"] = "1.0"
Expand Down
21 changes: 18 additions & 3 deletions utils/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,30 @@ func (j JSONFragment) Resolve(key string) interface{} {
// this is a numerical index, convert to jsonparser format
if err == nil {
jIdx := "[" + key + "]"
val, _, _, err := jsonparser.Get(j.json, jIdx)
val, valType, _, err := jsonparser.Get(j.json, jIdx)
if err == nil {
return JSONFragment{val}
if err == nil {
if valType == jsonparser.String {
strVal, err := jsonparser.ParseString(val)
if err == nil {
return strVal
}
}
return JSONFragment{val}
}
}
}
val, _, _, err := jsonparser.Get(j.json, key)
val, valType, _, err := jsonparser.Get(j.json, key)
if err != nil {
return err
}

if valType == jsonparser.String {
strVal, err := jsonparser.ParseString(val)
if err == nil {
return strVal
}
}
return JSONFragment{val}
}

Expand Down
1 change: 1 addition & 0 deletions utils/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func TestJSON(t *testing.T) {
{nil, "key", ""},
{[]byte(`malformed`), "key", ""},
{[]byte(`["one", "two", "three"]`), "0", "one"},
{[]byte(`["escaped \"string\""]`), "0", `escaped "string"`},
{[]byte(`{"1": "one"}`), "1", "one"},
{[]byte(`{"arr": ["one", "two"]}`), "arr[1]", "two"},
{[]byte(`{"arr": ["one", "two"]}`), "arr.1", "two"},
Expand Down

0 comments on commit 1ce62e5

Please sign in to comment.