github.com/0chain/gosdk@v1.17.11/zboxcore/zboxutil/uint128_test.go (about)

     1  package zboxutil
     2  
     3  import (
     4  	"math"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func TestNewUint128(t *testing.T) {
    12  	type args struct {
    13  		x uint64
    14  	}
    15  	tests := []struct {
    16  		name string
    17  		args args
    18  		want Uint128
    19  	}{
    20  		{
    21  			name: "OK",
    22  			args: args{x: 5},
    23  			want: Uint128{
    24  				Low: 5,
    25  			},
    26  		},
    27  		{
    28  			name: "0_OK",
    29  			args: args{x: 0},
    30  			want: Uint128{
    31  				Low: 0,
    32  			},
    33  		},
    34  		{
    35  			name: "Max_OK",
    36  			args: args{x: math.MaxUint64},
    37  			want: Uint128{
    38  				Low: math.MaxUint64,
    39  			},
    40  		},
    41  	}
    42  	for _, tt := range tests {
    43  		t.Run(tt.name, func(t *testing.T) {
    44  			if got := NewUint128(tt.args.x); !reflect.DeepEqual(got, tt.want) {
    45  				t.Errorf("NewUint128() = %v, want %v", got, tt.want)
    46  			}
    47  		})
    48  	}
    49  }
    50  
    51  func TestUint128_Add(t *testing.T) {
    52  	tests := []struct {
    53  		x         Uint128
    54  		y         Uint128
    55  		want      Uint128
    56  		wantPanic bool
    57  	}{
    58  		{},
    59  		{
    60  			x: NewUint128(^uint64(0)),
    61  			y: NewUint128(1),
    62  			want: Uint128{
    63  				High: 1,
    64  				Low:  0,
    65  			},
    66  		},
    67  		{
    68  			x: NewUint128(^uint64(0)),
    69  			y: NewUint128(^uint64(0)),
    70  			want: Uint128{
    71  				High: 1,
    72  				Low:  ^uint64(0) - 1,
    73  			},
    74  		},
    75  		{
    76  			x: Uint128{
    77  				Low:  ^uint64(0),
    78  				High: ^uint64(0),
    79  			},
    80  			y:         NewUint128(1),
    81  			wantPanic: true,
    82  		},
    83  	}
    84  	for _, tt := range tests {
    85  		func() {
    86  			defer func() {
    87  				pan := recover()
    88  				assert.True(t, tt.wantPanic != (pan == nil))
    89  			}()
    90  
    91  			if got := tt.x.Add(tt.y); !reflect.DeepEqual(got, tt.want) {
    92  				t.Errorf("Add() = %v, want %v", got, tt.want)
    93  			}
    94  		}()
    95  	}
    96  }
    97  
    98  func TestUint128_Add64(t *testing.T) {
    99  	testData := []struct {
   100  		num       Uint128
   101  		expected  Uint128
   102  		add       uint64
   103  		wantPanic bool
   104  	}{
   105  		{Uint128{0, 0}, Uint128{0, 1}, 1, false},
   106  		{Uint128{18446744073709551615, 18446744073709551614}, Uint128{18446744073709551615, 18446744073709551615}, 1, false},
   107  		{Uint128{0, 18446744073709551615}, Uint128{1, 0}, 1, false},
   108  		{Uint128{18446744073709551615, 0}, Uint128{18446744073709551615, 1}, 1, false},
   109  		{Uint128{0, 18446744073709551615}, Uint128{1, 24}, 25, false},
   110  		{Uint128{^uint64(0), ^uint64(0)}, Uint128{}, 1, true},
   111  	}
   112  
   113  	for _, test := range testData {
   114  		func() {
   115  			defer func() {
   116  				pan := recover()
   117  				assert.True(t, test.wantPanic != (pan == nil))
   118  			}()
   119  			res := test.num.Add64(test.add)
   120  			if res != test.expected {
   121  				t.Errorf("expected: %v + %d = %v but got %v", test.num, test.add, test.expected, res)
   122  			}
   123  		}()
   124  	}
   125  }
   126  
   127  func TestUint128_Equals(t *testing.T) {
   128  	testData := []struct {
   129  		u1       Uint128
   130  		u2       Uint128
   131  		expected bool
   132  	}{
   133  		{Uint128{0, 0}, Uint128{0, 1}, false},
   134  		{Uint128{1, 0}, Uint128{0, 1}, false},
   135  		{Uint128{18446744073709551615, 18446744073709551614}, Uint128{18446744073709551615, 18446744073709551615}, false},
   136  		{Uint128{0, 1}, Uint128{0, 1}, true},
   137  		{Uint128{0, 0}, Uint128{0, 0}, true},
   138  		{Uint128{314, 0}, Uint128{314, 0}, true},
   139  		{Uint128{18446744073709551615, 18446744073709551615}, Uint128{18446744073709551615, 18446744073709551615}, true},
   140  	}
   141  
   142  	for _, test := range testData {
   143  		if actual := test.u1.Equals(test.u2); actual != test.expected {
   144  			t.Errorf("expected: %v.Equals(%v) expected %v but got %v", test.u1, test.u2, test.expected, actual)
   145  		}
   146  	}
   147  }
   148  
   149  func TestUint128_And(t *testing.T) {
   150  	u1 := Uint128{14799720563850130797, 11152134164166830811}
   151  	u2 := Uint128{10868624793753271583, 6542293553298186666}
   152  
   153  	expected := Uint128{9529907221165552909, 1927615693132931210}
   154  	if !(u1.And(u2)).Equals(expected) {
   155  		t.Errorf("incorrect AND computation: %v & %v != %v", u1, u2, expected)
   156  	}
   157  }
   158  
   159  func TestUint128_Or64(t *testing.T) {
   160  	u1 := Uint128{14799720563850130797, 11152134164166830811}
   161  	u2 := Uint128{10868624793753271583, 6542293553298186666}
   162  
   163  	expected := Uint128{16138438136437849471, 15766812024332086267}
   164  	if !(u1.Or(u2)).Equals(expected) {
   165  		t.Errorf("incorrect OR computation: %v | %v != %v", u1, u2, expected)
   166  	}
   167  }
   168  
   169  func TestUint128_Xor(t *testing.T) {
   170  	u1 := Uint128{14799720563850130797, 11152134164166830811}
   171  	u2 := Uint128{10868624793753271583, 6542293553298186666}
   172  
   173  	expected := Uint128{6608530915272296562, 13839196331199155057}
   174  	if !(u1.Xor(u2)).Equals(expected) {
   175  		t.Errorf("incorrect XOR computation: %v ^ %v != %v", u1, u2, expected)
   176  	}
   177  }
   178  
   179  func TestUint128_Sub(t *testing.T) {
   180  	testData := []struct {
   181  		num      Uint128
   182  		expected Uint128
   183  		sub      Uint128
   184  	}{
   185  		{Uint128{0, 1}, Uint128{0, 0}, NewUint128(1)},
   186  		{Uint128{18446744073709551615, 18446744073709551615}, Uint128{18446744073709551615, 18446744073709551614}, NewUint128(1)},
   187  		{Uint128{0, 18446744073709551615}, Uint128{0, 18446744073709551614}, NewUint128(1)},
   188  		{Uint128{18446744073709551615, 0}, Uint128{18446744073709551614, 18446744073709551615}, NewUint128(1)},
   189  		{Uint128{18446744073709551615, 0}, Uint128{18446744073709551614, 18446744073709551591}, NewUint128(25)},
   190  		{Uint128{0, 0}, Uint128{18446744073709551615, 18446744073709551615}, Uint128{0, 1}},
   191  	}
   192  
   193  	for _, test := range testData {
   194  
   195  		res := test.num.Sub(test.sub)
   196  		if res != test.expected {
   197  			t.Errorf("expected: %v - %d = %v but got %v", test.num, test.sub, test.expected, res)
   198  		}
   199  	}
   200  }
   201  
   202  func TestUint128_Sub64(t *testing.T) {
   203  	testData := []struct {
   204  		num      Uint128
   205  		expected Uint128
   206  		sub      uint64
   207  	}{
   208  		{Uint128{0, 1}, Uint128{0, 0}, 1},
   209  		{Uint128{18446744073709551615, 18446744073709551615}, Uint128{18446744073709551615, 18446744073709551614}, 1},
   210  		{Uint128{0, 18446744073709551615}, Uint128{0, 18446744073709551614}, 1},
   211  		{Uint128{18446744073709551615, 0}, Uint128{18446744073709551614, 18446744073709551615}, 1},
   212  		{Uint128{18446744073709551615, 0}, Uint128{18446744073709551614, 18446744073709551591}, 25},
   213  		{Uint128{0, 0}, Uint128{18446744073709551615, 18446744073709551615}, 1},
   214  	}
   215  
   216  	for _, test := range testData {
   217  		res := test.num.Sub64(test.sub)
   218  		if res != test.expected {
   219  			t.Errorf("expected: %v - %d = %v but got %v", test.num, test.sub, test.expected, res)
   220  		}
   221  	}
   222  }
   223  
   224  func TestUint128_Equals64(t *testing.T) {
   225  	testData := []struct {
   226  		u1       Uint128
   227  		u2       uint64
   228  		expected bool
   229  	}{
   230  		{Uint128{0, 0}, 1, false},
   231  		{Uint128{1, 0}, 1, false},
   232  		{Uint128{18446744073709551615, 18446744073709551614}, 18446744073709551615, false},
   233  		{Uint128{0, 1}, 1, true},
   234  		{Uint128{0, 0}, 0, true},
   235  	}
   236  
   237  	for _, test := range testData {
   238  		if actual := test.u1.Equals64(test.u2); actual != test.expected {
   239  			t.Errorf("expected: %v.Equals64(%v) expected %v but got %v", test.u1, test.u2, test.expected, actual)
   240  		}
   241  	}
   242  }
   243  
   244  func TestUint128_And64(t *testing.T) {
   245  	var (
   246  		u1        = Uint128{14799720563850130797, 11152134164166830811}
   247  		u2 uint64 = 6542293553298186666
   248  	)
   249  
   250  	expected := Uint128{0, 1927615693132931210}
   251  	if !u1.And64(u2).Equals(expected) {
   252  		t.Errorf("incorrect AND computation: %v & %v != %v", u1, u2, expected)
   253  	}
   254  }
   255  
   256  func TestUint128_Lsh(t *testing.T) {
   257  	testData := []struct {
   258  		u1       Uint128
   259  		u2       uint64
   260  		expected Uint128
   261  	}{
   262  		{Uint128{0, 1}, 5, Uint128{0, 32}},
   263  		{Uint128{0, 1}, 63, Uint128{0, 1 << 63}},
   264  		{Uint128{0, 1}, 64, Uint128{1, 0}},
   265  		{Uint128{0, 1}, 127, Uint128{1 << 63, 0}},
   266  	}
   267  
   268  	for _, test := range testData {
   269  		if actual := test.u1.Lsh(test.u2); actual != test.expected {
   270  			t.Errorf("expected: %v.Lsn(%v) expected %v but got %v", test.u1, test.u2, test.expected, actual)
   271  		}
   272  	}
   273  }
   274  
   275  func TestUint128_Not(t *testing.T) {
   276  	testData := []struct {
   277  		u1       Uint128
   278  		expected Uint128
   279  	}{
   280  		{Uint128{0, 0}, Uint128{^uint64(0), ^uint64(0)}},
   281  		{Uint128{0, 1}, Uint128{^uint64(0), ^uint64(1)}},
   282  		{Uint128{1, 0}, Uint128{^uint64(1), ^uint64(0)}},
   283  	}
   284  
   285  	for _, test := range testData {
   286  		if actual := test.u1.Not(); actual != test.expected {
   287  			t.Errorf("expected: %v.Not() expected %v but got %v", test.u1, test.expected, actual)
   288  		}
   289  	}
   290  }
   291  
   292  func TestUint128_CountOnes(t *testing.T) {
   293  	testData := []struct {
   294  		u1       Uint128
   295  		expected int
   296  	}{
   297  		{Uint128{0, ^uint64(0)}, 64},
   298  		{Uint128{^uint64(0), 1}, 65},
   299  		{Uint128{^uint64(0), ^uint64(0)}, 128},
   300  		{Uint128{0, 0}, 0},
   301  	}
   302  
   303  	for _, test := range testData {
   304  		if actual := test.u1.CountOnes(); actual != test.expected {
   305  			t.Errorf("expected: %v.CountOnes() expected %v but got %v", test.u1, test.expected, actual)
   306  		}
   307  	}
   308  }
   309  
   310  func TestUint128_TrailingZeros(t *testing.T) {
   311  	testData := []struct {
   312  		u1       Uint128
   313  		expected int
   314  	}{
   315  		{Uint128{0, ^uint64(0)}, 0},
   316  		{Uint128{0, 1 << 63}, 63},
   317  		{Uint128{1 << 63, 0}, 127},
   318  		{Uint128{0, 0}, 128},
   319  	}
   320  
   321  	for _, test := range testData {
   322  		if actual := test.u1.TrailingZeros(); actual != test.expected {
   323  			t.Errorf("expected: %v.TrailingZeros() expected %v but got %v", test.u1, test.expected, actual)
   324  		}
   325  	}
   326  }