From f900f98050bbdfbdbf4ef5ce3c839f78ab929cf5 Mon Sep 17 00:00:00 2001 From: k2tzumi Date: Thu, 11 Aug 2022 15:10:00 +0900 Subject: [PATCH 1/2] refs https://github.com/k1LoW/runn/pull/90#issuecomment-1207325344, vars: section supports schemes to read external files such as `json://` --- option.go | 6 +++++- testdata/vars.json | 4 ++++ vars.go | 32 ++++++++++++++++++++++++++++++++ vars_test.go | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 testdata/vars.json create mode 100644 vars.go create mode 100644 vars_test.go diff --git a/option.go b/option.go index e80fd189..84dc2634 100644 --- a/option.go +++ b/option.go @@ -49,7 +49,11 @@ func Book(path string) Option { } } for k, v := range loaded.Vars { - bk.Vars[k] = v + ev, err := evaluateSchema(v) + if err != nil { + return err + } + bk.Vars[k] = ev } bk.Steps = loaded.Steps bk.stepKeys = loaded.stepKeys diff --git a/testdata/vars.json b/testdata/vars.json new file mode 100644 index 00000000..21b6ae2b --- /dev/null +++ b/testdata/vars.json @@ -0,0 +1,4 @@ +{ + "foo": "test", + "bar": 1 +} \ No newline at end of file diff --git a/vars.go b/vars.go new file mode 100644 index 00000000..4dee644a --- /dev/null +++ b/vars.go @@ -0,0 +1,32 @@ +package runn + +import ( + "fmt" + "os" + "strings" + + "github.com/goccy/go-json" +) + +const varsSupportScheme string = "json://" + +func evaluateSchema(value interface{}) (interface{}, error) { + switch v := value.(type) { + case string: + if strings.HasPrefix(v, varsSupportScheme) { + byteArray, err := os.ReadFile(v[len(varsSupportScheme):]) + if err != nil { + return value, fmt.Errorf("read external files error: %w", err) + + } + var jsonObj interface{} + if err := json.Unmarshal(byteArray, &jsonObj); err != nil { + return value, fmt.Errorf("unmarshal error: %w", err) + } + + return jsonObj, nil + } + } + + return value, nil +} diff --git a/vars_test.go b/vars_test.go new file mode 100644 index 00000000..dd5c7310 --- /dev/null +++ b/vars_test.go @@ -0,0 +1,35 @@ +package runn + +import ( + "os" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEvaluateSchema(t *testing.T) { + brokenJson, _ := os.CreateTemp("", "broken_json") + defer os.Remove(brokenJson.Name()) + + tests := []struct { + value interface{} + want interface{} + error bool + }{ + {1, 1, false}, + {[]string{"1"}, []string{"1"}, false}, + {"string", "string", false}, + {"json://testdata/vars.json", map[string]interface{}{"foo": "test", "bar": float64(1)}, false}, + {"json://not_exists.json", "json://not_exists.json", true}, + {"json://" + brokenJson.Name(), "json://" + brokenJson.Name(), true}, + } + for _, tt := range tests { + got, err := evaluateSchema(tt.value) + if diff := cmp.Diff(got, tt.want, nil); diff != "" { + t.Errorf("%s", diff) + } + if (tt.error && err == nil) || (!tt.error && err != nil) { + t.Errorf("no much error") + } + } +} From 4acccf0546becf939ddcb03106cbab0eff4126d7 Mon Sep 17 00:00:00 2001 From: k2tzumi Date: Thu, 11 Aug 2022 16:57:58 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8=20Support=20for=20read=20json=20i?= =?UTF-8?q?n=20Var=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- operator_test.go | 8 ++++++++ option.go | 6 +++++- testdata/book/vars_external.yml | 23 +++++++++++++++++++++++ testdata/vars_array.json | 10 ++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 testdata/book/vars_external.yml create mode 100644 testdata/vars_array.json diff --git a/operator_test.go b/operator_test.go index d53ae054..63ca4517 100644 --- a/operator_test.go +++ b/operator_test.go @@ -447,6 +447,14 @@ func TestVars(t *testing.T) { []Option{Book("testdata/book/vars.yml")}, true, }, + { + []Option{Book("testdata/book/vars_external.yml"), Var("override", "json://testdata/vars.json")}, + false, + }, + { + []Option{Book("testdata/book/vars_external.yml")}, + true, + }, } ctx := context.Background() for _, tt := range tests { diff --git a/option.go b/option.go index 84dc2634..49bc360b 100644 --- a/option.go +++ b/option.go @@ -254,7 +254,11 @@ func T(t *testing.T) Option { // Var - Set variable to runner func Var(k string, v interface{}) Option { return func(bk *book) error { - bk.Vars[k] = v + ev, err := evaluateSchema(v) + if err != nil { + return err + } + bk.Vars[k] = ev return nil } } diff --git a/testdata/book/vars_external.yml b/testdata/book/vars_external.yml new file mode 100644 index 00000000..5edb9bc9 --- /dev/null +++ b/testdata/book/vars_external.yml @@ -0,0 +1,23 @@ +desc: external vars +vars: + external: json://testdata/vars.json + nonEvaluate: + value: json://testdata/vars.json + tabular: json://testdata/vars_array.json + override: + foo: "test2" + bar: 2 +steps: + evaluate: + test: | + vars.external.foo == "test" && + vars.external.bar == 1 + nonEvaluate: + test: | + vars.nonEvaluate.value == "json://testdata/vars.json" + tabular: + test: | + vars.tabular[1].bar == 2 + override: + test: | + vars.override == vars.external diff --git a/testdata/vars_array.json b/testdata/vars_array.json new file mode 100644 index 00000000..9a76d41e --- /dev/null +++ b/testdata/vars_array.json @@ -0,0 +1,10 @@ +[ + { + "foo": "test1", + "bar": 1 + }, + { + "foo": "test2", + "bar": 2 + } +] \ No newline at end of file