From 394a5d3f54e62035ce8cabaae2d4c63b9b227be0 Mon Sep 17 00:00:00 2001 From: Mario Lopez Gallego Date: Wed, 28 Apr 2021 09:55:04 +0200 Subject: [PATCH] feat: accept context conf arrays (#26) * feat: accept context conf arrays * fix: add extra line --- map.go | 3 ++ table.go | 46 +++++++++++++++++++ test/acceptance/environments/local.yml | 5 ++ .../acceptance/features/elasticsearch.feature | 2 +- 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/map.go b/map.go index 55bb6e51..becc8116 100755 --- a/map.go +++ b/map.go @@ -61,6 +61,9 @@ func (m *gjsonMap) Get(path string) interface{} { case gjson.Number: return result.Float() default: + if result.IsArray() { + return result.Array() + } return result.String() } } diff --git a/table.go b/table.go index 54e14e92..2cac8772 100755 --- a/table.go +++ b/table.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/cucumber/godog" + "github.com/tidwall/gjson" ) // ConvertTableToMap converts a godog table with 2 columns into a map[string]interface{}. @@ -142,6 +143,8 @@ func ConvertTableWithHeaderToStructSlice(ctx context.Context, t *godog.Table, sl // }) // It will be equivalent to: // testElement := TestElement{Name: "example 1", Value: 1} +// Warning: still pending process values directly as arrays, i.e.: | addresses | ["http://localhost:8080"] | +// use by now a CONF tag, i.e.: | addresses | [CONF:elasticsearch.addresses] | func ConvertTableWithoutHeaderToStruct(ctx context.Context, t *godog.Table, v interface{}) error { if len(t.Rows) == 0 { return nil @@ -189,6 +192,22 @@ func assignFieldInStruct(value reflect.Value, fieldName string, fieldValue inter f = fv.Elem() } fieldValueStr := fmt.Sprintf("%v", fieldValue) + if f.Kind() == reflect.Slice { + array, ok := fieldValue.([]gjson.Result) + if !ok { + return fmt.Errorf("failed setting the field '%s' with value '%s', not an array/slice", fieldName, fieldValueStr) + } + length := len(array) + var fv reflect.Value + if length > 0 { + fv = makeSlice(array[0], length) + for i, v := range array { + setSliceValue(fv.Index(i), v) + } + } + f.Set(fv) + return nil + } if f.Kind() == reflect.String { f.SetString(fieldValueStr) return nil @@ -235,3 +254,30 @@ func assignFieldInStruct(value reflect.Value, fieldName string, fieldValue inter } return nil } + +func makeSlice(element gjson.Result, length int) reflect.Value { + var rv reflect.Value + switch element.Type { + case gjson.False, gjson.True: + var b bool + rv = reflect.ValueOf(b) + case gjson.Number: + var i int + rv = reflect.ValueOf(i) + case gjson.String, gjson.JSON, gjson.Null: + var s string + rv = reflect.ValueOf(s) + } + return reflect.MakeSlice(reflect.SliceOf(rv.Type()), length, length) +} + +func setSliceValue(field reflect.Value, value gjson.Result) { + switch value.Type { + case gjson.False, gjson.True: + field.Set(reflect.ValueOf(value.Bool())) + case gjson.Number: + field.Set(reflect.ValueOf(value.Int())) + case gjson.String, gjson.JSON, gjson.Null: + field.Set(reflect.ValueOf(value.String())) + } +} diff --git a/test/acceptance/environments/local.yml b/test/acceptance/environments/local.yml index 94e5ba4c..ce0440a8 100755 --- a/test/acceptance/environments/local.yml +++ b/test/acceptance/environments/local.yml @@ -96,3 +96,8 @@ signPublicKey: | # HTTP mock settings httpMockUrl: http://localhost:9000 + +# elasticsearch settings +elasticsearch: + addresses: + - http://localhost:9200 diff --git a/test/acceptance/features/elasticsearch.feature b/test/acceptance/features/elasticsearch.feature index 0609a028..5f0c9d35 100755 --- a/test/acceptance/features/elasticsearch.feature +++ b/test/acceptance/features/elasticsearch.feature @@ -3,7 +3,7 @@ Feature: Elasticsearch client @elasticsearch Scenario: Create and search a document Given the elasticsearch server - | addresses | [ http://localhost:9200 ] | + | addresses | [CONF:elasticsearch.addresses] | When I create the elasticsearch document with index "example" and the JSON properties | name | example | | number | [NUMBER:1] |