github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/substring/substrutil_test.go (about)

     1  // Copyright 2021 Matrix Origin
     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 substring
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/container/types"
    21  	"github.com/stretchr/testify/require"
    22  )
    23  
    24  func TestSubstringFromLeftConstOffsetUnbounded(t *testing.T) {
    25  	cases := []struct {
    26  		name  string
    27  		args1 []string
    28  		start int64
    29  		want  []string
    30  	}{
    31  		{
    32  			name:  "Test01",
    33  			args1: []string{"abcdefghijklmn"},
    34  			start: 5,
    35  			want:  []string{"efghijklmn"},
    36  		},
    37  		{
    38  			name:  "Test02",
    39  			args1: []string{"abcdefghijklmn"},
    40  			start: 12,
    41  			want:  []string{"lmn"},
    42  		},
    43  		{
    44  			name:  "Test03",
    45  			args1: []string{"abcdefghijklmn"},
    46  			start: 15,
    47  			want:  []string{""},
    48  		},
    49  	}
    50  
    51  	for _, c := range cases {
    52  		t.Run(c.name, func(t *testing.T) {
    53  			out := make([]string, len(c.args1))
    54  			got := SubstringFromLeftConstOffsetUnbounded(c.args1, out, c.start-1)
    55  			require.Equal(t, c.want, got)
    56  		})
    57  	}
    58  }
    59  
    60  func TestSubstringFromRightConstOffsetUnbounded(t *testing.T) {
    61  	cases := []struct {
    62  		name  string
    63  		args1 []string
    64  		start int64
    65  		want  []string
    66  	}{
    67  		{
    68  			name:  "Test01",
    69  			args1: []string{"abcdefghijklmn"},
    70  			start: -5,
    71  			want:  []string{"jklmn"},
    72  		},
    73  		{
    74  			name:  "Test02",
    75  			args1: []string{"abcdefghijklmn"},
    76  			start: -14,
    77  			want:  []string{"abcdefghijklmn"},
    78  		},
    79  		{
    80  			name:  "Test03",
    81  			args1: []string{"abcdefghijklmn"},
    82  			start: -16,
    83  			want:  []string{""},
    84  		},
    85  	}
    86  
    87  	for _, c := range cases {
    88  		t.Run(c.name, func(t *testing.T) {
    89  			out := make([]string, len(c.args1))
    90  			got := SubstringFromRightConstOffsetUnbounded(c.args1, out, -c.start)
    91  			require.Equal(t, c.want, got)
    92  		})
    93  	}
    94  }
    95  
    96  func TestSubstringFromZeroConstOffsetUnbounded(t *testing.T) {
    97  	cases := []struct {
    98  		name  string
    99  		args1 []string
   100  		start int64
   101  		want  []string
   102  	}{
   103  		{
   104  			name:  "Test01",
   105  			args1: []string{"abcdefghijklmn"},
   106  			start: 0,
   107  			want:  []string{""},
   108  		},
   109  		{
   110  			name:  "Test02",
   111  			args1: []string{"abcd132456"},
   112  			start: 0,
   113  			want:  []string{""},
   114  		},
   115  	}
   116  
   117  	for _, c := range cases {
   118  		t.Run(c.name, func(t *testing.T) {
   119  			out := make([]string, len(c.args1))
   120  			got := SubstringFromZeroConstOffsetUnbounded(c.args1, out)
   121  			require.Equal(t, c.want, got)
   122  		})
   123  	}
   124  }
   125  
   126  func tTestSubstringDynamicOffsetUnbounded[T types.BuiltinNumber](t *testing.T, name string, arg []string, startArgs []T, want []string) {
   127  	t.Run(name, func(t *testing.T) {
   128  		out := make([]string, len(arg))
   129  		got := SubstringDynamicOffsetUnbounded(arg, out, startArgs, []bool{false, false})
   130  		require.Equal(t, want, got)
   131  	})
   132  }
   133  
   134  func TestSubstringDynamicOffsetUnbounded(t *testing.T) {
   135  	tTestSubstringDynamicOffsetUnbounded(t, "Testu1", []string{"abcdefghijklmn"}, []uint8{5}, []string{"efghijklmn"})
   136  	tTestSubstringDynamicOffsetUnbounded(t, "Testu2", []string{"abcdefghijklmn"}, []uint16{5}, []string{"efghijklmn"})
   137  	tTestSubstringDynamicOffsetUnbounded(t, "Testu3", []string{"abcdefghijklmn"}, []uint32{5}, []string{"efghijklmn"})
   138  	tTestSubstringDynamicOffsetUnbounded(t, "Testu4", []string{"abcdefghijklmn"}, []uint64{5}, []string{"efghijklmn"})
   139  	tTestSubstringDynamicOffsetUnbounded(t, "Testi1", []string{"abcdefghijklmn"}, []int8{5}, []string{"efghijklmn"})
   140  	tTestSubstringDynamicOffsetUnbounded(t, "Testi2", []string{"abcdefghijklmn"}, []int16{5}, []string{"efghijklmn"})
   141  	tTestSubstringDynamicOffsetUnbounded(t, "Testi3", []string{"abcdefghijklmn"}, []int32{5}, []string{"efghijklmn"})
   142  	tTestSubstringDynamicOffsetUnbounded(t, "Testi4", []string{"abcdefghijklmn"}, []int64{5}, []string{"efghijklmn"})
   143  	tTestSubstringDynamicOffsetUnbounded(t, "Testf3", []string{"abcdefghijklmn"}, []float32{5}, []string{"efghijklmn"})
   144  	tTestSubstringDynamicOffsetUnbounded(t, "Testf4", []string{"abcdefghijklmn"}, []float64{5}, []string{"efghijklmn"})
   145  }
   146  
   147  //-------------------------------------------------------------
   148  
   149  func TestSubstringFromLeftConstOffsetBounded(t *testing.T) {
   150  	cases := []struct {
   151  		name   string
   152  		args   []string
   153  		start  int64
   154  		length int64
   155  		want   []string
   156  	}{
   157  		{
   158  			name:   "Test01",
   159  			args:   []string{"abcdefghijklmn"},
   160  			start:  5,
   161  			length: 6,
   162  			want:   []string{"efghij"},
   163  		},
   164  		{
   165  			name:   "Test02",
   166  			args:   []string{"abcdefghijklmn"},
   167  			start:  5,
   168  			length: 10,
   169  			want:   []string{"efghijklmn"},
   170  		},
   171  		{
   172  			name:   "Test03",
   173  			args:   []string{"abcdefghijklmn"},
   174  			start:  5,
   175  			length: 0,
   176  			want:   []string{""},
   177  		},
   178  		{
   179  			name:   "Test04",
   180  			args:   []string{"abcdefghijklmn"},
   181  			start:  5,
   182  			length: -3,
   183  			want:   []string{""},
   184  		},
   185  		{
   186  			name:   "Test05",
   187  			args:   []string{"abcdefghijklmn"},
   188  			start:  5,
   189  			length: -8,
   190  			want:   []string{""},
   191  		},
   192  		{
   193  			name:   "Test06",
   194  			args:   []string{"abcdefghijklmn"},
   195  			start:  5,
   196  			length: -10,
   197  			want:   []string{""},
   198  		},
   199  	}
   200  
   201  	for _, c := range cases {
   202  		t.Run(c.name, func(t *testing.T) {
   203  			out := make([]string, len(c.args))
   204  			got := SubstringFromLeftConstOffsetBounded(c.args, out, c.start-1, c.length)
   205  			require.Equal(t, c.want, got)
   206  		})
   207  	}
   208  }
   209  
   210  func TestSubstringFromRightConstOffsetBounded(t *testing.T) {
   211  	cases := []struct {
   212  		name   string
   213  		args   []string
   214  		start  int64
   215  		length int64
   216  		want   []string
   217  	}{
   218  		{
   219  			name:   "Test03",
   220  			args:   []string{"abcdefghijklmn"},
   221  			start:  -10,
   222  			length: 5,
   223  			want:   []string{"efghi"},
   224  		},
   225  		{
   226  			name:   "Test04",
   227  			args:   []string{"abcdefghijklmn"},
   228  			start:  -10,
   229  			length: 0,
   230  			want:   []string{""},
   231  		},
   232  		{
   233  			name:   "Test05",
   234  			args:   []string{"abcdefghijklmn"},
   235  			start:  -10,
   236  			length: 12,
   237  			want:   []string{"efghijklmn"},
   238  		},
   239  		{
   240  			name:   "Test06",
   241  			args:   []string{"abcdefghijklmn"},
   242  			start:  -14,
   243  			length: 12,
   244  			want:   []string{"abcdefghijkl"},
   245  		},
   246  		{
   247  			name:   "Test07",
   248  			args:   []string{"abcdefghijklmn"},
   249  			start:  -20,
   250  			length: 4,
   251  			want:   []string{""},
   252  		},
   253  		{
   254  			name:   "Test08",
   255  			args:   []string{"abcdefghijklmn"},
   256  			start:  -16,
   257  			length: 10,
   258  			want:   []string{""},
   259  		},
   260  		{
   261  			name:   "Test09",
   262  			args:   []string{"abcdefghijklmn"},
   263  			start:  -16,
   264  			length: 20,
   265  			want:   []string{""},
   266  		},
   267  		{
   268  			name:   "Test10",
   269  			args:   []string{"abcdefghijklmn"},
   270  			start:  -8,
   271  			length: -4,
   272  			want:   []string{""},
   273  		},
   274  		{
   275  			name:   "Test11",
   276  			args:   []string{"abcdefghijklmn"},
   277  			start:  -8,
   278  			length: -6,
   279  			want:   []string{""},
   280  		},
   281  		{
   282  			name:   "Test11",
   283  			args:   []string{"abcdefghijklmn"},
   284  			start:  -14,
   285  			length: -6,
   286  			want:   []string{""},
   287  		},
   288  	}
   289  
   290  	for _, c := range cases {
   291  		t.Run(c.name, func(t *testing.T) {
   292  			out := make([]string, len(c.args))
   293  			got := SubstringFromRightConstOffsetBounded(c.args, out, -c.start, c.length)
   294  			require.Equal(t, c.want, got)
   295  		})
   296  	}
   297  }
   298  
   299  func TestSubstringFromZeroConstOffsetBounded(t *testing.T) {
   300  	cases := []struct {
   301  		name   string
   302  		args1  []string
   303  		start  int64
   304  		length int64
   305  		want   []string
   306  	}{
   307  		{
   308  			name:   "Test01",
   309  			args1:  []string{"abcdefghijklmn"},
   310  			start:  0,
   311  			length: 20,
   312  			want:   []string{""},
   313  		},
   314  		{
   315  			name:   "Test02",
   316  			args1:  []string{"abcd132456"},
   317  			start:  0,
   318  			length: -5,
   319  			want:   []string{""}},
   320  	}
   321  
   322  	for _, c := range cases {
   323  		t.Run(c.name, func(t *testing.T) {
   324  			out := make([]string, len(c.args1))
   325  			got := SubstringFromZeroConstOffsetBounded(c.args1, out)
   326  			require.Equal(t, c.want, got)
   327  		})
   328  	}
   329  }
   330  
   331  func tTestSubstringDynamicOffsetBounded[T1, T2 types.BuiltinNumber](
   332  	t *testing.T, name string, srcArgs []string, startArgs []T1, lengthArgs []T2, cs []bool, want []string) {
   333  	t.Run(name, func(t *testing.T) {
   334  		out := make([]string, len(srcArgs))
   335  		got := SubstringDynamicOffsetBounded(srcArgs, out, startArgs, lengthArgs, cs)
   336  		require.Equal(t, want, got)
   337  	})
   338  }
   339  
   340  func TestSubstringDynamicOffsetBounded(t *testing.T) {
   341  	tTestSubstringDynamicOffsetBounded(t, "Test01", []string{"abcdefghijklmn"},
   342  		[]uint8{5}, []uint8{6}, []bool{false, false, false},
   343  		[]string{"efghij"})
   344  
   345  	tTestSubstringDynamicOffsetBounded(t, "Test02", []string{"abcdefghijklmn"},
   346  		[]uint16{5}, []uint16{6}, []bool{false, false, false},
   347  		[]string{"efghij"})
   348  
   349  	tTestSubstringDynamicOffsetBounded(t, "Test03", []string{"abcdefghijklmn"},
   350  		[]uint32{5}, []uint32{6}, []bool{false, false, false},
   351  		[]string{"efghij"})
   352  
   353  	tTestSubstringDynamicOffsetBounded(t, "Test04", []string{"abcdefghijklmn"},
   354  		[]uint64{5}, []uint64{6}, []bool{false, false, false},
   355  		[]string{"efghij"})
   356  
   357  	tTestSubstringDynamicOffsetBounded(t, "Test04", []string{"abcdefghijklmn"},
   358  		[]uint64{5}, []uint64{6}, []bool{false, false, false},
   359  		[]string{"efghij"})
   360  
   361  	tTestSubstringDynamicOffsetBounded(t, "Test05", []string{"abcdefghijklmn"},
   362  		[]uint32{5}, []int64{6}, []bool{false, false, false},
   363  		[]string{"efghij"})
   364  
   365  	tTestSubstringDynamicOffsetBounded(t, "Test06", []string{"abcdefghijklmn"},
   366  		[]uint32{5}, []int64{-6}, []bool{false, false, false},
   367  		[]string{""})
   368  
   369  	tTestSubstringDynamicOffsetBounded(t, "Test07", []string{"abcdefghijklmn"},
   370  		[]uint32{5}, []int8{-6}, []bool{false, false, false},
   371  		[]string{""})
   372  
   373  	tTestSubstringDynamicOffsetBounded(t, "Test08", []string{"abcdefghijklmn"},
   374  		[]uint32{5}, []int8{0}, []bool{false, false, false},
   375  		[]string{""})
   376  
   377  	tTestSubstringDynamicOffsetBounded(t, "Test09", []string{"abcdefghijklmn"},
   378  		[]uint32{5}, []int16{-10}, []bool{false, false, false},
   379  		[]string{""})
   380  
   381  	tTestSubstringDynamicOffsetBounded(t, "Test10", []string{"abcdefghijklmn"},
   382  		[]uint32{0}, []int16{-10}, []bool{false, false, false},
   383  		[]string{""})
   384  
   385  	tTestSubstringDynamicOffsetBounded(t, "Test11", []string{"abcdefghijklmn"},
   386  		[]int32{-10}, []int16{-2}, []bool{false, false, false},
   387  		[]string{""})
   388  
   389  	tTestSubstringDynamicOffsetBounded(t, "Test12", []string{"abcdefghijklmn"},
   390  		[]int32{-10}, []int64{-6}, []bool{false, false, false},
   391  		[]string{""})
   392  
   393  	tTestSubstringDynamicOffsetBounded(t, "Test13", []string{"abcdefghijklmn"},
   394  		[]int32{-10}, []int64{-12}, []bool{false, false, false},
   395  		[]string{""})
   396  
   397  	tTestSubstringDynamicOffsetBounded(t, "Test14", []string{"abcdefghijklmn"},
   398  		[]int32{-10}, []int64{0}, []bool{false, false, false},
   399  		[]string{""})
   400  
   401  	tTestSubstringDynamicOffsetBounded(t, "Test15", []string{"abcdefghijklmn"},
   402  		[]int32{-10}, []int64{-9}, []bool{false, false, false},
   403  		[]string{""})
   404  
   405  	tTestSubstringDynamicOffsetBounded(t, "Test16", []string{"abcdefghijklmn"},
   406  		[]int32{-10}, []int64{-10}, []bool{false, false, false},
   407  		[]string{""})
   408  }