Skip to content

Commit

Permalink
Merge pull request #135 from hairyhenderson/fix-nested-map-bugs-134
Browse files Browse the repository at this point in the history
Fixing bug with 'has' and 'datasource' around referencing sub-maps in nested maps
  • Loading branch information
hairyhenderson authored May 6, 2017
2 parents 582a78b + f358f18 commit b895176
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 20 deletions.
8 changes: 4 additions & 4 deletions data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ func TestDatasource(t *testing.T) {
data := &Data{
Sources: sources,
}
expected := map[string]interface{}{"hello": "world"}
expected := map[string]interface{}{"hello": map[interface{}]interface{}{"cruel": "world"}}
actual := data.Datasource("foo")
assert.Equal(t, expected["hello"], actual["hello"])
assert.Equal(t, expected, actual)
}

test("json", "application/json", `{"hello":"world"}`)
test("yml", "application/yaml", `hello: world`)
test("json", "application/json", `{"hello":{"cruel":"world"}}`)
test("yml", "application/yaml", "hello:\n cruel: world\n")
}

func TestDatasourceExists(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions gomplate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ func TestHasTemplate(t *testing.T) {
"has": ty.Has,
},
}
assert.Equal(t, "true", testTemplate(g, `{{has ("foo: true" | yaml) "foo"}}`))
assert.Equal(t, "false", testTemplate(g, `{{has ("foo: true" | yaml) "bar"}}`))
assert.Equal(t, "true", testTemplate(g, `{{has ("foo:\n bar: true" | yaml) "foo"}}`))
assert.Equal(t, "true", testTemplate(g, `{{has ("foo:\n bar: true" | yaml).foo "bar"}}`))
assert.Equal(t, "false", testTemplate(g, `{{has ("foo: true" | yaml) "bah"}}`))
tmpl := `{{- $data := yaml "foo: bar\nbaz: qux\n" }}
{{- if (has $data "baz") }}
{{- $data.baz }}
Expand Down
12 changes: 6 additions & 6 deletions test/integration/datasources_file.bats
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ function teardown () {
}

@test "supports json datasource file" {
echo '{"foo": "bar"}' > $tmpdir/config.json
gomplate -d config=$tmpdir/config.json -i '{{(datasource "config").foo}}'
echo '{"foo": {"bar": "baz"}}' > $tmpdir/config.json
gomplate -d config=$tmpdir/config.json -i '{{(datasource "config").foo.bar}}'
[ "$status" -eq 0 ]
[[ "${output}" == "bar" ]]
[[ "${output}" == "baz" ]]
}

@test "supports YAML datasource file" {
echo 'foo: bar' > $tmpdir/config.yml
gomplate -d config=$tmpdir/config.yml -i '{{(datasource "config").foo}}'
echo -e 'foo:\n bar: baz' > $tmpdir/config.yml
gomplate -d config=$tmpdir/config.yml -i '{{(datasource "config").foo.bar}}'
[ "$status" -eq 0 ]
[[ "${output}" == "bar" ]]
[[ "${output}" == "baz" ]]
}

@test "ds alias" {
Expand Down
19 changes: 19 additions & 0 deletions test/integration/typeconv_funcs.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bats

load helper

tmpdir=$(mktemp -u)

function setup () {
mkdir -p $tmpdir
}

function teardown () {
rm -rf $tmpdir || true
}

@test "'has' can handle sub-maps in nested maps" {
gomplate -d config=$tmpdir/config.yml -i '{{ has ("foo:\n bar:\n baz: qux" | yaml).foo.bar "baz"}}'
[ "$status" -eq 0 ]
[[ "${output}" == "true" ]]
}
17 changes: 12 additions & 5 deletions typeconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"log"
"reflect"
"strconv"
"strings"

Expand Down Expand Up @@ -43,13 +44,13 @@ func unmarshalArray(obj []interface{}, in string, f func([]byte, interface{}) er
// JSON - Unmarshal a JSON Object
func (t *TypeConv) JSON(in string) map[string]interface{} {
obj := make(map[string]interface{})
return unmarshalObj(obj, in, json.Unmarshal)
return unmarshalObj(obj, in, yaml.Unmarshal)
}

// JSONArray - Unmarshal a JSON Array
func (t *TypeConv) JSONArray(in string) []interface{} {
obj := make([]interface{}, 1)
return unmarshalArray(obj, in, json.Unmarshal)
return unmarshalArray(obj, in, yaml.Unmarshal)
}

// YAML - Unmarshal a YAML Object
Expand Down Expand Up @@ -102,9 +103,15 @@ func (t *TypeConv) Join(a []interface{}, sep string) string {
}

// Has determines whether or not a given object has a property with the given key
func (t *TypeConv) Has(in map[string]interface{}, key string) bool {
_, ok := in[key]
return ok
func (t *TypeConv) Has(in interface{}, key string) bool {
av := reflect.ValueOf(in)
kv := reflect.ValueOf(key)

if av.Kind() == reflect.Map {
return av.MapIndex(kv).IsValid()
}

return false
}

func toString(in interface{}) string {
Expand Down
11 changes: 8 additions & 3 deletions typeconv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestBool(t *testing.T) {
func TestUnmarshalObj(t *testing.T) {
ty := new(TypeConv)
expected := map[string]interface{}{
"foo": "bar",
"foo": map[interface{}]interface{}{"bar": "baz"},
"one": 1.0,
"true": true,
}
Expand All @@ -37,8 +37,9 @@ func TestUnmarshalObj(t *testing.T) {
assert.Equal(t, expected["one"], actual["one"])
assert.Equal(t, expected["true"], actual["true"])
}
test(ty.JSON(`{"foo":"bar","one":1.0,"true":true}`))
test(ty.YAML(`foo: bar
test(ty.JSON(`{"foo":{"bar":"baz"},"one":1.0,"true":true}`))
test(ty.YAML(`foo:
bar: baz
one: 1.0
true: true
`))
Expand Down Expand Up @@ -130,8 +131,12 @@ func TestHas(t *testing.T) {

in := map[string]interface{}{
"foo": "bar",
"baz": map[string]interface{}{
"qux": "quux",
},
}

assert.True(t, ty.Has(in, "foo"))
assert.False(t, ty.Has(in, "bar"))
assert.True(t, ty.Has(in["baz"], "qux"))
}

0 comments on commit b895176

Please sign in to comment.