github.com/instill-ai/component@v0.16.0-beta/pkg/operator/json/v0/operator_test.go (about) 1 package json 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "testing" 7 8 qt "github.com/frankban/quicktest" 9 "go.uber.org/zap" 10 "google.golang.org/protobuf/types/known/structpb" 11 12 "github.com/instill-ai/x/errmsg" 13 ) 14 15 const asJSON = ` 16 { 17 "a": "27", 18 "b": 27 19 }` 20 21 var asMap = map[string]any{"a": "27", "b": 27} 22 23 func TestOperator_Execute(t *testing.T) { 24 c := qt.New(t) 25 26 testcases := []struct { 27 name string 28 29 task string 30 in map[string]any 31 want map[string]any 32 wantErr string 33 34 // The marshal task will return a string with a valid JSON in the 35 // output. However, the format of the JSON may vary (e.g. spaces), so 36 // this field will be used to do a JSON comparison instead of a value 37 // one. 38 wantJSON json.RawMessage 39 }{ 40 { 41 name: "ok - marshal", 42 43 task: taskMarshal, 44 in: map[string]any{"json": asMap}, 45 wantJSON: json.RawMessage(asJSON), 46 }, 47 { 48 name: "nok - marshal", 49 50 task: taskMarshal, 51 in: map[string]any{}, 52 wantErr: "Couldn't convert the provided object to JSON.", 53 }, 54 { 55 name: "ok - unmarshal", 56 57 task: taskUnmarshal, 58 in: map[string]any{"string": asJSON}, 59 want: map[string]any{"json": asMap}, 60 }, 61 { 62 name: "nok - unmarshal", 63 64 task: taskUnmarshal, 65 in: map[string]any{"string": `{`}, 66 wantErr: "Couldn't parse the JSON string. Please check the syntax is correct.", 67 }, 68 { 69 name: "ok - jq", 70 71 task: taskJQ, 72 in: map[string]any{ 73 "jsonInput": `{"a": {"b": 42}}`, 74 "jqFilter": ".a | .[]", 75 }, 76 want: map[string]any{ 77 "results": []any{42}, 78 }, 79 }, 80 { 81 name: "ok - jq create object", 82 83 task: taskJQ, 84 in: map[string]any{ 85 "jsonInput": `{"id": "sample", "10": {"b": 42}}`, 86 "jqFilter": `{(.id): .["10"].b}`, 87 }, 88 want: map[string]any{ 89 "results": []any{ 90 map[string]any{"sample": 42}, 91 }, 92 }, 93 }, 94 { 95 name: "nok - jq invalid JSON input", 96 97 task: taskJQ, 98 in: map[string]any{ 99 "jsonInput": "{", 100 "jqFilter": ".", 101 }, 102 wantErr: "Couldn't parse the JSON input. Please check the syntax is correct.", 103 }, 104 { 105 name: "nok - jq invalid filter", 106 107 task: taskJQ, 108 in: map[string]any{ 109 "jsonInput": asJSON, 110 "jqFilter": ".foo & .bar", 111 }, 112 wantErr: `Couldn't parse the jq filter: unexpected token "&". Please check the syntax is correct.`, 113 }, 114 } 115 116 logger := zap.NewNop() 117 operator := Init(logger, nil) 118 119 for _, tc := range testcases { 120 c.Run(tc.name, func(c *qt.C) { 121 exec, err := operator.CreateExecution(nil, tc.task) 122 c.Assert(err, qt.IsNil) 123 124 pbIn, err := structpb.NewStruct(tc.in) 125 c.Assert(err, qt.IsNil) 126 127 got, err := exec.Execution.Execute([]*structpb.Struct{pbIn}) 128 if tc.wantErr != "" { 129 c.Check(errmsg.Message(err), qt.Matches, tc.wantErr) 130 return 131 } 132 133 c.Check(err, qt.IsNil) 134 c.Assert(got, qt.HasLen, 1) 135 136 if tc.wantJSON != nil { 137 // Check JSON in the output string. 138 b := got[0].Fields["string"].GetStringValue() 139 c.Check([]byte(b), qt.JSONEquals, tc.wantJSON) 140 return 141 } 142 143 gotJSON, err := got[0].MarshalJSON() 144 c.Assert(err, qt.IsNil) 145 c.Check(gotJSON, qt.JSONEquals, tc.want) 146 }) 147 } 148 } 149 150 func TestOperator_CreateExecution(t *testing.T) { 151 c := qt.New(t) 152 153 logger := zap.NewNop() 154 operator := Init(logger, nil) 155 156 c.Run("nok - unsupported task", func(c *qt.C) { 157 task := "FOOBAR" 158 want := fmt.Sprintf("%s task is not supported.", task) 159 160 _, err := operator.CreateExecution(nil, task) 161 c.Check(err, qt.IsNotNil) 162 c.Check(errmsg.Message(err), qt.Equals, want) 163 }) 164 }