github.com/mitranim/gg@v0.1.17/comparison_test.go (about)

     1  package gg_test
     2  
     3  import (
     4  	r "reflect"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/mitranim/gg"
     9  	"github.com/mitranim/gg/gtest"
    10  )
    11  
    12  var testArr32_0 = [4]byte{0x00, 0x2e, 0x7a, 0xb0}
    13  var testArr32_1 = [4]byte{0x4b, 0x38, 0xa9, 0x65}
    14  var testArr64_0 = [8]byte{0x00, 0x2e, 0x7a, 0xb0, 0xef, 0x3f, 0x44, 0x88}
    15  var testArr64_1 = [8]byte{0x4b, 0x38, 0xa9, 0x65, 0x13, 0x0d, 0x46, 0x29}
    16  var testArr128_0 = [16]byte{0x00, 0x2e, 0x7a, 0xb0, 0xef, 0x3f, 0x44, 0x88, 0x95, 0x88, 0xc1, 0xf1, 0x10, 0xeb, 0xc2, 0x08}
    17  var testArr128_1 = [16]byte{0x4b, 0x38, 0xa9, 0x65, 0x13, 0x0d, 0x46, 0x29, 0xb7, 0x98, 0xd8, 0x69, 0x6f, 0xdf, 0xc7, 0xf2}
    18  var testArr192_0 = [32]byte{0x00, 0x2e, 0x7a, 0xb0, 0xef, 0x3f, 0x44, 0x88, 0x95, 0x88, 0xc1, 0xf1, 0x10, 0xeb, 0xc2, 0x08, 0xe9, 0x68, 0x33, 0x30, 0xb3, 0xdb, 0x4b, 0x82}
    19  var testArr192_1 = [32]byte{0x4b, 0x38, 0xa9, 0x65, 0x13, 0x0d, 0x46, 0x29, 0xb7, 0x98, 0xd8, 0x69, 0x6f, 0xdf, 0xc7, 0xf2, 0x41, 0x50, 0xd4, 0xc4, 0x4f, 0x45, 0x45, 0x13}
    20  var testArr256_0 = [32]byte{0x00, 0x2e, 0x7a, 0xb0, 0xef, 0x3f, 0x44, 0x88, 0x95, 0x88, 0xc1, 0xf1, 0x10, 0xeb, 0xc2, 0x08, 0xe9, 0x68, 0x33, 0x30, 0xb3, 0xdb, 0x4b, 0x82, 0x8e, 0x1d, 0xb5, 0xe5, 0x1a, 0x90, 0xe4, 0xa2}
    21  var testArr256_1 = [32]byte{0x4b, 0x38, 0xa9, 0x65, 0x13, 0x0d, 0x46, 0x29, 0xb7, 0x98, 0xd8, 0x69, 0x6f, 0xdf, 0xc7, 0xf2, 0x41, 0x50, 0xd4, 0xc4, 0x4f, 0x45, 0x45, 0x13, 0x81, 0xce, 0x33, 0xcb, 0x28, 0x13, 0x17, 0x32}
    22  
    23  func TestIsZero(t *testing.T) {
    24  	defer gtest.Catch(t)
    25  
    26  	gtest.True(gg.IsZero(0))
    27  	gtest.False(gg.IsZero(1))
    28  	gtest.False(gg.IsZero(-1))
    29  
    30  	gtest.True(gg.IsZero(``))
    31  	gtest.False(gg.IsZero(` `))
    32  
    33  	gtest.True(gg.IsZero([]string(nil)))
    34  	gtest.False(gg.IsZero([]string{}))
    35  
    36  	t.Run(`method`, func(t *testing.T) {
    37  		defer gtest.Catch(t)
    38  
    39  		gtest.True(gg.IsZero[IsZeroAlwaysTrue](``))
    40  		gtest.True(gg.IsZero[IsZeroAlwaysFalse](``))
    41  		gtest.True(gg.IsZero[IsZeroAlwaysTrue](`str`))
    42  		gtest.False(gg.IsZero[IsZeroAlwaysFalse](`str`))
    43  
    44  		gtest.True(gg.IsZero(r.ValueOf(nil)))
    45  		gtest.True(gg.IsZero(r.ValueOf(``)))
    46  		gtest.False(gg.IsZero(r.ValueOf(`str`)))
    47  	})
    48  
    49  	t.Run(`time`, func(t *testing.T) {
    50  		defer gtest.Catch(t)
    51  
    52  		const minSec = 60
    53  		const hourMin = 60
    54  		const offsetHour = 1
    55  
    56  		local := time.FixedZone(`local`, minSec*hourMin*offsetHour)
    57  
    58  		testZero := func(src time.Time) {
    59  			gtest.True(src.IsZero())
    60  			gtest.True(gg.IsZero(src))
    61  			gtest.Eq(gg.IsZero(src), src.IsZero())
    62  		}
    63  
    64  		testZero(time.Time{})
    65  		testZero(time.Time{}.In(time.UTC))
    66  		testZero(time.Time{}.In(local))
    67  
    68  		gtest.Eq(time.Time{}, time.Time{}.In(time.UTC))
    69  		gtest.NotEq(time.Time{}, time.Time{}.In(local))
    70  
    71  		gtest.Eq(
    72  			time.Date(1, 1, 1, offsetHour, 0, 0, 0, local),
    73  			time.Time{}.In(local),
    74  		)
    75  
    76  		gtest.True(gg.IsZero(time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)))
    77  		gtest.True(gg.IsZero(time.Date(1, 1, 1, offsetHour, 0, 0, 0, local)))
    78  
    79  		gtest.False(gg.IsZero(time.Date(1, 1, 1, 0, 0, 0, 1, time.UTC)))
    80  		gtest.False(gg.IsZero(time.Date(1, 1, 0, 0, 0, 0, 1, local)))
    81  	})
    82  
    83  	t.Run(`struct_inner_field_fake_zero`, func(t *testing.T) {
    84  		defer gtest.Catch(t)
    85  
    86  		{
    87  			var tar FatStruct
    88  			tar.Name = `str`[:0]
    89  			gtest.True(gg.IsZero(tar))
    90  		}
    91  
    92  		{
    93  			var tar FatStructNonComparable
    94  			tar.Name = `str`[:0]
    95  			gtest.True(gg.IsZero(tar))
    96  		}
    97  	})
    98  }
    99  
   100  // This is a control. Our version should be significantly more efficient.
   101  func Benchmark_is_zero_reflect_fat_struct_zero(b *testing.B) {
   102  	var val FatStruct
   103  
   104  	for ind := 0; ind < b.N; ind++ {
   105  		gg.Nop1(r.ValueOf(val).IsZero())
   106  	}
   107  }
   108  
   109  // This is a control. Our version should be significantly more efficient.
   110  func Benchmark_is_zero_reflect_fat_struct_non_zero(b *testing.B) {
   111  	val := FatStruct{Id: 10}
   112  
   113  	for ind := 0; ind < b.N; ind++ {
   114  		gg.Nop1(r.ValueOf(val).IsZero())
   115  	}
   116  }
   117  
   118  func Benchmark_is_zero_IsZero_fat_struct_zero(b *testing.B) {
   119  	var val FatStruct
   120  
   121  	for ind := 0; ind < b.N; ind++ {
   122  		gg.Nop1(gg.IsZero(val))
   123  	}
   124  }
   125  
   126  func Benchmark_is_zero_IsZero_fat_struct_non_zero(b *testing.B) {
   127  	val := FatStruct{Id: 10}
   128  
   129  	for ind := 0; ind < b.N; ind++ {
   130  		gg.Nop1(gg.IsZero(val))
   131  	}
   132  }
   133  
   134  func Benchmark_is_zero_IsZero_fat_struct_non_comparable_zero(b *testing.B) {
   135  	var val FatStructNonComparable
   136  
   137  	for ind := 0; ind < b.N; ind++ {
   138  		gg.Nop1(gg.IsZero(val))
   139  	}
   140  }
   141  
   142  func Benchmark_is_zero_IsZero_fat_struct_non_comparable_non_zero(b *testing.B) {
   143  	var val FatStructNonComparable
   144  	val.Id = 10
   145  
   146  	for ind := 0; ind < b.N; ind++ {
   147  		gg.Nop1(gg.IsZero(val))
   148  	}
   149  }
   150  
   151  func Benchmark_is_zero_IsZero_time_Time_zero(b *testing.B) {
   152  	for ind := 0; ind < b.N; ind++ {
   153  		gg.Nop1(gg.IsZero(time.Time{}))
   154  	}
   155  }
   156  
   157  func Benchmark_is_zero_IsZero_time_Time_non_zero(b *testing.B) {
   158  	inst := time.Now()
   159  
   160  	for ind := 0; ind < b.N; ind++ {
   161  		gg.Nop1(gg.IsZero(inst))
   162  	}
   163  }
   164  
   165  func Benchmark_is_zero_method_time_Time(b *testing.B) {
   166  	inst := time.Now()
   167  
   168  	for ind := 0; ind < b.N; ind++ {
   169  		gg.Nop1(inst.IsZero())
   170  	}
   171  }
   172  
   173  func Benchmark_is_zero_string_non_zero(b *testing.B) {
   174  	val := `some_string`
   175  
   176  	for ind := 0; ind < b.N; ind++ {
   177  		gg.Nop1(gg.IsZero(val))
   178  	}
   179  }
   180  
   181  func Benchmark_is_zero_int_non_zero(b *testing.B) {
   182  	val := 123
   183  
   184  	for ind := 0; ind < b.N; ind++ {
   185  		gg.Nop1(gg.IsZero(val))
   186  	}
   187  }
   188  
   189  func TestIsTrueZero(t *testing.T) {
   190  	defer gtest.Catch(t)
   191  
   192  	gtest.True(gg.IsTrueZero(false))
   193  	gtest.False(gg.IsTrueZero(true))
   194  
   195  	gtest.True(gg.IsTrueZero(byte(0)))
   196  	gtest.False(gg.IsTrueZero(byte(1)))
   197  
   198  	gtest.True(gg.IsTrueZero(0))
   199  	gtest.False(gg.IsTrueZero(1))
   200  
   201  	gtest.True(gg.IsTrueZero(``))
   202  	gtest.False(gg.IsTrueZero(`str`[:0]))
   203  
   204  	gtest.True(gg.IsTrueZero(FatStruct{}))
   205  	gtest.False(gg.IsTrueZero(FatStruct{Id: 1}))
   206  }
   207  
   208  func TestIs(t *testing.T) {
   209  	defer gtest.Catch(t)
   210  
   211  	gtest.True(gg.Is[int](10, 10))
   212  	gtest.False(gg.Is[int](10, 20))
   213  
   214  	gtest.True(gg.Is[any](10, 10))
   215  	gtest.False(gg.Is[any](10, 20))
   216  
   217  	var one int = 10
   218  	var two int = 10
   219  	gtest.True(gg.Is(one, one))
   220  	gtest.True(gg.Is(one, two))
   221  	gtest.True(gg.Is(&one, &one))
   222  	gtest.False(gg.Is(&one, &two))
   223  
   224  	gtest.True(gg.Is([1]byte{}, [1]byte{}))
   225  	gtest.True(gg.Is([2]byte{}, [2]byte{}))
   226  	gtest.True(gg.Is([4]byte{}, [4]byte{}))
   227  	gtest.True(gg.Is([8]byte{}, [8]byte{}))
   228  	gtest.True(gg.Is([16]byte{}, [16]byte{}))
   229  	gtest.True(gg.Is([32]byte{}, [32]byte{}))
   230  	gtest.True(gg.Is([64]byte{}, [64]byte{}))
   231  
   232  	gtest.True(gg.Is(testArr32_0, testArr32_0))
   233  	gtest.False(gg.Is(testArr32_0, testArr32_1))
   234  
   235  	gtest.True(gg.Is(testArr64_0, testArr64_0))
   236  	gtest.False(gg.Is(testArr64_0, testArr64_1))
   237  
   238  	gtest.True(gg.Is(testArr128_0, testArr128_0))
   239  	gtest.False(gg.Is(testArr128_0, testArr128_1))
   240  
   241  	gtest.True(gg.Is(testArr256_0, testArr256_0))
   242  	gtest.False(gg.Is(testArr256_0, testArr256_1))
   243  
   244  	// Nil slices must be identical regardless of the element type.
   245  	gtest.True(gg.Is([]struct{}(nil), []struct{}(nil)))
   246  	gtest.True(gg.Is([]int(nil), []int(nil)))
   247  	gtest.True(gg.Is([]string(nil), []string(nil)))
   248  
   249  	// Slices of zero-sized types and empty slices of non-zero-sized types are
   250  	// backed by the same "zerobase" pointer, which makes them identical.
   251  	// This may vary between Go implementations and versions.
   252  	gtest.True(gg.Is([]struct{}{}, []struct{}{}))
   253  	gtest.True(gg.Is(make([]struct{}, 128), make([]struct{}, 128)))
   254  	gtest.True(gg.Is([]int{}, []int{}))
   255  	gtest.True(gg.Is([]string{}, []string{}))
   256  
   257  	// Non-empty slices of non-zero-sized types must always be distinct.
   258  	gtest.False(gg.Is([]int{0}, []int{0}))
   259  	gtest.False(gg.Is([]string{``}, []string{``}))
   260  
   261  	// Even though strings are reference types, string constants may be identical
   262  	// when equal. The same may occur for interface values created from string
   263  	// constants. This may vary between Go implementations and versions.
   264  	gtest.True(gg.Is(``, ``))
   265  	gtest.True(gg.Is(`one`, `one`))
   266  	gtest.True(gg.Is[any](`one`, `one`))
   267  	gtest.False(gg.Is(`one`, `two`))
   268  	gtest.False(gg.Is[any](`one`, `two`))
   269  
   270  	// However, slicing string constants may produce strings which are equal but
   271  	// not identical. This may vary between Go implementations and versions.
   272  	gtest.True(`123_one`[3:] == `456_one`[3:])
   273  	gtest.False(gg.Is(`123_one`[3:], `456_one`[3:]))
   274  }
   275  
   276  func BenchmarkIs_ifaces(b *testing.B) {
   277  	for ind := 0; ind < b.N; ind++ {
   278  		gg.Nop1(gg.Is(any(nil), any(nil)))
   279  	}
   280  }
   281  
   282  func BenchmarkIs_slices(b *testing.B) {
   283  	for ind := 0; ind < b.N; ind++ {
   284  		gg.Nop1(gg.Is([]byte(nil), []byte(nil)))
   285  	}
   286  }
   287  
   288  func BenchmarkIs_array_32(b *testing.B) {
   289  	for ind := 0; ind < b.N; ind++ {
   290  		gg.Nop1(gg.Is(testArr32_0, testArr32_1))
   291  	}
   292  }
   293  
   294  func BenchmarkIs_array_64(b *testing.B) {
   295  	for ind := 0; ind < b.N; ind++ {
   296  		gg.Nop1(gg.Is(testArr64_0, testArr64_1))
   297  	}
   298  }
   299  
   300  func BenchmarkIs_array_128(b *testing.B) {
   301  	for ind := 0; ind < b.N; ind++ {
   302  		gg.Nop1(gg.Is(testArr128_0, testArr128_1))
   303  	}
   304  }
   305  
   306  func BenchmarkIs_array_192(b *testing.B) {
   307  	for ind := 0; ind < b.N; ind++ {
   308  		gg.Nop1(gg.Is(testArr192_0, testArr192_1))
   309  	}
   310  }
   311  
   312  func BenchmarkIs_array_256(b *testing.B) {
   313  	for ind := 0; ind < b.N; ind++ {
   314  		gg.Nop1(gg.Is(testArr256_0, testArr256_1))
   315  	}
   316  }
   317  
   318  func BenchmarkIs_struct_256(b *testing.B) {
   319  	type Type struct{ _, _, _, _ uint64 }
   320  
   321  	for ind := 0; ind < b.N; ind++ {
   322  		gg.Nop1(gg.Is(Type{}, Type{}))
   323  	}
   324  }
   325  
   326  func BenchmarkIs_struct_512(b *testing.B) {
   327  	type Type struct{ _, _, _, _, _, _, _, _ uint64 }
   328  
   329  	for ind := 0; ind < b.N; ind++ {
   330  		gg.Nop1(gg.Is(Type{}, Type{}))
   331  	}
   332  }
   333  
   334  func BenchmarkIs_struct_fat(b *testing.B) {
   335  	for ind := 0; ind < b.N; ind++ {
   336  		gg.Nop1(gg.Is(FatStruct{}, FatStruct{}))
   337  	}
   338  }
   339  
   340  func Benchmark_eq_operator(b *testing.B) {
   341  	for ind := 0; ind < b.N; ind++ {
   342  		gg.Nop1(ind == ind*2)
   343  	}
   344  }
   345  
   346  func BenchmarkEq_int(b *testing.B) {
   347  	for ind := 0; ind < b.N; ind++ {
   348  		gg.Nop1(gg.Eq(ind, ind*2))
   349  	}
   350  }
   351  
   352  func BenchmarkEq_array_64(b *testing.B) {
   353  	for ind := 0; ind < b.N; ind++ {
   354  		gg.Nop1(gg.Eq(testArr64_0, testArr64_1))
   355  	}
   356  }
   357  
   358  func BenchmarkEq_array_128(b *testing.B) {
   359  	for ind := 0; ind < b.N; ind++ {
   360  		gg.Nop1(gg.Eq(testArr128_0, testArr128_1))
   361  	}
   362  }
   363  
   364  func BenchmarkEq_array_256(b *testing.B) {
   365  	for ind := 0; ind < b.N; ind++ {
   366  		gg.Nop1(gg.Eq(testArr256_0, testArr256_1))
   367  	}
   368  }
   369  
   370  func Benchmark_reflect_DeepEqual_int(b *testing.B) {
   371  	one := 123
   372  	two := 123
   373  
   374  	for ind := 0; ind < b.N; ind++ {
   375  		gg.Nop1(r.DeepEqual(one, two))
   376  	}
   377  }
   378  
   379  func BenchmarkEqual_int(b *testing.B) {
   380  	one := 123
   381  	two := 123
   382  
   383  	for ind := 0; ind < b.N; ind++ {
   384  		gg.Nop1(gg.Equal(one, two))
   385  	}
   386  }
   387  
   388  func Benchmark_reflect_DeepEqual_bytes(b *testing.B) {
   389  	one := []byte(`one`)
   390  	two := []byte(`two`)
   391  
   392  	for ind := 0; ind < b.N; ind++ {
   393  		gg.Nop1(r.DeepEqual(one, two))
   394  	}
   395  }
   396  
   397  func BenchmarkEqual_bytes(b *testing.B) {
   398  	one := []byte(`one`)
   399  	two := []byte(`two`)
   400  
   401  	for ind := 0; ind < b.N; ind++ {
   402  		gg.Nop1(gg.Equal(one, two))
   403  	}
   404  }
   405  
   406  func Benchmark_reflect_DeepEqual_time_Time(b *testing.B) {
   407  	one := time.Date(1234, 5, 23, 12, 34, 56, 0, time.UTC)
   408  	two := time.Date(1234, 5, 23, 12, 34, 56, 0, time.UTC)
   409  
   410  	for ind := 0; ind < b.N; ind++ {
   411  		gg.Nop1(r.DeepEqual(one, two))
   412  	}
   413  }
   414  
   415  func BenchmarkEqual_time_Time(b *testing.B) {
   416  	one := time.Date(1234, 5, 23, 12, 34, 56, 0, time.UTC)
   417  	two := time.Date(1234, 5, 23, 12, 34, 56, 0, time.UTC)
   418  
   419  	for ind := 0; ind < b.N; ind++ {
   420  		gg.Nop1(gg.Equal(one, two))
   421  	}
   422  }
   423  
   424  func TestSliceIs(t *testing.T) {
   425  	defer gtest.Catch(t)
   426  
   427  	const msgNotIs = `expected given slice headers to be distinct, but they were identical`
   428  	const msgIs = `expected given slice headers to be identical, but they were distinct`
   429  
   430  	gtest.True(gg.SliceIs([]byte(nil), []byte(nil)))
   431  	gtest.True(gg.SliceIs([]string(nil), []string(nil)))
   432  
   433  	gtest.SliceIs([]byte(nil), []byte(nil))
   434  	gtest.SliceIs([]string(nil), []string(nil))
   435  
   436  	gtest.PanicStr(msgNotIs, func() { gtest.NotSliceIs([]byte(nil), []byte(nil)) })
   437  	gtest.PanicStr(msgNotIs, func() { gtest.NotSliceIs([]string(nil), []string(nil)) })
   438  
   439  	gtest.True(gg.SliceIs([]byte{}, []byte{}), `zerobase`)
   440  	gtest.True(gg.SliceIs([]string{}, []string{}), `zerobase`)
   441  
   442  	gtest.SliceIs([]byte{}, []byte{}, `zerobase`)
   443  	gtest.SliceIs([]string{}, []string{}, `zerobase`)
   444  
   445  	gtest.PanicStr(msgNotIs, func() { gtest.NotSliceIs([]byte{}, []byte{}) })
   446  	gtest.PanicStr(msgNotIs, func() { gtest.NotSliceIs([]string{}, []string{}) })
   447  
   448  	gtest.False(gg.SliceIs([]byte{0}, []byte{0}))
   449  	gtest.False(gg.SliceIs([]string{``}, []string{``}))
   450  
   451  	gtest.NotSliceIs([]byte{0}, []byte{0})
   452  	gtest.NotSliceIs([]string{``}, []string{``})
   453  
   454  	gtest.PanicStr(msgIs, func() { gtest.SliceIs([]byte{0}, []byte{0}) })
   455  	gtest.PanicStr(msgIs, func() { gtest.SliceIs([]string{``}, []string{``}) })
   456  }
   457  
   458  func BenchmarkSliceIs(b *testing.B) {
   459  	defer gtest.Catch(b)
   460  	src := nonEmptyByteSlice()
   461  	b.ResetTimer()
   462  
   463  	for ind := 0; ind < b.N; ind++ {
   464  		gg.SliceIs(src, src)
   465  	}
   466  }
   467  
   468  //go:noinline
   469  func nonEmptyByteSlice() []byte { return []byte(`one`) }
   470  
   471  func TestLess(t *testing.T) {
   472  	defer gtest.Catch(t)
   473  
   474  	gtest.True(gg.Less[Comparer[int]]())
   475  
   476  	gtest.True(gg.Less(ComparerOf(0)))
   477  	gtest.False(gg.Less(ComparerOf(0), ComparerOf(0)))
   478  
   479  	gtest.True(gg.Less(ComparerOf(0), ComparerOf(10)))
   480  	gtest.False(gg.Less(ComparerOf(0), ComparerOf(10), ComparerOf(10)))
   481  	gtest.False(gg.Less(ComparerOf(0), ComparerOf(0), ComparerOf(10)))
   482  
   483  	gtest.True(gg.Less(ComparerOf(0), ComparerOf(10), ComparerOf(20)))
   484  	gtest.False(gg.Less(ComparerOf(10), ComparerOf(0), ComparerOf(20)))
   485  	gtest.False(gg.Less(ComparerOf(20), ComparerOf(0), ComparerOf(10)))
   486  }
   487  
   488  func TestLessPrim(t *testing.T) {
   489  	defer gtest.Catch(t)
   490  
   491  	gtest.True(gg.LessPrim[int]())
   492  
   493  	gtest.True(gg.LessPrim(0))
   494  	gtest.False(gg.LessPrim(0, 0))
   495  
   496  	gtest.True(gg.LessPrim(0, 10))
   497  	gtest.False(gg.LessPrim(0, 10, 10))
   498  	gtest.False(gg.LessPrim(0, 0, 10))
   499  
   500  	gtest.True(gg.LessPrim(0, 10, 20))
   501  	gtest.False(gg.LessPrim(10, 0, 20))
   502  	gtest.False(gg.LessPrim(20, 0, 10))
   503  }
   504  
   505  func TestLessEq(t *testing.T) {
   506  	defer gtest.Catch(t)
   507  
   508  	gtest.True(gg.LessEq[Comparer[int]]())
   509  
   510  	gtest.True(gg.LessEq(ComparerOf(0)))
   511  	gtest.True(gg.LessEq(ComparerOf(0), ComparerOf(0)))
   512  
   513  	gtest.True(gg.LessEq(ComparerOf(0), ComparerOf(10)))
   514  	gtest.True(gg.LessEq(ComparerOf(0), ComparerOf(10), ComparerOf(10)))
   515  	gtest.True(gg.LessEq(ComparerOf(0), ComparerOf(0), ComparerOf(10)))
   516  
   517  	gtest.True(gg.LessEq(ComparerOf(0), ComparerOf(10), ComparerOf(20)))
   518  	gtest.False(gg.LessEq(ComparerOf(10), ComparerOf(0), ComparerOf(20)))
   519  	gtest.False(gg.LessEq(ComparerOf(20), ComparerOf(0), ComparerOf(10)))
   520  }
   521  
   522  func TestLessEqPrim(t *testing.T) {
   523  	defer gtest.Catch(t)
   524  
   525  	gtest.True(gg.LessEqPrim[int]())
   526  
   527  	gtest.True(gg.LessEqPrim(0))
   528  	gtest.True(gg.LessEqPrim(0, 0))
   529  
   530  	gtest.True(gg.LessEqPrim(0, 10))
   531  	gtest.True(gg.LessEqPrim(0, 10, 10))
   532  	gtest.True(gg.LessEqPrim(0, 0, 10))
   533  
   534  	gtest.True(gg.LessEqPrim(0, 10, 20))
   535  	gtest.False(gg.LessEqPrim(10, 0, 20))
   536  	gtest.False(gg.LessEqPrim(20, 0, 10))
   537  }
   538  
   539  func TestMinPrim2(t *testing.T) {
   540  	defer gtest.Catch(t)
   541  
   542  	gtest.Eq(gg.MinPrim2(10, 20), 10)
   543  	gtest.Eq(gg.MinPrim2(20, 10), 10)
   544  	gtest.Eq(gg.MinPrim2(-10, 10), -10)
   545  	gtest.Eq(gg.MinPrim2(10, -10), -10)
   546  	gtest.Eq(gg.MinPrim2(0, 10), 0)
   547  	gtest.Eq(gg.MinPrim2(10, 0), 0)
   548  	gtest.Eq(gg.MinPrim2(-10, 0), -10)
   549  	gtest.Eq(gg.MinPrim2(0, -10), -10)
   550  }
   551  
   552  func TestMaxPrim2(t *testing.T) {
   553  	defer gtest.Catch(t)
   554  
   555  	gtest.Eq(gg.MaxPrim2(10, 20), 20)
   556  	gtest.Eq(gg.MaxPrim2(20, 10), 20)
   557  	gtest.Eq(gg.MaxPrim2(-10, 10), 10)
   558  	gtest.Eq(gg.MaxPrim2(10, -10), 10)
   559  	gtest.Eq(gg.MaxPrim2(0, 10), 10)
   560  	gtest.Eq(gg.MaxPrim2(10, 0), 10)
   561  	gtest.Eq(gg.MaxPrim2(-10, 0), 0)
   562  	gtest.Eq(gg.MaxPrim2(0, -10), 0)
   563  }
   564  
   565  func TestMin2(t *testing.T) {
   566  	defer gtest.Catch(t)
   567  
   568  	gtest.Eq(gg.Min2(ComparerOf(10), ComparerOf(20)), ComparerOf(10))
   569  	gtest.Eq(gg.Min2(ComparerOf(20), ComparerOf(10)), ComparerOf(10))
   570  	gtest.Eq(gg.Min2(ComparerOf(-10), ComparerOf(10)), ComparerOf(-10))
   571  	gtest.Eq(gg.Min2(ComparerOf(10), ComparerOf(-10)), ComparerOf(-10))
   572  	gtest.Eq(gg.Min2(ComparerOf(0), ComparerOf(10)), ComparerOf(0))
   573  	gtest.Eq(gg.Min2(ComparerOf(10), ComparerOf(0)), ComparerOf(0))
   574  	gtest.Eq(gg.Min2(ComparerOf(-10), ComparerOf(0)), ComparerOf(-10))
   575  	gtest.Eq(gg.Min2(ComparerOf(0), ComparerOf(-10)), ComparerOf(-10))
   576  }
   577  
   578  func TestMax2(t *testing.T) {
   579  	defer gtest.Catch(t)
   580  
   581  	gtest.Eq(gg.Max2(ComparerOf(10), ComparerOf(20)), ComparerOf(20))
   582  	gtest.Eq(gg.Max2(ComparerOf(20), ComparerOf(10)), ComparerOf(20))
   583  	gtest.Eq(gg.Max2(ComparerOf(-10), ComparerOf(10)), ComparerOf(10))
   584  	gtest.Eq(gg.Max2(ComparerOf(10), ComparerOf(-10)), ComparerOf(10))
   585  	gtest.Eq(gg.Max2(ComparerOf(0), ComparerOf(10)), ComparerOf(10))
   586  	gtest.Eq(gg.Max2(ComparerOf(10), ComparerOf(0)), ComparerOf(10))
   587  	gtest.Eq(gg.Max2(ComparerOf(-10), ComparerOf(0)), ComparerOf(0))
   588  	gtest.Eq(gg.Max2(ComparerOf(0), ComparerOf(-10)), ComparerOf(0))
   589  }
   590  
   591  func BenchmarkMaxPrim2(b *testing.B) {
   592  	for ind := 0; ind < b.N; ind++ {
   593  		gg.Nop1(gg.MaxPrim2(10, 20))
   594  	}
   595  }
   596  
   597  func BenchmarkMax2(b *testing.B) {
   598  	for ind := 0; ind < b.N; ind++ {
   599  		gg.Nop1(gg.Max2(ComparerOf(10), ComparerOf(20)))
   600  	}
   601  }