github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/json/json_keys_test.go (about)

     1  // Copyright 2023 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package json
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/require"
    23  	"gopkg.in/src-d/go-errors.v1"
    24  
    25  	"github.com/dolthub/go-mysql-server/sql"
    26  	"github.com/dolthub/go-mysql-server/sql/types"
    27  )
    28  
    29  func TestJSONKeys(t *testing.T) {
    30  	_, err := NewJSONKeys()
    31  	require.True(t, errors.Is(err, sql.ErrInvalidArgumentNumber))
    32  
    33  	f1 := buildGetFieldExpressions(t, NewJSONKeys, 1)
    34  	f2 := buildGetFieldExpressions(t, NewJSONKeys, 2)
    35  
    36  	testCases := []struct {
    37  		f   sql.Expression
    38  		row sql.Row
    39  		exp interface{}
    40  		err bool
    41  	}{
    42  		{
    43  			f:   f1,
    44  			row: sql.Row{nil},
    45  			exp: nil,
    46  		},
    47  		{
    48  			f:   f1,
    49  			row: sql.Row{`null`},
    50  			exp: nil,
    51  		},
    52  		{
    53  			f:   f1,
    54  			row: sql.Row{1},
    55  			err: true,
    56  		},
    57  		{
    58  			f:   f1,
    59  			row: sql.Row{`1`},
    60  			exp: nil,
    61  		},
    62  		{
    63  			f:   f1,
    64  			row: sql.Row{`[1]`},
    65  			exp: nil,
    66  		},
    67  		{
    68  			f:   f1,
    69  			row: sql.Row{`{}`},
    70  			exp: types.MustJSON(`[]`),
    71  		},
    72  		{
    73  			f:   f1,
    74  			row: sql.Row{`badjson`},
    75  			err: true,
    76  		},
    77  		{
    78  			f:   f1,
    79  			row: sql.Row{`"doublestringisvalidjson"`},
    80  			exp: nil,
    81  		},
    82  		{
    83  			f:   f1,
    84  			row: sql.Row{`{"a": 1}`},
    85  			exp: types.MustJSON(`["a"]`),
    86  		},
    87  		{
    88  			f:   f1,
    89  			row: sql.Row{`{"aa": 1, "bb": 2, "c": 3}`},
    90  			exp: types.MustJSON(`["c", "aa", "bb"]`),
    91  		},
    92  
    93  		{
    94  			f:   f2,
    95  			row: sql.Row{`{"a": [1, false]}`, nil},
    96  			exp: nil,
    97  		},
    98  		{
    99  			f:   f2,
   100  			row: sql.Row{`{"a": [1, false]}`, 123},
   101  			err: true,
   102  		},
   103  		{
   104  			f:   f2,
   105  			row: sql.Row{`{"a": [1, false]}`, "$"},
   106  			exp: types.MustJSON(`["a"]`),
   107  		},
   108  		{
   109  			f:   f2,
   110  			row: sql.Row{`{"a": {"z": 1}}`, "$.a"},
   111  			exp: types.MustJSON(`["z"]`),
   112  		},
   113  		{
   114  			f:   f2,
   115  			row: sql.Row{`[1, 2, {"a": 1, "b": {"c": 30}}]`, "$[2]"},
   116  			exp: types.MustJSON(`["a", "b"]`),
   117  		},
   118  		{
   119  			f:   f2,
   120  			row: sql.Row{`[1, 2, {"a": 1, "b": {"c": {"d": 100}}}]`, "$[2].b.c"},
   121  			exp: types.MustJSON(`["d"]`),
   122  		},
   123  		{
   124  			f:   f2,
   125  			row: sql.Row{`{"a": 1, "b": {"c": {"d": "foo"}}}`, "$.b.c"},
   126  			exp: types.MustJSON(`["d"]`),
   127  		},
   128  		{
   129  			f:   f2,
   130  			row: sql.Row{`{"a": 1, "b": [2, 3], "c": {"d": "foo"}}`, "$.d"},
   131  			exp: nil,
   132  		},
   133  		{
   134  			f:   f2,
   135  			row: sql.Row{`{"a": 1, "b": [2, 3], "c": {"d": "foo"}}`, "$["},
   136  			err: true,
   137  		},
   138  	}
   139  
   140  	for _, tt := range testCases {
   141  		var args []string
   142  		for _, a := range tt.row {
   143  			args = append(args, fmt.Sprintf("%v", a))
   144  		}
   145  		t.Run(strings.Join(args, ", "), func(t *testing.T) {
   146  			require := require.New(t)
   147  			result, err := tt.f.Eval(sql.NewEmptyContext(), tt.row)
   148  			if tt.err {
   149  				require.Error(err)
   150  			} else {
   151  				require.NoError(err)
   152  			}
   153  			require.Equal(tt.exp, result)
   154  		})
   155  	}
   156  }