// Copyright (c) 2022 Alibaba Group Holding Ltd. // // 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, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package util import ( "errors" "testing" ) func TestSplitEscaped(t *testing.T) { tests := []struct { desc string in string want []string }{ { desc: "empty", in: "", want: []string{}, }, { desc: "no match", in: "foo", want: []string{"foo"}, }, { desc: "first", in: ":foo", want: []string{"", "foo"}, }, { desc: "last", in: "foo:", want: []string{"foo", ""}, }, { desc: "multiple", in: "foo:bar:baz", want: []string{"foo", "bar", "baz"}, }, { desc: "multiple with escapes", in: `foo\:bar:baz\:qux`, want: []string{`foo\:bar`, `baz\:qux`}, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got, want := splitEscaped(tt.in, kvSeparatorRune), tt.want; !stringSlicesEqual(got, want) { t.Errorf("%s: got:%v, want:%v", tt.desc, got, want) } }) } } func TestIsNPathElement(t *testing.T) { tests := []struct { desc string in string expect bool }{ { desc: "empty", in: "", expect: false, }, { desc: "negative", in: "[-45]", expect: false, }, { desc: "negative-1", in: "[-1]", expect: true, }, { desc: "valid", in: "[0]", expect: true, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got := IsNPathElement(tt.in); got != tt.expect { t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) } }) } } func stringSlicesEqual(a, b []string) bool { if len(a) != len(b) { return false } for i, aa := range a { if aa != b[i] { return false } } return true } func TestPathFromString(t *testing.T) { tests := []struct { desc string in string expect Path }{ { desc: "no-path", in: "", expect: Path{}, }, { desc: "valid-path", in: "a.b.c", expect: Path{"a", "b", "c"}, }, { desc: "surround-periods", in: ".a.", expect: Path{"a"}, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got := PathFromString(tt.in); !got.Equals(tt.expect) { t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) } }) } } func TestToYAMLPath(t *testing.T) { tests := []struct { desc string in string expect Path }{ { desc: "all-uppercase", in: "A.B.C.D", expect: Path{"a", "b", "c", "d"}, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got := ToYAMLPath(tt.in); !got.Equals(tt.expect) { t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) } }) } } func TestIsKVPathElement(t *testing.T) { tests := []struct { desc string in string expect bool }{ { desc: "valid", in: "[1:2]", expect: true, }, { desc: "invalid", in: "[:2]", expect: false, }, { desc: "invalid-2", in: "[1:]", expect: false, }, { desc: "empty", in: "", expect: false, }, { desc: "no-brackets", in: "1:2", expect: false, }, { desc: "one-bracket", in: "[1:2", expect: false, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got := IsKVPathElement(tt.in); got != tt.expect { t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) } }) } } func TestIsVPathElement(t *testing.T) { tests := []struct { desc string in string expect bool }{ { desc: "valid", in: "[:1]", expect: true, }, { desc: "kv-path-elem", in: "[1:2]", expect: false, }, { desc: "invalid", in: "1:2", expect: false, }, { desc: "empty", in: "", expect: false, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got := IsVPathElement(tt.in); got != tt.expect { t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got) } }) } } func TestPathKV(t *testing.T) { tests := []struct { desc string in string wantK string wantV string wantErr error }{ { desc: "valid", in: "[1:2]", wantK: "1", wantV: "2", wantErr: nil, }, { desc: "invalid", in: "[1:", wantErr: errors.New(""), }, { desc: "empty", in: "", wantErr: errors.New(""), }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if k, v, err := PathKV(tt.in); k != tt.wantK || v != tt.wantV || errNilCheck(err, tt.wantErr) { t.Errorf("%s: expect %v %v %v got %v %v %v", tt.desc, tt.wantK, tt.wantV, tt.wantErr, k, v, err) } }) } } func TestPathV(t *testing.T) { tests := []struct { desc string in string want string err error }{ { desc: "valid-kv", in: "[1:2]", want: "1:2", err: nil, }, { desc: "valid-v", in: "[:1]", want: "1", err: nil, }, { desc: "invalid", in: "083fj", want: "", err: errors.New(""), }, { desc: "empty", in: "", want: "", err: errors.New(""), }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got, err := PathV(tt.in); got != tt.want || errNilCheck(err, tt.err) { t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.want, tt.err, got, err) } }) } } func TestRemoveBrackets(t *testing.T) { tests := []struct { desc string in string expect string expectStat bool }{ { desc: "has-brackets", in: "[yo]", expect: "yo", expectStat: true, }, { desc: "one-bracket", in: "[yo", expect: "", expectStat: false, }, { desc: "other-bracket", in: "yo]", expect: "", expectStat: false, }, { desc: "no-brackets", in: "yo", expect: "", expectStat: false, }, { desc: "empty", in: "", expect: "", expectStat: false, }, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { if got, stat := RemoveBrackets(tt.in); got != tt.expect || stat != tt.expectStat { t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.expect, tt.expectStat, got, stat) } }) } } func errNilCheck(err1, err2 error) bool { return (err1 == nil && err2 != nil) || (err1 != nil && err2 == nil) }