github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/sorter/basic_comparators_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package sorter
    13  
    14  import (
    15  	"fmt"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/stretchr/testify/assert"
    20  )
    21  
    22  func TestBasicComparator_String(t *testing.T) {
    23  	Orange := "Orange"
    24  	orange := "orange"
    25  	apple := "apple"
    26  
    27  	t.Run("strings asc", func(t *testing.T) {
    28  		comp := newStringComparator("asc")
    29  
    30  		params := []struct {
    31  			a        *string
    32  			b        *string
    33  			expected int
    34  		}{
    35  			{&Orange, &orange, 0},
    36  			{&orange, &orange, 0},
    37  			{&apple, &apple, 0},
    38  			{&orange, &apple, 1},
    39  			{&apple, &orange, -1},
    40  			{nil, &apple, -1},
    41  			{&orange, nil, 1},
    42  			{nil, nil, 0},
    43  		}
    44  
    45  		for i, p := range params {
    46  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
    47  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
    48  			})
    49  		}
    50  	})
    51  
    52  	t.Run("strings desc", func(t *testing.T) {
    53  		comp := newStringComparator("desc")
    54  
    55  		params := []struct {
    56  			a        *string
    57  			b        *string
    58  			expected int
    59  		}{
    60  			{&Orange, &orange, 0},
    61  			{&orange, &orange, 0},
    62  			{&apple, &apple, 0},
    63  			{&orange, &apple, -1},
    64  			{&apple, &orange, 1},
    65  			{nil, &apple, 1},
    66  			{&orange, nil, -1},
    67  			{nil, nil, 0},
    68  		}
    69  
    70  		for i, p := range params {
    71  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
    72  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
    73  			})
    74  		}
    75  	})
    76  }
    77  
    78  func TestBasicComparator_StringArray(t *testing.T) {
    79  	o_b_a := []string{"orange", "banana", "apple"}
    80  	p := []string{"pear"}
    81  	o_a := []string{"orange", "apple"}
    82  	o_b := []string{"orange", "banana"}
    83  
    84  	t.Run("strings array asc", func(t *testing.T) {
    85  		comp := newStringArrayComparator("asc")
    86  
    87  		params := []struct {
    88  			a        *[]string
    89  			b        *[]string
    90  			expected int
    91  		}{
    92  			{&o_b_a, &o_b_a, 0},
    93  			{&p, &p, 0},
    94  			{&o_a, &o_a, 0},
    95  			{&o_b, &o_b, 0},
    96  			{&o_a, &o_b, -1},
    97  			{&o_b, &o_b_a, -1},
    98  			{&p, &o_b_a, 1},
    99  			{nil, &o_a, -1},
   100  			{&p, nil, 1},
   101  			{nil, nil, 0},
   102  		}
   103  
   104  		for i, p := range params {
   105  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   106  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   107  			})
   108  		}
   109  	})
   110  
   111  	t.Run("strings array desc", func(t *testing.T) {
   112  		comp := newStringArrayComparator("desc")
   113  
   114  		params := []struct {
   115  			a        *[]string
   116  			b        *[]string
   117  			expected int
   118  		}{
   119  			{&o_b_a, &o_b_a, 0},
   120  			{&p, &p, 0},
   121  			{&o_a, &o_a, 0},
   122  			{&o_b, &o_b, 0},
   123  			{&o_a, &o_b, 1},
   124  			{&o_b, &o_b_a, 1},
   125  			{&p, &o_b_a, -1},
   126  			{nil, &o_a, 1},
   127  			{&p, nil, -1},
   128  			{nil, nil, 0},
   129  		}
   130  
   131  		for i, p := range params {
   132  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   133  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   134  			})
   135  		}
   136  	})
   137  }
   138  
   139  func TestBasicComparator_Float64(t *testing.T) {
   140  	f_10 := -10.0
   141  	f100 := 100.0
   142  	f0 := 0.0
   143  
   144  	t.Run("floats asc", func(t *testing.T) {
   145  		comp := newFloat64Comparator("asc")
   146  
   147  		params := []struct {
   148  			a        *float64
   149  			b        *float64
   150  			expected int
   151  		}{
   152  			{&f_10, &f_10, 0},
   153  			{&f100, &f100, 0},
   154  			{&f0, &f0, 0},
   155  			{&f100, &f_10, 1},
   156  			{&f0, &f100, -1},
   157  			{nil, &f_10, -1},
   158  			{&f0, nil, 1},
   159  			{nil, nil, 0},
   160  		}
   161  
   162  		for i, p := range params {
   163  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   164  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   165  			})
   166  		}
   167  	})
   168  
   169  	t.Run("floats desc", func(t *testing.T) {
   170  		comp := newFloat64Comparator("desc")
   171  
   172  		params := []struct {
   173  			a        *float64
   174  			b        *float64
   175  			expected int
   176  		}{
   177  			{&f_10, &f_10, 0},
   178  			{&f100, &f100, 0},
   179  			{&f0, &f0, 0},
   180  			{&f100, &f_10, -1},
   181  			{&f0, &f100, 1},
   182  			{nil, &f_10, 1},
   183  			{&f0, nil, -1},
   184  			{nil, nil, 0},
   185  		}
   186  
   187  		for i, p := range params {
   188  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   189  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   190  			})
   191  		}
   192  	})
   193  }
   194  
   195  func TestBasicComparator_Float64Array(t *testing.T) {
   196  	f_3_2_1 := []float64{3, 2, 1}
   197  	f_4 := []float64{4}
   198  	f_3_1 := []float64{3, 1}
   199  	f_3_2 := []float64{3, 2}
   200  
   201  	t.Run("floats array asc", func(t *testing.T) {
   202  		comp := newFloat64ArrayComparator("asc")
   203  
   204  		params := []struct {
   205  			a        *[]float64
   206  			b        *[]float64
   207  			expected int
   208  		}{
   209  			{&f_3_2_1, &f_3_2_1, 0},
   210  			{&f_4, &f_4, 0},
   211  			{&f_3_1, &f_3_1, 0},
   212  			{&f_3_2, &f_3_2, 0},
   213  			{&f_3_1, &f_3_2, -1},
   214  			{&f_3_2, &f_3_2_1, -1},
   215  			{&f_4, &f_3_2_1, 1},
   216  			{nil, &f_3_1, -1},
   217  			{&f_4, nil, 1},
   218  			{nil, nil, 0},
   219  		}
   220  
   221  		for i, p := range params {
   222  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   223  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   224  			})
   225  		}
   226  	})
   227  
   228  	t.Run("floats array desc", func(t *testing.T) {
   229  		comp := newFloat64ArrayComparator("desc")
   230  
   231  		params := []struct {
   232  			a        *[]float64
   233  			b        *[]float64
   234  			expected int
   235  		}{
   236  			{&f_3_2_1, &f_3_2_1, 0},
   237  			{&f_4, &f_4, 0},
   238  			{&f_3_1, &f_3_1, 0},
   239  			{&f_3_2, &f_3_2, 0},
   240  			{&f_3_1, &f_3_2, 1},
   241  			{&f_3_2, &f_3_2_1, 1},
   242  			{&f_4, &f_3_2_1, -1},
   243  			{nil, &f_3_1, 1},
   244  			{&f_4, nil, -1},
   245  			{nil, nil, 0},
   246  		}
   247  
   248  		for i, p := range params {
   249  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   250  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   251  			})
   252  		}
   253  	})
   254  }
   255  
   256  func TestBasicComparator_Date(t *testing.T) {
   257  	t1 := time.Now()
   258  	t2 := time.Now().Add(time.Second)
   259  	t3 := time.Now().Add(2 * time.Second)
   260  
   261  	t.Run("dates asc", func(t *testing.T) {
   262  		comp := newDateComparator("asc")
   263  
   264  		params := []struct {
   265  			a        *time.Time
   266  			b        *time.Time
   267  			expected int
   268  		}{
   269  			{&t1, &t1, 0},
   270  			{&t3, &t3, 0},
   271  			{&t2, &t2, 0},
   272  			{&t3, &t1, 1},
   273  			{&t2, &t3, -1},
   274  			{nil, &t1, -1},
   275  			{&t2, nil, 1},
   276  			{nil, nil, 0},
   277  		}
   278  
   279  		for i, p := range params {
   280  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   281  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   282  			})
   283  		}
   284  	})
   285  
   286  	t.Run("dates desc", func(t *testing.T) {
   287  		comp := newDateComparator("desc")
   288  
   289  		params := []struct {
   290  			a        *time.Time
   291  			b        *time.Time
   292  			expected int
   293  		}{
   294  			{&t1, &t1, 0},
   295  			{&t3, &t3, 0},
   296  			{&t2, &t2, 0},
   297  			{&t3, &t1, -1},
   298  			{&t2, &t3, 1},
   299  			{nil, &t1, 1},
   300  			{&t2, nil, -1},
   301  			{nil, nil, 0},
   302  		}
   303  
   304  		for i, p := range params {
   305  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   306  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   307  			})
   308  		}
   309  	})
   310  }
   311  
   312  func TestBasicComparator_DateArray(t *testing.T) {
   313  	t1 := time.Now()
   314  	t2 := time.Now().Add(time.Second)
   315  	t3 := time.Now().Add(2 * time.Second)
   316  	t4 := time.Now().Add(3 * time.Second)
   317  
   318  	t_3_2_1 := []time.Time{t3, t2, t1}
   319  	t_4 := []time.Time{t4}
   320  	t_3_1 := []time.Time{t3, t1}
   321  	t_3_2 := []time.Time{t3, t2}
   322  
   323  	t.Run("dates array asc", func(t *testing.T) {
   324  		comp := newDateArrayComparator("asc")
   325  
   326  		params := []struct {
   327  			a        *[]time.Time
   328  			b        *[]time.Time
   329  			expected int
   330  		}{
   331  			{&t_3_2_1, &t_3_2_1, 0},
   332  			{&t_4, &t_4, 0},
   333  			{&t_3_1, &t_3_1, 0},
   334  			{&t_3_2, &t_3_2, 0},
   335  			{&t_3_1, &t_3_2, -1},
   336  			{&t_3_2, &t_3_2_1, -1},
   337  			{&t_4, &t_3_2_1, 1},
   338  			{nil, &t_3_1, -1},
   339  			{&t_4, nil, 1},
   340  			{nil, nil, 0},
   341  		}
   342  
   343  		for i, p := range params {
   344  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   345  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   346  			})
   347  		}
   348  	})
   349  
   350  	t.Run("dates array desc", func(t *testing.T) {
   351  		comp := newDateArrayComparator("desc")
   352  
   353  		params := []struct {
   354  			a        *[]time.Time
   355  			b        *[]time.Time
   356  			expected int
   357  		}{
   358  			{&t_3_2_1, &t_3_2_1, 0},
   359  			{&t_4, &t_4, 0},
   360  			{&t_3_1, &t_3_1, 0},
   361  			{&t_3_2, &t_3_2, 0},
   362  			{&t_3_1, &t_3_2, 1},
   363  			{&t_3_2, &t_3_2_1, 1},
   364  			{&t_4, &t_3_2_1, -1},
   365  			{nil, &t_3_1, 1},
   366  			{&t_4, nil, -1},
   367  			{nil, nil, 0},
   368  		}
   369  
   370  		for i, p := range params {
   371  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   372  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   373  			})
   374  		}
   375  	})
   376  }
   377  
   378  func TestBasicComparator_Bool(t *testing.T) {
   379  	fa := false
   380  	tr := true
   381  
   382  	t.Run("bools asc", func(t *testing.T) {
   383  		comp := newBoolComparator("asc")
   384  
   385  		params := []struct {
   386  			a        *bool
   387  			b        *bool
   388  			expected int
   389  		}{
   390  			{&fa, &fa, 0},
   391  			{&tr, &tr, 0},
   392  			{&fa, &tr, -1},
   393  			{nil, &fa, -1},
   394  			{&tr, nil, 1},
   395  			{nil, nil, 0},
   396  		}
   397  
   398  		for i, p := range params {
   399  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   400  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   401  			})
   402  		}
   403  	})
   404  
   405  	t.Run("bools desc", func(t *testing.T) {
   406  		comp := newBoolComparator("desc")
   407  
   408  		params := []struct {
   409  			a        *bool
   410  			b        *bool
   411  			expected int
   412  		}{
   413  			{&fa, &fa, 0},
   414  			{&tr, &tr, 0},
   415  			{&fa, &tr, 1},
   416  			{nil, &fa, 1},
   417  			{&tr, nil, -1},
   418  			{nil, nil, 0},
   419  		}
   420  
   421  		for i, p := range params {
   422  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   423  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   424  			})
   425  		}
   426  	})
   427  }
   428  
   429  func TestBasicComparator_BoolArray(t *testing.T) {
   430  	fa_tr_fa := []bool{false, true, false}
   431  	tr := []bool{true}
   432  	fa_fa := []bool{false, false}
   433  	fa_tr := []bool{false, true}
   434  
   435  	t.Run("bools array asc", func(t *testing.T) {
   436  		comp := newBoolArrayComparator("asc")
   437  
   438  		params := []struct {
   439  			a        *[]bool
   440  			b        *[]bool
   441  			expected int
   442  		}{
   443  			{&fa_tr_fa, &fa_tr_fa, 0},
   444  			{&tr, &tr, 0},
   445  			{&fa_fa, &fa_fa, 0},
   446  			{&fa_tr, &fa_tr, 0},
   447  			{&fa_fa, &fa_tr, -1},
   448  			{&fa_tr, &fa_tr_fa, -1},
   449  			{&tr, &fa_tr_fa, 1},
   450  			{nil, &fa_fa, -1},
   451  			{&tr, nil, 1},
   452  			{nil, nil, 0},
   453  		}
   454  
   455  		for i, p := range params {
   456  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   457  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   458  			})
   459  		}
   460  	})
   461  
   462  	t.Run("bools array desc", func(t *testing.T) {
   463  		comp := newBoolArrayComparator("desc")
   464  
   465  		params := []struct {
   466  			a        *[]bool
   467  			b        *[]bool
   468  			expected int
   469  		}{
   470  			{&fa_tr_fa, &fa_tr_fa, 0},
   471  			{&tr, &tr, 0},
   472  			{&fa_fa, &fa_fa, 0},
   473  			{&fa_tr, &fa_tr, 0},
   474  			{&fa_fa, &fa_tr, 1},
   475  			{&fa_tr, &fa_tr_fa, 1},
   476  			{&tr, &fa_tr_fa, -1},
   477  			{nil, &fa_fa, 1},
   478  			{&tr, nil, -1},
   479  			{nil, nil, 0},
   480  		}
   481  
   482  		for i, p := range params {
   483  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   484  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   485  			})
   486  		}
   487  	})
   488  }
   489  
   490  func TestBasicComparator_Int(t *testing.T) {
   491  	i_10 := -10
   492  	i100 := 100
   493  	i0 := 0
   494  
   495  	t.Run("ints asc", func(t *testing.T) {
   496  		comp := newIntComparator("asc")
   497  
   498  		params := []struct {
   499  			a        *int
   500  			b        *int
   501  			expected int
   502  		}{
   503  			{&i_10, &i_10, 0},
   504  			{&i100, &i100, 0},
   505  			{&i0, &i0, 0},
   506  			{&i100, &i_10, 1},
   507  			{&i0, &i100, -1},
   508  			{nil, &i_10, -1},
   509  			{&i0, nil, 1},
   510  			{nil, nil, 0},
   511  		}
   512  
   513  		for i, p := range params {
   514  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   515  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   516  			})
   517  		}
   518  	})
   519  
   520  	t.Run("ints desc", func(t *testing.T) {
   521  		comp := newIntComparator("desc")
   522  
   523  		params := []struct {
   524  			a        *int
   525  			b        *int
   526  			expected int
   527  		}{
   528  			{&i_10, &i_10, 0},
   529  			{&i100, &i100, 0},
   530  			{&i0, &i0, 0},
   531  			{&i100, &i_10, -1},
   532  			{&i0, &i100, 1},
   533  			{nil, &i_10, 1},
   534  			{&i0, nil, -1},
   535  			{nil, nil, 0},
   536  		}
   537  
   538  		for i, p := range params {
   539  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   540  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   541  			})
   542  		}
   543  	})
   544  }
   545  
   546  func TestBasicComparator_Any(t *testing.T) {
   547  	in := -10
   548  	fl := 100.0
   549  	st := "string"
   550  	ti := time.Now()
   551  	bo := true
   552  	an := struct{}{}
   553  
   554  	t.Run("any asc", func(t *testing.T) {
   555  		comp := newAnyComparator("asc")
   556  
   557  		params := []struct {
   558  			a        interface{}
   559  			b        interface{}
   560  			expected int
   561  		}{
   562  			{&in, &in, 0},
   563  			{&fl, &fl, 0},
   564  			{&st, &st, 0},
   565  			{&ti, &ti, 0},
   566  			{&bo, &bo, 0},
   567  			{&an, &an, 0},
   568  			{&in, &fl, 0},
   569  			{&fl, &st, 0},
   570  			{&st, &ti, 0},
   571  			{&ti, &bo, 0},
   572  			{&bo, &an, 0},
   573  			{&an, &in, 0},
   574  			{nil, &in, -1},
   575  			{nil, &fl, -1},
   576  			{nil, &st, -1},
   577  			{&ti, nil, 1},
   578  			{&bo, nil, 1},
   579  			{&an, nil, 1},
   580  			{nil, nil, 0},
   581  		}
   582  
   583  		for i, p := range params {
   584  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   585  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   586  			})
   587  		}
   588  	})
   589  
   590  	t.Run("any desc", func(t *testing.T) {
   591  		comp := newAnyComparator("desc")
   592  
   593  		params := []struct {
   594  			a        interface{}
   595  			b        interface{}
   596  			expected int
   597  		}{
   598  			{&in, &in, 0},
   599  			{&fl, &fl, 0},
   600  			{&st, &st, 0},
   601  			{&ti, &ti, 0},
   602  			{&bo, &bo, 0},
   603  			{&an, &an, 0},
   604  			{&in, &fl, 0},
   605  			{&fl, &st, 0},
   606  			{&st, &ti, 0},
   607  			{&ti, &bo, 0},
   608  			{&bo, &an, 0},
   609  			{&an, &in, 0},
   610  			{nil, &in, 1},
   611  			{nil, &fl, 1},
   612  			{nil, &st, 1},
   613  			{&ti, nil, -1},
   614  			{&bo, nil, -1},
   615  			{&an, nil, -1},
   616  			{nil, nil, 0},
   617  		}
   618  
   619  		for i, p := range params {
   620  			t.Run(fmt.Sprintf("data #%d", i), func(t *testing.T) {
   621  				assert.Equal(t, p.expected, comp.compare(p.a, p.b))
   622  			})
   623  		}
   624  	})
   625  }