From 08749fe2b8443220d3bbdb78a0959ad4edb87568 Mon Sep 17 00:00:00 2001 From: Asterism12 Date: Fri, 26 Jan 2024 16:33:40 +0800 Subject: [PATCH] add mode 'literal' in plugin 'switch'; add tests of plugin. --- plugins/get.go | 34 ++++++++++++----- tests/plugins_test.go | 89 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 tests/plugins_test.go diff --git a/plugins/get.go b/plugins/get.go index ca4e7a8..53c44e6 100644 --- a/plugins/get.go +++ b/plugins/get.go @@ -149,9 +149,10 @@ func (g getPluginRoot) Name() string { } const ( - Case = "case" - ModeString = "string" - ModeDeep = "deep" + Case = "case" + ModeString = "string" + ModeLiteral = "literal" + ModeDeep = "deep" ) type getPluginSwitch struct { @@ -162,15 +163,17 @@ func (g getPluginSwitch) Exec(s *base.Setter, root, data any, expression []strin param = param[0].([]any) mode, ok := param[0].(string) if !ok { - return g.switchByString(s, root, data, value, param) + return g.switchByLiteral(value, param) } switch mode { case ModeDeep: return g.switchByDeep(s, root, data, value, param[1:]) case ModeString: return g.switchByString(s, root, data, value, param[1:]) + case ModeLiteral: + return g.switchByLiteral(value, param[1:]) default: - return g.switchByString(s, root, data, value, param[1:]) + return g.switchByLiteral(value, param[1:]) } } @@ -188,6 +191,20 @@ func (g getPluginSwitch) switchByString(s *base.Setter, root, data, value any, p return nil } +func (g getPluginSwitch) switchByLiteral(value any, param []any) any { + cases := param[0].(map[string]any) + valueAsString := g.getAsString(value) + for c, literal := range cases { + if c == valueAsString { + return literal + } + } + if len(param) == 2 { + return param[1] + } + return nil +} + func (g getPluginSwitch) getAsString(v any) string { switch v := v.(type) { case string: @@ -207,7 +224,7 @@ func (g getPluginSwitch) bytesToString(bys []byte) string { } func (g getPluginSwitch) switchByDeep(s *base.Setter, root, data, value any, param []any) any { - for _, c := range param { + for _, c := range param[0].([]any) { c := c.(map[string]any) if caseValue, ok := c[Case]; ok { if base.DeepEqual(value, caseValue) { @@ -215,9 +232,8 @@ func (g getPluginSwitch) switchByDeep(s *base.Setter, root, data, value any, par } } } - c := param[len(param)-1].(map[string]any) - if _, ok := c[Case]; !ok { - return g.getValue(s, root, data, c) + if len(param) == 2 { + return g.getValue(s, root, data, param[1].(map[string]any)) } return nil } diff --git a/tests/plugins_test.go b/tests/plugins_test.go new file mode 100644 index 0000000..e3ed043 --- /dev/null +++ b/tests/plugins_test.go @@ -0,0 +1,89 @@ +package tests + +import ( + "encoding/json" + "fmt" + "github.com/Asterism12/many" + "github.com/Asterism12/many/base" + "testing" +) + +func mustUnmarshal(s string) any { + var v any + err := json.Unmarshal([]byte(s), &v) + if err != nil { + panic(fmt.Errorf("json err %w", err)) + } + return v +} + +func TestSwitch(t *testing.T) { + type args struct { + data string + expression string + } + tests := []struct { + name string + args args + want any + verifyErr bool + }{ + { + name: "literal-standard", + args: args{ + data: `{"type":"apple"}`, + expression: `["#switch.type",["literal",{"apple":"fruit","tomato":"vegetable"},"no_idea"]]`, + }, + want: "fruit", + }, + { + name: "literal-omit-parameter-default", + args: args{ + data: `{"type":"meat"}`, + expression: `["#switch.type",[{"apple":"fruit","tomato":"vegetable"},"no_idea"]]`, + }, + want: "no_idea", + }, + { + name: "string-standard", + args: args{ + data: `{"type":"apple","word":{"vegetable":"good","fruit":"better"}}`, + expression: `["#switch.type",["string",{"apple":"word.fruit","tomato":"word.vegetable"},"no_idea"]]`, + }, + want: "better", + }, + { + name: "deep-standard", + args: args{ + data: `{"type":"apple","word":{"vegetable":"good","fruit":"better"}}`, + expression: `["#switch.type",["deep",[{"case":"apple","router":"word.fruit"}]]]`, + }, + want: "better", + }, + { + name: "deep-default", + args: args{ + data: `{"type":"meat"}`, + expression: `["#switch.type",["deep",[{"case":"apple","router":"word.fruit"}],{"literal":"no_idea"}]]`, + }, + want: "no_idea", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + data := mustUnmarshal(tt.args.data) + expression := mustUnmarshal(tt.args.expression) + m := many.New() + if err := m.Verify([]map[string]any{{"res": expression}}); (err != nil) != tt.verifyErr { + t.Errorf("Verify() = %v, want %v", err, tt.verifyErr) + } + if !tt.verifyErr { + if got := m.Get(data, data, expression); !base.DeepEqual(got, tt.want) { + t.Errorf("Get() = %v, want %v", got, tt.want) + } else { + fmt.Println(got, tt.want) + } + } + }) + } +}