From e606342fbbbfa40a4400ede163843b78cd4409c7 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 21 Jul 2021 13:07:35 +0800 Subject: [PATCH] types/json: migrate test-infra to testify (#26375) --- types/json/binary_functions_test.go | 15 +- types/json/binary_test.go | 520 +++++++++++++++------------- types/json/main_test.go | 28 ++ types/json/path_expr_test.go | 97 +++--- 4 files changed, 369 insertions(+), 291 deletions(-) create mode 100644 types/json/main_test.go diff --git a/types/json/binary_functions_test.go b/types/json/binary_functions_test.go index c5da4701d850a..9b1662599bfc3 100644 --- a/types/json/binary_functions_test.go +++ b/types/json/binary_functions_test.go @@ -15,20 +15,17 @@ package json import ( "testing" - . "github.com/pingcap/check" + "github.com/stretchr/testify/require" ) -var _ = Suite(&testJSONFuncSuite{}) +func TestDecodeEscapedUnicode(t *testing.T) { + t.Parallel() -type testJSONFuncSuite struct{} - -func (s *testJSONFuncSuite) TestDecodeEscapedUnicode(c *C) { - c.Parallel() in := "597d" r, size, err := decodeEscapedUnicode([]byte(in)) - c.Assert(string(r[:]), Equals, "好\x00") - c.Assert(size, Equals, 3) - c.Assert(err, IsNil) + require.NoError(t, err) + require.Equal(t, "好\x00", string(r[:])) + require.Equal(t, 3, size) } func BenchmarkDecodeEscapedUnicode(b *testing.B) { diff --git a/types/json/binary_test.go b/types/json/binary_test.go index 0d1ce274e2f5a..d6a8c0bcf1c02 100644 --- a/types/json/binary_test.go +++ b/types/json/binary_test.go @@ -14,39 +14,35 @@ package json import ( + "fmt" "math" "strings" "testing" - . "github.com/pingcap/check" + "github.com/stretchr/testify/require" ) -var _ = Suite(&testJSONSuite{}) +func TestBinaryJSONMarshalUnmarshal(t *testing.T) { + t.Parallel() -type testJSONSuite struct{} - -func TestT(t *testing.T) { - TestingT(t) -} - -func (s *testJSONSuite) TestBinaryJSONMarshalUnmarshal(c *C) { - c.Parallel() - strs := []string{ + expectedList := []string{ `{"a": [1, "2", {"aa": "bb"}, 4, null], "b": true, "c": null}`, `{"aaaaaaaaaaa": [1, "2", {"aa": "bb"}, 4.1], "bbbbbbbbbb": true, "ccccccccc": "d"}`, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`, `{"a": "&<>"}`, } - for _, str := range strs { - parsedBJ := mustParseBinaryFromString(c, str) - c.Assert(parsedBJ.String(), Equals, str) + + for _, expected := range expectedList { + result := mustParseBinaryFromString(t, expected) + require.Equal(t, expected, result.String()) } } -func (s *testJSONSuite) TestBinaryJSONExtract(c *C) { - c.Parallel() - bj1 := mustParseBinaryFromString(c, `{"\"hello\"": "world", "a": [1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}], "b": true, "c": ["d"]}`) - bj2 := mustParseBinaryFromString(c, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`) +func TestBinaryJSONExtract(t *testing.T) { + t.Parallel() + + bj1 := mustParseBinaryFromString(t, `{"\"hello\"": "world", "a": [1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}], "b": true, "c": ["d"]}`) + bj2 := mustParseBinaryFromString(t, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`) var tests = []struct { bj BinaryJSON @@ -56,43 +52,44 @@ func (s *testJSONSuite) TestBinaryJSONExtract(c *C) { err error }{ // test extract with only one path expression. - {bj1, []string{"$.a"}, mustParseBinaryFromString(c, `[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]`), true, nil}, - {bj2, []string{"$.a"}, mustParseBinaryFromString(c, "null"), false, nil}, + {bj1, []string{"$.a"}, mustParseBinaryFromString(t, `[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]`), true, nil}, + {bj2, []string{"$.a"}, mustParseBinaryFromString(t, "null"), false, nil}, {bj1, []string{"$[0]"}, bj1, true, nil}, // in Extract, autowraped bj1 as an array. - {bj2, []string{"$[0]"}, mustParseBinaryFromString(c, `{"a": 1, "b": true}`), true, nil}, - {bj1, []string{"$.a[2].aa"}, mustParseBinaryFromString(c, `"bb"`), true, nil}, - {bj1, []string{"$.a[*].aa"}, mustParseBinaryFromString(c, `["bb", "cc"]`), true, nil}, - {bj1, []string{"$.*[0]"}, mustParseBinaryFromString(c, `["world", 1, true, "d"]`), true, nil}, - {bj1, []string{`$.a[*]."aa"`}, mustParseBinaryFromString(c, `["bb", "cc"]`), true, nil}, - {bj1, []string{`$."\"hello\""`}, mustParseBinaryFromString(c, `"world"`), true, nil}, - {bj1, []string{`$**[1]`}, mustParseBinaryFromString(c, `"2"`), true, nil}, + {bj2, []string{"$[0]"}, mustParseBinaryFromString(t, `{"a": 1, "b": true}`), true, nil}, + {bj1, []string{"$.a[2].aa"}, mustParseBinaryFromString(t, `"bb"`), true, nil}, + {bj1, []string{"$.a[*].aa"}, mustParseBinaryFromString(t, `["bb", "cc"]`), true, nil}, + {bj1, []string{"$.*[0]"}, mustParseBinaryFromString(t, `["world", 1, true, "d"]`), true, nil}, + {bj1, []string{`$.a[*]."aa"`}, mustParseBinaryFromString(t, `["bb", "cc"]`), true, nil}, + {bj1, []string{`$."\"hello\""`}, mustParseBinaryFromString(t, `"world"`), true, nil}, + {bj1, []string{`$**[1]`}, mustParseBinaryFromString(t, `"2"`), true, nil}, // test extract with multi path expressions. - {bj1, []string{"$.a", "$[5]"}, mustParseBinaryFromString(c, `[[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]]`), true, nil}, - {bj2, []string{"$.a", "$[0]"}, mustParseBinaryFromString(c, `[{"a": 1, "b": true}]`), true, nil}, + {bj1, []string{"$.a", "$[5]"}, mustParseBinaryFromString(t, `[[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]]`), true, nil}, + {bj2, []string{"$.a", "$[0]"}, mustParseBinaryFromString(t, `[{"a": 1, "b": true}]`), true, nil}, } - for _, tt := range tests { + for _, test := range tests { var pathExprList = make([]PathExpression, 0) - for _, peStr := range tt.pathExprStrings { + for _, peStr := range test.pathExprStrings { pe, err := ParseJSONPathExpr(peStr) - c.Assert(err, IsNil) + require.NoError(t, err) pathExprList = append(pathExprList, pe) } - result, found := tt.bj.Extract(pathExprList) - c.Assert(found, Equals, tt.found) + result, found := test.bj.Extract(pathExprList) + require.Equal(t, test.found, found) if found { - c.Assert(result.String(), Equals, tt.expected.String()) + require.Equal(t, test.expected.String(), result.String()) } } } -func (s *testJSONSuite) TestBinaryJSONType(c *C) { - c.Parallel() +func TestBinaryJSONType(t *testing.T) { + t.Parallel() + var tests = []struct { - In string - Out string + in string + out string }{ {`{"a": "b"}`, "OBJECT"}, {`["a", "b"]`, "ARRAY"}, @@ -101,64 +98,72 @@ func (s *testJSONSuite) TestBinaryJSONType(c *C) { {`null`, "NULL"}, {`true`, "BOOLEAN"}, } - for _, tt := range tests { - bj := mustParseBinaryFromString(c, tt.In) - c.Assert(bj.Type(), Equals, tt.Out) + + for _, test := range tests { + result := mustParseBinaryFromString(t, test.in) + require.Equal(t, test.out, result.Type()) } + // we can't parse '9223372036854775808' to JSON::Uint64 now, // because go builtin JSON parser treats that as DOUBLE. - c.Assert(CreateBinary(uint64(1<<63)).Type(), Equals, "UNSIGNED INTEGER") + require.Equal(t, "UNSIGNED INTEGER", CreateBinary(uint64(1<<63)).Type()) } -func (s *testJSONSuite) TestBinaryJSONUnquote(c *C) { +func TestBinaryJSONUnquote(t *testing.T) { + t.Parallel() + var tests = []struct { json string unquoted string - err error }{ - {json: `3`, unquoted: "3", err: nil}, - {json: `"3"`, unquoted: "3", err: nil}, - {json: `"[{\"x\":\"{\\\"y\\\":12}\"}]"`, unquoted: `[{"x":"{\"y\":12}"}]`, err: nil}, - {json: `"hello, \"escaped quotes\" world"`, unquoted: "hello, \"escaped quotes\" world", err: nil}, - {json: "\"\\u4f60\"", unquoted: "你", err: nil}, - {json: `true`, unquoted: "true", err: nil}, - {json: `null`, unquoted: "null", err: nil}, - {json: `{"a": [1, 2]}`, unquoted: `{"a": [1, 2]}`, err: nil}, - {json: `"'"`, unquoted: `'`, err: nil}, - {json: `"''"`, unquoted: `''`, err: nil}, - {json: `""`, unquoted: ``, err: nil}, - } - for _, tt := range tests { - bj := mustParseBinaryFromString(c, tt.json) - unquoted, err := bj.Unquote() - c.Assert(err, IsNil) - c.Assert(unquoted, Equals, tt.unquoted) + {json: `3`, unquoted: "3"}, + {json: `"3"`, unquoted: "3"}, + {json: `"[{\"x\":\"{\\\"y\\\":12}\"}]"`, unquoted: `[{"x":"{\"y\":12}"}]`}, + {json: `"hello, \"escaped quotes\" world"`, unquoted: "hello, \"escaped quotes\" world"}, + {json: "\"\\u4f60\"", unquoted: "你"}, + {json: `true`, unquoted: "true"}, + {json: `null`, unquoted: "null"}, + {json: `{"a": [1, 2]}`, unquoted: `{"a": [1, 2]}`}, + {json: `"'"`, unquoted: `'`}, + {json: `"''"`, unquoted: `''`}, + {json: `""`, unquoted: ``}, + } + + for _, test := range tests { + result := mustParseBinaryFromString(t, test.json) + unquoted, err := result.Unquote() + require.NoError(t, err) + require.Equal(t, test.unquoted, unquoted) } } -func (s *testJSONSuite) TestQuoteString(c *C) { +func TestQuoteString(t *testing.T) { + t.Parallel() + var tests = []struct { - j string + raw string quoted string }{ - {j: "3", quoted: `3`}, - {j: "hello, \"escaped quotes\" world", quoted: `"hello, \"escaped quotes\" world"`}, - {j: "你", quoted: `你`}, - {j: "true", quoted: `true`}, - {j: "null", quoted: `null`}, - {j: `"`, quoted: `"\""`}, - {j: `'`, quoted: `'`}, - {j: `''`, quoted: `''`}, - {j: ``, quoted: ``}, - {j: "\\ \" \b \f \n \r \t", quoted: `"\\ \" \b \f \n \r \t"`}, - } - for _, tt := range tests { - c.Assert(quoteString(tt.j), Equals, tt.quoted) + {raw: "3", quoted: `3`}, + {raw: "hello, \"escaped quotes\" world", quoted: `"hello, \"escaped quotes\" world"`}, + {raw: "你", quoted: `你`}, + {raw: "true", quoted: `true`}, + {raw: "null", quoted: `null`}, + {raw: `"`, quoted: `"\""`}, + {raw: `'`, quoted: `'`}, + {raw: `''`, quoted: `''`}, + {raw: ``, quoted: ``}, + {raw: "\\ \" \b \f \n \r \t", quoted: `"\\ \" \b \f \n \r \t"`}, + } + + for _, test := range tests { + require.Equal(t, test.quoted, quoteString(test.raw)) } } -func (s *testJSONSuite) TestBinaryJSONModify(c *C) { - c.Parallel() +func TestBinaryJSONModify(t *testing.T) { + t.Parallel() + var tests = []struct { base string setField string @@ -194,25 +199,27 @@ func (s *testJSONSuite) TestBinaryJSONModify(c *C) { {"null", "$**.a", "{}", "null", false, ModifySet}, {"null", "$**[3]", "{}", "null", false, ModifySet}, } - for _, tt := range tests { - pathExpr, err := ParseJSONPathExpr(tt.setField) - c.Assert(err, IsNil) - - base := mustParseBinaryFromString(c, tt.base) - value := mustParseBinaryFromString(c, tt.setValue) - expected := mustParseBinaryFromString(c, tt.expected) - obtain, err := base.Modify([]PathExpression{pathExpr}, []BinaryJSON{value}, tt.mt) - if tt.success { - c.Assert(err, IsNil) - c.Assert(obtain.String(), Equals, expected.String()) + + for _, test := range tests { + pathExpr, err := ParseJSONPathExpr(test.setField) + require.NoError(t, err) + + base := mustParseBinaryFromString(t, test.base) + value := mustParseBinaryFromString(t, test.setValue) + expected := mustParseBinaryFromString(t, test.expected) + obtain, err := base.Modify([]PathExpression{pathExpr}, []BinaryJSON{value}, test.mt) + if test.success { + require.NoError(t, err) + require.Equal(t, expected.String(), obtain.String()) } else { - c.Assert(err, NotNil) + require.Error(t, err) } } } -func (s *testJSONSuite) TestBinaryJSONRemove(c *C) { - c.Parallel() +func TestBinaryJSONRemove(t *testing.T) { + t.Parallel() + var tests = []struct { base string path string @@ -231,34 +238,36 @@ func (s *testJSONSuite) TestBinaryJSONRemove(c *C) { {`{"a":[3,4,5]}`, "$.a[4]", `{"a":[3,4,5]}`, true}, {`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[2].aa", `{"a": [1, 2, {}]}`, true}, } - for _, tt := range tests { - pathExpr, err := ParseJSONPathExpr(tt.path) - c.Assert(err, IsNil) - base := mustParseBinaryFromString(c, tt.base) - expected := mustParseBinaryFromString(c, tt.expected) + for _, test := range tests { + pathExpr, err := ParseJSONPathExpr(test.path) + require.NoError(t, err) + + base := mustParseBinaryFromString(t, test.base) + expected := mustParseBinaryFromString(t, test.expected) obtain, err := base.Remove([]PathExpression{pathExpr}) - if tt.success { - c.Assert(err, IsNil) - c.Assert(obtain.String(), Equals, expected.String()) + if test.success { + require.NoError(t, err) + require.Equal(t, expected.String(), obtain.String()) } else { - c.Assert(err, NotNil) + require.Error(t, err) } } } -func (s *testJSONSuite) TestCompareBinary(c *C) { - c.Parallel() - jNull := mustParseBinaryFromString(c, `null`) - jBoolTrue := mustParseBinaryFromString(c, `true`) - jBoolFalse := mustParseBinaryFromString(c, `false`) +func TestCompareBinary(t *testing.T) { + t.Parallel() + + jNull := mustParseBinaryFromString(t, `null`) + jBoolTrue := mustParseBinaryFromString(t, `true`) + jBoolFalse := mustParseBinaryFromString(t, `false`) jIntegerLarge := CreateBinary(uint64(1 << 63)) - jIntegerSmall := mustParseBinaryFromString(c, `3`) - jStringLarge := mustParseBinaryFromString(c, `"hello, world"`) - jStringSmall := mustParseBinaryFromString(c, `"hello"`) - jArrayLarge := mustParseBinaryFromString(c, `["a", "c"]`) - jArraySmall := mustParseBinaryFromString(c, `["a", "b"]`) - jObject := mustParseBinaryFromString(c, `{"a": "b"}`) + jIntegerSmall := mustParseBinaryFromString(t, `3`) + jStringLarge := mustParseBinaryFromString(t, `"hello, world"`) + jStringSmall := mustParseBinaryFromString(t, `"hello"`) + jArrayLarge := mustParseBinaryFromString(t, `["a", "c"]`) + jArraySmall := mustParseBinaryFromString(t, `["a", "b"]`) + jObject := mustParseBinaryFromString(t, `{"a": "b"}`) var tests = []struct { left BinaryJSON @@ -304,14 +313,17 @@ func (s *testJSONSuite) TestCompareBinary(c *C) { {CreateBinary(uint64(9)), CreateBinary(float64(8.9)), 1}, {CreateBinary(uint64(9)), CreateBinary(float64(9.1)), -1}, } - for _, tt := range tests { - cmp := CompareBinary(tt.left, tt.right) - c.Assert(cmp == tt.result, IsTrue, Commentf("left: %v, right: %v, expect: %v, got: %v", tt.left, tt.right, tt.result, cmp)) + + for _, test := range tests { + result := CompareBinary(test.left, test.right) + comment := fmt.Sprintf("left: %v, right: %v, expect: %v, got: %v", test.left, test.right, test.result, result) + require.Equal(t, test.result, result, comment) } } -func (s *testJSONSuite) TestBinaryJSONMerge(c *C) { - c.Parallel() +func TestBinaryJSONMerge(t *testing.T) { + t.Parallel() + var tests = []struct { suffixes []string expected string @@ -328,25 +340,23 @@ func (s *testJSONSuite) TestBinaryJSONMerge(c *C) { {[]string{`{}`, `[]`}, `[{}]`}, } - for _, tt := range tests { - suffixes := make([]BinaryJSON, 0, len(tt.suffixes)+1) - for _, s := range tt.suffixes { - suffixes = append(suffixes, mustParseBinaryFromString(c, s)) + for _, test := range tests { + suffixes := make([]BinaryJSON, 0, len(test.suffixes)+1) + for _, s := range test.suffixes { + suffixes = append(suffixes, mustParseBinaryFromString(t, s)) } result := MergeBinary(suffixes) - cmp := CompareBinary(result, mustParseBinaryFromString(c, tt.expected)) - c.Assert(cmp, Equals, 0) + cmp := CompareBinary(result, mustParseBinaryFromString(t, test.expected)) + require.Equal(t, 0, cmp) } } -func mustParseBinaryFromString(c *C, s string) BinaryJSON { - bj, err := ParseBinaryFromString(s) - c.Assert(err, IsNil) - return bj +func mustParseBinaryFromString(t *testing.T, s string) BinaryJSON { + result, err := ParseBinaryFromString(s) + require.NoError(t, err) + return result } -const benchStr = `{"a":[1,"2",{"aa":"bb"},4,null],"b":true,"c":null}` - func BenchmarkBinaryMarshal(b *testing.B) { b.ReportAllocs() b.SetBytes(int64(len(benchStr))) @@ -356,8 +366,9 @@ func BenchmarkBinaryMarshal(b *testing.B) { } } -func (s *testJSONSuite) TestBinaryJSONContains(c *C) { - c.Parallel() +func TestBinaryJSONContains(t *testing.T) { + t.Parallel() + var tests = []struct { input string target string @@ -381,31 +392,34 @@ func (s *testJSONSuite) TestBinaryJSONContains(c *C) { {`[{"a":{"a":1},"b":2}]`, `{"a":1}`, false}, } - for _, tt := range tests { - obj := mustParseBinaryFromString(c, tt.input) - target := mustParseBinaryFromString(c, tt.target) - c.Assert(ContainsBinary(obj, target), Equals, tt.expected) + for _, test := range tests { + obj := mustParseBinaryFromString(t, test.input) + target := mustParseBinaryFromString(t, test.target) + require.Equal(t, test.expected, ContainsBinary(obj, target)) } } -func (s *testJSONSuite) TestBinaryJSONCopy(c *C) { - c.Parallel() - strs := []string{ +func TestBinaryJSONCopy(t *testing.T) { + t.Parallel() + + expectedList := []string{ `{"a": [1, "2", {"aa": "bb"}, 4, null], "b": true, "c": null}`, `{"aaaaaaaaaaa": [1, "2", {"aa": "bb"}, 4.1], "bbbbbbbbbb": true, "ccccccccc": "d"}`, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`, } - for _, str := range strs { - parsedBJ := mustParseBinaryFromString(c, str) - c.Assert(parsedBJ.Copy().String(), Equals, parsedBJ.String()) + for _, expected := range expectedList { + result := mustParseBinaryFromString(t, expected) + require.Equal(t, result.String(), result.Copy().String()) } } -func (s *testJSONSuite) TestGetKeys(c *C) { - c.Parallel() - parsedBJ := mustParseBinaryFromString(c, "[]") - c.Assert(parsedBJ.GetKeys().String(), Equals, "[]") - parsedBJ = mustParseBinaryFromString(c, "{}") - c.Assert(parsedBJ.GetKeys().String(), Equals, "[]") + +func TestGetKeys(t *testing.T) { + t.Parallel() + + parsedBJ := mustParseBinaryFromString(t, "[]") + require.Equal(t, "[]", parsedBJ.GetKeys().String()) + parsedBJ = mustParseBinaryFromString(t, "{}") + require.Equal(t, "[]", parsedBJ.GetKeys().String()) b := strings.Builder{} b.WriteString("{\"") @@ -414,12 +428,13 @@ func (s *testJSONSuite) TestGetKeys(c *C) { } b.WriteString("\": 1}") parsedBJ, err := ParseBinaryFromString(b.String()) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[types:8129]TiDB does not yet support JSON objects with the key length >= 65536") + require.Error(t, err) + require.EqualError(t, err, "[types:8129]TiDB does not yet support JSON objects with the key length >= 65536") } -func (s *testJSONSuite) TestBinaryJSONDepth(c *C) { - c.Parallel() +func TestBinaryJSONDepth(t *testing.T) { + t.Parallel() + var tests = []struct { input string expected int @@ -433,132 +448,151 @@ func (s *testJSONSuite) TestBinaryJSONDepth(c *C) { {`{"Person": {"Name": "Homer", "Age": 39, "Hobbies": ["Eating", "Sleeping"]} }`, 4}, } - for _, tt := range tests { - obj := mustParseBinaryFromString(c, tt.input) - c.Assert(obj.GetElemDepth(), Equals, tt.expected) + for _, test := range tests { + obj := mustParseBinaryFromString(t, test.input) + require.Equal(t, test.expected, obj.GetElemDepth()) } } -func (s *testJSONSuite) TestParseBinaryFromString(c *C) { - c.Parallel() +func TestParseBinaryFromString(t *testing.T) { + t.Parallel() + obj, err := ParseBinaryFromString("") - c.Assert(obj.String(), Equals, "") - c.Assert(err, ErrorMatches, "*The document is empty*") + require.Error(t, err) + require.Equal(t, "", obj.String()) + require.Regexp(t, ".*The document is empty.*", err.Error()) + obj, err = ParseBinaryFromString(`"a""`) - c.Assert(obj.String(), Equals, "") - c.Assert(err, ErrorMatches, "*The document root must not be followed by other values.*") + require.Error(t, err) + require.Equal(t, "", obj.String()) + require.Regexp(t, ".*The document root must not be followed by other values\\..*", err.Error()) } -func (s *testJSONSuite) TestCreateBinary(c *C) { - c.Parallel() +func TestCreateBinary(t *testing.T) { + t.Parallel() + bj := CreateBinary(int64(1 << 62)) - c.Assert(bj.TypeCode, Equals, TypeCodeInt64) - c.Assert(bj.Value, NotNil) + require.Equal(t, TypeCodeInt64, bj.TypeCode) + require.NotNil(t, bj.Value) + bj = CreateBinary(123456789.1234567) - c.Assert(bj.TypeCode, Equals, TypeCodeFloat64) + require.Equal(t, TypeCodeFloat64, bj.TypeCode) + bj = CreateBinary(0.00000001) - c.Assert(bj.TypeCode, Equals, TypeCodeFloat64) + require.Equal(t, TypeCodeFloat64, bj.TypeCode) + bj = CreateBinary(1e-20) - c.Assert(bj.TypeCode, Equals, TypeCodeFloat64) - c.Assert(bj.Value, NotNil) + require.Equal(t, TypeCodeFloat64, bj.TypeCode) + require.NotNil(t, bj.Value) + bj2 := CreateBinary(bj) - c.Assert(bj2.TypeCode, Equals, bj.TypeCode) - c.Assert(bj2.Value, NotNil) + require.Equal(t, bj.TypeCode, bj2.TypeCode) + require.NotNil(t, bj2.Value) + func() { defer func() { r := recover() - c.Assert(r, ErrorMatches, "unknown type:.*") + require.Regexp(t, "unknown type:.*", r) }() bj = CreateBinary(int8(123)) - c.Assert(bj.TypeCode, Equals, bj.TypeCode) + require.Equal(t, bj.TypeCode, bj.TypeCode) }() } -func (s *testJSONSuite) TestFunctions(c *C) { - c.Parallel() +func TestFunctions(t *testing.T) { + t.Parallel() + testByte := []byte{'\\', 'b', 'f', 'n', 'r', 't', 'u', 'z', '0'} testOutput, err := unquoteString(string(testByte)) - c.Assert(testOutput, Equals, "\bfnrtuz0") - c.Assert(err, IsNil) + require.Equal(t, "\bfnrtuz0", testOutput) + require.NoError(t, err) + n, err := PeekBytesAsJSON(testByte) - c.Assert(n, Equals, 0) - c.Assert(err, ErrorMatches, "Invalid JSON bytes") + require.Equal(t, 0, n) + require.EqualError(t, err, "Invalid JSON bytes") + n, err = PeekBytesAsJSON([]byte("")) - c.Assert(n, Equals, 0) - c.Assert(err, ErrorMatches, "Cant peek from empty bytes") + require.Equal(t, 0, n) + require.EqualError(t, err, "Cant peek from empty bytes") } -func (s *testJSONSuite) TestBinaryJSONExtractCallback(c *C) { - bj1 := mustParseBinaryFromString(c, `{"\"hello\"": "world", "a": [1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}], "b": true, "c": ["d"]}`) - bj2 := mustParseBinaryFromString(c, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`) +func TestBinaryJSONExtractCallback(t *testing.T) { + t.Parallel() + + bj1 := mustParseBinaryFromString(t, `{"\"hello\"": "world", "a": [1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}], "b": true, "c": ["d"]}`) + bj2 := mustParseBinaryFromString(t, `[{"a": 1, "b": true}, 3, 3.5, "hello, world", null, true]`) type ExpectedPair struct { path string bj BinaryJSON } + var tests = []struct { bj BinaryJSON pathExpr string expected []ExpectedPair }{ {bj1, "$.a", []ExpectedPair{ - {"$.a", mustParseBinaryFromString(c, `[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]`)}, + {"$.a", mustParseBinaryFromString(t, `[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]`)}, }}, {bj2, "$.a", []ExpectedPair{}}, {bj1, "$[0]", []ExpectedPair{}}, // in extractToCallback/Walk/Search, DON'T autowraped bj as an array. {bj2, "$[0]", []ExpectedPair{ - {"$[0]", mustParseBinaryFromString(c, `{"a": 1, "b": true}`)}, + {"$[0]", mustParseBinaryFromString(t, `{"a": 1, "b": true}`)}, }}, {bj1, "$.a[2].aa", []ExpectedPair{ - {"$.a[2].aa", mustParseBinaryFromString(c, `"bb"`)}, + {"$.a[2].aa", mustParseBinaryFromString(t, `"bb"`)}, }}, {bj1, "$.a[*].aa", []ExpectedPair{ - {"$.a[2].aa", mustParseBinaryFromString(c, `"bb"`)}, - {"$.a[4].aa", mustParseBinaryFromString(c, `"cc"`)}, + {"$.a[2].aa", mustParseBinaryFromString(t, `"bb"`)}, + {"$.a[4].aa", mustParseBinaryFromString(t, `"cc"`)}, }}, {bj1, "$.*[0]", []ExpectedPair{ // {"$.\"hello\"[0]", mustParseBinaryFromString(c, `"world"`)}, // NO autowraped as an array. - {"$.a[0]", mustParseBinaryFromString(c, `1`)}, + {"$.a[0]", mustParseBinaryFromString(t, `1`)}, // {"$.b[0]", mustParseBinaryFromString(c, `true`)}, // NO autowraped as an array. - {"$.c[0]", mustParseBinaryFromString(c, `"d"`)}, + {"$.c[0]", mustParseBinaryFromString(t, `"d"`)}, }}, {bj1, `$.a[*]."aa"`, []ExpectedPair{ - {"$.a[2].aa", mustParseBinaryFromString(c, `"bb"`)}, - {"$.a[4].aa", mustParseBinaryFromString(c, `"cc"`)}, + {"$.a[2].aa", mustParseBinaryFromString(t, `"bb"`)}, + {"$.a[4].aa", mustParseBinaryFromString(t, `"cc"`)}, }}, {bj1, `$."\"hello\""`, []ExpectedPair{ - {`$."\"hello\""`, mustParseBinaryFromString(c, `"world"`)}, + {`$."\"hello\""`, mustParseBinaryFromString(t, `"world"`)}, }}, {bj1, `$**[1]`, []ExpectedPair{ - {`$.a[1]`, mustParseBinaryFromString(c, `"2"`)}, + {`$.a[1]`, mustParseBinaryFromString(t, `"2"`)}, }}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.pathExpr) - c.Assert(err, IsNil) + for _, test := range tests { + pe, err := ParseJSONPathExpr(test.pathExpr) + require.NoError(t, err) count := 0 - cb := func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) { - c.Assert(count, Less, len(tt.expected)) - if count < len(tt.expected) { - c.Assert(fullpath.String(), Equals, tt.expected[count].path) - c.Assert(bj.String(), Equals, tt.expected[count].bj.String()) + cb := func(fullPath PathExpression, bj BinaryJSON) (stop bool, err error) { + require.Less(t, count, len(test.expected)) + if count < len(test.expected) { + require.Equal(t, test.expected[count].path, fullPath.String()) + require.Equal(t, test.expected[count].bj.String(), bj.String()) } count++ return false, nil } - fullpath := PathExpression{legs: make([]pathLeg, 0), flags: pathExpressionFlag(0)} - _, err = tt.bj.extractToCallback(pe, cb, fullpath) - c.Assert(err, IsNil) - c.Assert(count, Equals, len(tt.expected)) + + fullPath := PathExpression{legs: make([]pathLeg, 0), flags: pathExpressionFlag(0)} + _, err = test.bj.extractToCallback(pe, cb, fullPath) + require.NoError(t, err) + require.Equal(t, len(test.expected), count) } } -func (s *testJSONSuite) TestBinaryJSONWalk(c *C) { - bj1 := mustParseBinaryFromString(c, `["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]`) - bj2 := mustParseBinaryFromString(c, `{}`) +func TestBinaryJSONWalk(t *testing.T) { + t.Parallel() + + bj1 := mustParseBinaryFromString(t, `["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]`) + bj2 := mustParseBinaryFromString(t, `{}`) type ExpectedPair struct { path string @@ -570,60 +604,60 @@ func (s *testJSONSuite) TestBinaryJSONWalk(c *C) { expected []ExpectedPair }{ {bj1, []string{}, []ExpectedPair{ - {`$`, mustParseBinaryFromString(c, `["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]`)}, - {`$[0]`, mustParseBinaryFromString(c, `"abc"`)}, - {`$[1]`, mustParseBinaryFromString(c, `[{"k": "10"}, "def"]`)}, - {`$[1][0]`, mustParseBinaryFromString(c, `{"k": "10"}`)}, - {`$[1][0].k`, mustParseBinaryFromString(c, `"10"`)}, - {`$[1][1]`, mustParseBinaryFromString(c, `"def"`)}, - {`$[2]`, mustParseBinaryFromString(c, `{"x":"abc"}`)}, - {`$[2].x`, mustParseBinaryFromString(c, `"abc"`)}, - {`$[3]`, mustParseBinaryFromString(c, `{"y":"bcd"}`)}, - {`$[3].y`, mustParseBinaryFromString(c, `"bcd"`)}, + {`$`, mustParseBinaryFromString(t, `["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]`)}, + {`$[0]`, mustParseBinaryFromString(t, `"abc"`)}, + {`$[1]`, mustParseBinaryFromString(t, `[{"k": "10"}, "def"]`)}, + {`$[1][0]`, mustParseBinaryFromString(t, `{"k": "10"}`)}, + {`$[1][0].k`, mustParseBinaryFromString(t, `"10"`)}, + {`$[1][1]`, mustParseBinaryFromString(t, `"def"`)}, + {`$[2]`, mustParseBinaryFromString(t, `{"x":"abc"}`)}, + {`$[2].x`, mustParseBinaryFromString(t, `"abc"`)}, + {`$[3]`, mustParseBinaryFromString(t, `{"y":"bcd"}`)}, + {`$[3].y`, mustParseBinaryFromString(t, `"bcd"`)}, }}, {bj1, []string{`$[1]`}, []ExpectedPair{ - {`$[1]`, mustParseBinaryFromString(c, `[{"k": "10"}, "def"]`)}, - {`$[1][0]`, mustParseBinaryFromString(c, `{"k": "10"}`)}, - {`$[1][0].k`, mustParseBinaryFromString(c, `"10"`)}, - {`$[1][1]`, mustParseBinaryFromString(c, `"def"`)}, + {`$[1]`, mustParseBinaryFromString(t, `[{"k": "10"}, "def"]`)}, + {`$[1][0]`, mustParseBinaryFromString(t, `{"k": "10"}`)}, + {`$[1][0].k`, mustParseBinaryFromString(t, `"10"`)}, + {`$[1][1]`, mustParseBinaryFromString(t, `"def"`)}, }}, {bj1, []string{`$[1]`, `$[1]`}, []ExpectedPair{ // test for unique - {`$[1]`, mustParseBinaryFromString(c, `[{"k": "10"}, "def"]`)}, - {`$[1][0]`, mustParseBinaryFromString(c, `{"k": "10"}`)}, - {`$[1][0].k`, mustParseBinaryFromString(c, `"10"`)}, - {`$[1][1]`, mustParseBinaryFromString(c, `"def"`)}, + {`$[1]`, mustParseBinaryFromString(t, `[{"k": "10"}, "def"]`)}, + {`$[1][0]`, mustParseBinaryFromString(t, `{"k": "10"}`)}, + {`$[1][0].k`, mustParseBinaryFromString(t, `"10"`)}, + {`$[1][1]`, mustParseBinaryFromString(t, `"def"`)}, }}, {bj1, []string{`$.m`}, []ExpectedPair{}}, {bj2, []string{}, []ExpectedPair{ - {`$`, mustParseBinaryFromString(c, `{}`)}, + {`$`, mustParseBinaryFromString(t, `{}`)}, }}, } - for _, tt := range tests { + for _, test := range tests { count := 0 - cb := func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) { - c.Assert(count, Less, len(tt.expected)) - if count < len(tt.expected) { - c.Assert(fullpath.String(), Equals, tt.expected[count].path) - c.Assert(bj.String(), Equals, tt.expected[count].bj.String()) + cb := func(fullPath PathExpression, bj BinaryJSON) (stop bool, err error) { + require.Less(t, count, len(test.expected)) + if count < len(test.expected) { + require.Equal(t, test.expected[count].path, fullPath.String()) + require.Equal(t, test.expected[count].bj.String(), bj.String()) } count++ return false, nil } var err error - if len(tt.paths) > 0 { - peList := make([]PathExpression, 0, len(tt.paths)) - for _, path := range tt.paths { + if len(test.paths) > 0 { + peList := make([]PathExpression, 0, len(test.paths)) + for _, path := range test.paths { pe, errPath := ParseJSONPathExpr(path) - c.Assert(errPath, IsNil) + require.NoError(t, errPath) peList = append(peList, pe) } - err = tt.bj.Walk(cb, peList...) + err = test.bj.Walk(cb, peList...) } else { - err = tt.bj.Walk(cb) + err = test.bj.Walk(cb) } - c.Assert(err, IsNil) - c.Assert(count, Equals, len(tt.expected)) + require.NoError(t, err) + require.Equal(t, len(test.expected), count) } } diff --git a/types/json/main_test.go b/types/json/main_test.go new file mode 100644 index 0000000000000..d80d8796a849f --- /dev/null +++ b/types/json/main_test.go @@ -0,0 +1,28 @@ +// Copyright 2021 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package json + +import ( + "testing" + + "github.com/pingcap/tidb/util/testbridge" + "go.uber.org/goleak" +) + +const benchStr = `{"a":[1,"2",{"aa":"bb"},4,null],"b":true,"c":null}` + +func TestMain(m *testing.M) { + testbridge.WorkaroundGoCheckFlags() + goleak.VerifyTestMain(m) +} diff --git a/types/json/path_expr_test.go b/types/json/path_expr_test.go index 5efc648283d0a..5fa79dc5f4546 100644 --- a/types/json/path_expr_test.go +++ b/types/json/path_expr_test.go @@ -14,12 +14,14 @@ package json import ( - . "github.com/pingcap/check" + "testing" + + "github.com/stretchr/testify/require" ) -func (s *testJSONSuite) TestContainsAnyAsterisk(c *C) { +func TestContainsAnyAsterisk(t *testing.T) { var tests = []struct { - exprString string + expression string containsAsterisks bool }{ {"$.a[b]", false}, @@ -27,16 +29,20 @@ func (s *testJSONSuite) TestContainsAnyAsterisk(c *C) { {"$.*[b]", true}, {"$**.a[b]", true}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.exprString) - c.Assert(err, IsNil) - c.Assert(pe.flags.containsAnyAsterisk(), Equals, tt.containsAsterisks) + + for _, test := range tests { + t.Run(test.expression, func(t *testing.T) { + t.Parallel() + pe, err := ParseJSONPathExpr(test.expression) + require.NoError(t, err) + require.Equal(t, test.containsAsterisks, pe.flags.containsAnyAsterisk()) + }) } } -func (s *testJSONSuite) TestValidatePathExpr(c *C) { +func TestValidatePathExpr(t *testing.T) { var tests = []struct { - exprString string + expression string success bool legs int }{ @@ -52,20 +58,23 @@ func (s *testJSONSuite) TestValidatePathExpr(c *C) { {`$ No Valid Legs Here .a.b.c`, false, 0}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.exprString) - if tt.success { - c.Assert(err, IsNil) - c.Assert(len(pe.legs), Equals, tt.legs) - } else { - c.Assert(err, NotNil) - } + for _, test := range tests { + t.Run(test.expression, func(t *testing.T) { + t.Parallel() + pe, err := ParseJSONPathExpr(test.expression) + if test.success { + require.NoError(t, err) + require.Len(t, pe.legs, test.legs) + } else { + require.Error(t, err) + } + }) } } -func (s *testJSONSuite) TestPathExprToString(c *C) { +func TestPathExprToString(t *testing.T) { var tests = []struct { - exprString string + expression string }{ {"$.a[1]"}, {"$.a[*]"}, @@ -73,16 +82,19 @@ func (s *testJSONSuite) TestPathExprToString(c *C) { {"$**.a[3]"}, {`$."\"hello\""`}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.exprString) - c.Assert(err, IsNil) - c.Assert(pe.String(), Equals, tt.exprString) + for _, test := range tests { + t.Run(test.expression, func(t *testing.T) { + t.Parallel() + pe, err := ParseJSONPathExpr(test.expression) + require.NoError(t, err) + require.Equal(t, test.expression, pe.String()) + }) } } -func (s *testJSONSuite) TestPushBackOneIndexLeg(c *C) { +func TestPushBackOneIndexLeg(t *testing.T) { var tests = []struct { - exprString string + expression string index int expected string containsAnyAsterisk bool @@ -94,19 +106,23 @@ func (s *testJSONSuite) TestPushBackOneIndexLeg(c *C) { {"$.*[2]", 2, "$.*[2][2]", true}, {"$**.a[3]", 3, "$**.a[3][3]", true}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.exprString) - c.Assert(err, IsNil) - pe = pe.pushBackOneIndexLeg(tt.index) - c.Assert(pe.String(), Equals, tt.expected) - c.Assert(pe.ContainsAnyAsterisk(), Equals, tt.containsAnyAsterisk) + for _, test := range tests { + t.Run(test.expression, func(t *testing.T) { + t.Parallel() + pe, err := ParseJSONPathExpr(test.expression) + require.NoError(t, err) + + pe = pe.pushBackOneIndexLeg(test.index) + require.Equal(t, test.expected, pe.String()) + require.Equal(t, test.containsAnyAsterisk, pe.ContainsAnyAsterisk()) + }) } } -func (s *testJSONSuite) TestPushBackOneKeyLeg(c *C) { +func TestPushBackOneKeyLeg(t *testing.T) { var tests = []struct { - exprString string + expression string key string expected string containsAnyAsterisk bool @@ -118,12 +134,15 @@ func (s *testJSONSuite) TestPushBackOneKeyLeg(c *C) { {"$.*[2]", "bb", "$.*[2].bb", true}, {"$**.a[3]", "cc", "$**.a[3].cc", true}, } - for _, tt := range tests { - pe, err := ParseJSONPathExpr(tt.exprString) - c.Assert(err, IsNil) - pe = pe.pushBackOneKeyLeg(tt.key) - c.Assert(pe.String(), Equals, tt.expected) - c.Assert(pe.ContainsAnyAsterisk(), Equals, tt.containsAnyAsterisk) + for _, test := range tests { + t.Run(test.expression, func(t *testing.T) { + pe, err := ParseJSONPathExpr(test.expression) + require.NoError(t, err) + + pe = pe.pushBackOneKeyLeg(test.key) + require.Equal(t, test.expected, pe.String()) + require.Equal(t, test.containsAnyAsterisk, pe.ContainsAnyAsterisk()) + }) } }