istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/util/path_test.go (about)

     1  // Copyright Istio Authors
     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 util
    16  
    17  import (
    18  	"errors"
    19  	"testing"
    20  )
    21  
    22  func TestSplitEscaped(t *testing.T) {
    23  	tests := []struct {
    24  		desc string
    25  		in   string
    26  		want []string
    27  	}{
    28  		{
    29  			desc: "empty",
    30  			in:   "",
    31  			want: []string{},
    32  		},
    33  		{
    34  			desc: "no match",
    35  			in:   "foo",
    36  			want: []string{"foo"},
    37  		},
    38  		{
    39  			desc: "first",
    40  			in:   ":foo",
    41  			want: []string{"", "foo"},
    42  		},
    43  		{
    44  			desc: "last",
    45  			in:   "foo:",
    46  			want: []string{"foo", ""},
    47  		},
    48  		{
    49  			desc: "multiple",
    50  			in:   "foo:bar:baz",
    51  			want: []string{"foo", "bar", "baz"},
    52  		},
    53  		{
    54  			desc: "multiple with escapes",
    55  			in:   `foo\:bar:baz\:qux`,
    56  			want: []string{`foo\:bar`, `baz\:qux`},
    57  		},
    58  	}
    59  	for _, tt := range tests {
    60  		t.Run(tt.desc, func(t *testing.T) {
    61  			if got, want := splitEscaped(tt.in, kvSeparatorRune), tt.want; !stringSlicesEqual(got, want) {
    62  				t.Errorf("%s: got:%v, want:%v", tt.desc, got, want)
    63  			}
    64  		})
    65  	}
    66  }
    67  
    68  func TestIsNPathElement(t *testing.T) {
    69  	tests := []struct {
    70  		desc   string
    71  		in     string
    72  		expect bool
    73  	}{
    74  		{
    75  			desc:   "empty",
    76  			in:     "",
    77  			expect: false,
    78  		},
    79  		{
    80  			desc:   "negative",
    81  			in:     "[-45]",
    82  			expect: false,
    83  		},
    84  		{
    85  			desc:   "negative-1",
    86  			in:     "[-1]",
    87  			expect: true,
    88  		},
    89  		{
    90  			desc:   "valid",
    91  			in:     "[0]",
    92  			expect: true,
    93  		},
    94  	}
    95  
    96  	for _, tt := range tests {
    97  		t.Run(tt.desc, func(t *testing.T) {
    98  			if got := IsNPathElement(tt.in); got != tt.expect {
    99  				t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got)
   100  			}
   101  		})
   102  	}
   103  }
   104  
   105  func stringSlicesEqual(a, b []string) bool {
   106  	if len(a) != len(b) {
   107  		return false
   108  	}
   109  	for i, aa := range a {
   110  		if aa != b[i] {
   111  			return false
   112  		}
   113  	}
   114  	return true
   115  }
   116  
   117  func TestPathFromString(t *testing.T) {
   118  	tests := []struct {
   119  		desc   string
   120  		in     string
   121  		expect Path
   122  	}{
   123  		{
   124  			desc:   "no-path",
   125  			in:     "",
   126  			expect: Path{},
   127  		},
   128  		{
   129  			desc:   "valid-path",
   130  			in:     "a.b.c",
   131  			expect: Path{"a", "b", "c"},
   132  		},
   133  		{
   134  			desc:   "surround-periods",
   135  			in:     ".a.",
   136  			expect: Path{"a"},
   137  		},
   138  	}
   139  
   140  	for _, tt := range tests {
   141  		t.Run(tt.desc, func(t *testing.T) {
   142  			if got := PathFromString(tt.in); !got.Equals(tt.expect) {
   143  				t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got)
   144  			}
   145  		})
   146  	}
   147  }
   148  
   149  func TestToYAMLPath(t *testing.T) {
   150  	tests := []struct {
   151  		desc   string
   152  		in     string
   153  		expect Path
   154  	}{
   155  		{
   156  			desc:   "all-uppercase",
   157  			in:     "A.B.C.D",
   158  			expect: Path{"a", "b", "c", "d"},
   159  		},
   160  	}
   161  
   162  	for _, tt := range tests {
   163  		t.Run(tt.desc, func(t *testing.T) {
   164  			if got := ToYAMLPath(tt.in); !got.Equals(tt.expect) {
   165  				t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got)
   166  			}
   167  		})
   168  	}
   169  }
   170  
   171  func TestIsKVPathElement(t *testing.T) {
   172  	tests := []struct {
   173  		desc   string
   174  		in     string
   175  		expect bool
   176  	}{
   177  		{
   178  			desc:   "valid",
   179  			in:     "[1:2]",
   180  			expect: true,
   181  		},
   182  		{
   183  			desc:   "invalid",
   184  			in:     "[:2]",
   185  			expect: false,
   186  		},
   187  		{
   188  			desc:   "invalid-2",
   189  			in:     "[1:]",
   190  			expect: false,
   191  		},
   192  		{
   193  			desc:   "empty",
   194  			in:     "",
   195  			expect: false,
   196  		},
   197  		{
   198  			desc:   "no-brackets",
   199  			in:     "1:2",
   200  			expect: false,
   201  		},
   202  		{
   203  			desc:   "one-bracket",
   204  			in:     "[1:2",
   205  			expect: false,
   206  		},
   207  	}
   208  
   209  	for _, tt := range tests {
   210  		t.Run(tt.desc, func(t *testing.T) {
   211  			if got := IsKVPathElement(tt.in); got != tt.expect {
   212  				t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got)
   213  			}
   214  		})
   215  	}
   216  }
   217  
   218  func TestIsVPathElement(t *testing.T) {
   219  	tests := []struct {
   220  		desc   string
   221  		in     string
   222  		expect bool
   223  	}{
   224  		{
   225  			desc:   "valid",
   226  			in:     "[:1]",
   227  			expect: true,
   228  		},
   229  		{
   230  			desc:   "kv-path-elem",
   231  			in:     "[1:2]",
   232  			expect: false,
   233  		},
   234  		{
   235  			desc:   "invalid",
   236  			in:     "1:2",
   237  			expect: false,
   238  		},
   239  		{
   240  			desc:   "empty",
   241  			in:     "",
   242  			expect: false,
   243  		},
   244  	}
   245  
   246  	for _, tt := range tests {
   247  		t.Run(tt.desc, func(t *testing.T) {
   248  			if got := IsVPathElement(tt.in); got != tt.expect {
   249  				t.Errorf("%s: expect %v got %v", tt.desc, tt.expect, got)
   250  			}
   251  		})
   252  	}
   253  }
   254  
   255  func TestPathKV(t *testing.T) {
   256  	tests := []struct {
   257  		desc    string
   258  		in      string
   259  		wantK   string
   260  		wantV   string
   261  		wantErr error
   262  	}{
   263  		{
   264  			desc:    "valid",
   265  			in:      "[1:2]",
   266  			wantK:   "1",
   267  			wantV:   "2",
   268  			wantErr: nil,
   269  		},
   270  		{
   271  			desc:    "invalid",
   272  			in:      "[1:",
   273  			wantErr: errors.New(""),
   274  		},
   275  		{
   276  			desc:    "empty",
   277  			in:      "",
   278  			wantErr: errors.New(""),
   279  		},
   280  	}
   281  
   282  	for _, tt := range tests {
   283  		t.Run(tt.desc, func(t *testing.T) {
   284  			if k, v, err := PathKV(tt.in); k != tt.wantK || v != tt.wantV || errNilCheck(err, tt.wantErr) {
   285  				t.Errorf("%s: expect %v %v %v got %v %v %v", tt.desc, tt.wantK, tt.wantV, tt.wantErr, k, v, err)
   286  			}
   287  		})
   288  	}
   289  }
   290  
   291  func TestPathV(t *testing.T) {
   292  	tests := []struct {
   293  		desc string
   294  		in   string
   295  		want string
   296  		err  error
   297  	}{
   298  		{
   299  			desc: "valid-kv",
   300  			in:   "[1:2]",
   301  			want: "1:2",
   302  			err:  nil,
   303  		},
   304  		{
   305  			desc: "valid-v",
   306  			in:   "[:1]",
   307  			want: "1",
   308  			err:  nil,
   309  		},
   310  		{
   311  			desc: "invalid",
   312  			in:   "083fj",
   313  			want: "",
   314  			err:  errors.New(""),
   315  		},
   316  		{
   317  			desc: "empty",
   318  			in:   "",
   319  			want: "",
   320  			err:  errors.New(""),
   321  		},
   322  	}
   323  
   324  	for _, tt := range tests {
   325  		t.Run(tt.desc, func(t *testing.T) {
   326  			if got, err := PathV(tt.in); got != tt.want || errNilCheck(err, tt.err) {
   327  				t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.want, tt.err, got, err)
   328  			}
   329  		})
   330  	}
   331  }
   332  
   333  func TestRemoveBrackets(t *testing.T) {
   334  	tests := []struct {
   335  		desc       string
   336  		in         string
   337  		expect     string
   338  		expectStat bool
   339  	}{
   340  		{
   341  			desc:       "has-brackets",
   342  			in:         "[yo]",
   343  			expect:     "yo",
   344  			expectStat: true,
   345  		},
   346  		{
   347  			desc:       "one-bracket",
   348  			in:         "[yo",
   349  			expect:     "",
   350  			expectStat: false,
   351  		},
   352  		{
   353  			desc:       "other-bracket",
   354  			in:         "yo]",
   355  			expect:     "",
   356  			expectStat: false,
   357  		},
   358  		{
   359  			desc:       "no-brackets",
   360  			in:         "yo",
   361  			expect:     "",
   362  			expectStat: false,
   363  		},
   364  		{
   365  			desc:       "empty",
   366  			in:         "",
   367  			expect:     "",
   368  			expectStat: false,
   369  		},
   370  	}
   371  
   372  	for _, tt := range tests {
   373  		t.Run(tt.desc, func(t *testing.T) {
   374  			if got, stat := RemoveBrackets(tt.in); got != tt.expect || stat != tt.expectStat {
   375  				t.Errorf("%s: expect %v %v got %v %v", tt.desc, tt.expect, tt.expectStat, got, stat)
   376  			}
   377  		})
   378  	}
   379  }
   380  
   381  func errNilCheck(err1, err2 error) bool {
   382  	return (err1 == nil && err2 != nil) || (err1 != nil && err2 == nil)
   383  }