code.vegaprotocol.io/vega@v0.79.0/libs/num/uint_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package num_test
    17  
    18  import (
    19  	"fmt"
    20  	"math/big"
    21  	"testing"
    22  
    23  	"code.vegaprotocol.io/vega/libs/num"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func TestUint256Constructors(t *testing.T) {
    30  	var expected uint64 = 42
    31  
    32  	t.Run("test from uint64", func(t *testing.T) {
    33  		n := num.NewUint(expected)
    34  		assert.Equal(t, expected, n.Uint64())
    35  	})
    36  
    37  	t.Run("test from string", func(t *testing.T) {
    38  		n, overflow := num.UintFromString("42", 10)
    39  		assert.False(t, overflow)
    40  		assert.Equal(t, expected, n.Uint64())
    41  	})
    42  
    43  	t.Run("test from big", func(t *testing.T) {
    44  		n, overflow := num.UintFromBig(big.NewInt(int64(expected)))
    45  		assert.False(t, overflow)
    46  		assert.Equal(t, expected, n.Uint64())
    47  	})
    48  }
    49  
    50  func TestUint256Serialization(t *testing.T) {
    51  	t.Run("JSON", func(t *testing.T) {
    52  		origin := "123456789123456789123456789"
    53  		n, _ := num.UintFromString(origin, 10)
    54  
    55  		// Serialize.
    56  		serialized, err := n.MarshalJSON()
    57  		require.NoError(t, err)
    58  
    59  		// Deserialize.
    60  		require.NoError(t, n.UnmarshalJSON(serialized))
    61  		assert.Equal(t, origin, n.String())
    62  	})
    63  
    64  	t.Run("Binary", func(t *testing.T) {
    65  		origin := "123456789123456789123456789"
    66  		n, _ := num.UintFromString(origin, 10)
    67  
    68  		// Serialize.
    69  		serialized, err := n.MarshalBinary()
    70  		require.NoError(t, err)
    71  
    72  		// Deserialize.
    73  		require.NoError(t, n.UnmarshalBinary(serialized))
    74  		assert.Equal(t, origin, n.String())
    75  	})
    76  
    77  	t.Run("Database", func(t *testing.T) {
    78  		origin := "123456789123456789123456789"
    79  		n, _ := num.UintFromString(origin, 10)
    80  
    81  		// Serialize.
    82  		serialized, err := n.Value()
    83  		require.NoError(t, err)
    84  
    85  		// Deserialize.
    86  		require.NoError(t, n.Scan(serialized))
    87  		assert.Equal(t, origin, n.String())
    88  	})
    89  }
    90  
    91  func TestUint256Clone(t *testing.T) {
    92  	var (
    93  		expect1 uint64 = 42
    94  		expect2 uint64 = 84
    95  		first          = num.NewUint(expect1)
    96  		second         = first.Clone()
    97  	)
    98  
    99  	assert.Equal(t, expect1, first.Uint64())
   100  	assert.Equal(t, expect1, second.Uint64())
   101  
   102  	// now we change second value, and ensure 1 hasn't changed
   103  	second.Add(second, num.NewUint(42))
   104  
   105  	assert.Equal(t, expect1, first.Uint64())
   106  	assert.Equal(t, expect2, second.Uint64())
   107  }
   108  
   109  func TestUint256Copy(t *testing.T) {
   110  	var (
   111  		expect1 uint64 = 42
   112  		expect2 uint64 = 84
   113  		first          = num.NewUint(expect1)
   114  		second         = num.NewUint(expect2)
   115  	)
   116  
   117  	assert.Equal(t, expect1, first.Uint64())
   118  	assert.Equal(t, expect2, second.Uint64())
   119  
   120  	// now we copy first into second
   121  	second.Copy(first)
   122  
   123  	// we check that first and second have the same value
   124  	assert.Equal(t, expect1, first.Uint64())
   125  	assert.Equal(t, expect1, second.Uint64())
   126  
   127  	// and now we will update first to have expect2 value
   128  	// and make sure it haven't changed second
   129  	first.SetUint64(expect2)
   130  	assert.Equal(t, expect2, first.Uint64())
   131  	assert.Equal(t, expect1, second.Uint64())
   132  }
   133  
   134  func TestUInt256IsZero(t *testing.T) {
   135  	zero := num.NewUint(0)
   136  	assert.True(t, zero.IsZero())
   137  }
   138  
   139  func TestUint256Print(t *testing.T) {
   140  	var (
   141  		expected = "42"
   142  		n        = num.NewUint(42)
   143  	)
   144  
   145  	assert.Equal(t, expected, fmt.Sprintf("%v", n))
   146  }
   147  
   148  func TestUint256Delta(t *testing.T) {
   149  	data := []struct {
   150  		x, y, z uint64
   151  		neg     bool
   152  	}{
   153  		{
   154  			x:   1234,
   155  			y:   1230,
   156  			z:   4,
   157  			neg: false,
   158  		},
   159  		{
   160  			x:   1230,
   161  			y:   1234,
   162  			z:   4,
   163  			neg: true,
   164  		},
   165  	}
   166  	for _, set := range data {
   167  		exp := num.NewUint(set.z)
   168  		x, y := num.NewUint(set.x), num.NewUint(set.y)
   169  		got, neg := num.NewUint(0).Delta(x, y)
   170  		assert.Equal(t, exp.String(), got.String())
   171  		assert.Equal(t, set.neg, neg)
   172  	}
   173  }
   174  
   175  func TestSum(t *testing.T) {
   176  	data := []struct {
   177  		x, y, z uint64
   178  		exp     uint64
   179  	}{
   180  		{
   181  			x:   1,
   182  			y:   2,
   183  			z:   3,
   184  			exp: 1 + 2 + 3,
   185  		},
   186  		{
   187  			x:   123,
   188  			y:   456,
   189  			z:   789,
   190  			exp: 123 + 456 + 789,
   191  		},
   192  	}
   193  	for _, set := range data {
   194  		x, y, z := num.NewUint(set.x), num.NewUint(set.y), num.NewUint(set.z)
   195  		exp := num.NewUint(set.exp)
   196  		zero := num.NewUint(0)
   197  		fSum := num.Sum(x, y, z)
   198  		assert.Equal(t, exp.String(), fSum.String())
   199  		ptr := zero.AddSum(x, y, z)
   200  		assert.Equal(t, exp.String(), zero.String())
   201  		assert.Equal(t, zero, ptr)
   202  		// compare to manual:
   203  		manual := num.NewUint(0)
   204  		manual = manual.Add(manual, x)
   205  		assert.NotEqual(t, exp.String(), manual.String(), "manual x only")
   206  		manual = manual.Add(manual, y)
   207  		assert.NotEqual(t, exp.String(), manual.String(), "manual x+y only")
   208  		manual = manual.Add(manual, z)
   209  		assert.Equal(t, exp.String(), manual.String())
   210  	}
   211  }
   212  
   213  func TestDeferDoCopy(t *testing.T) {
   214  	var (
   215  		expected1 uint64 = 42
   216  		expected2 uint64 = 84
   217  		n1               = num.NewUint(42)
   218  	)
   219  
   220  	n2 := *n1
   221  
   222  	assert.Equal(t, expected1, n1.Uint64())
   223  	assert.Equal(t, expected1, n2.Uint64())
   224  
   225  	n2.SetUint64(expected2)
   226  	assert.Equal(t, expected1, n1.Uint64())
   227  	assert.Equal(t, expected2, n2.Uint64())
   228  }
   229  
   230  func TestDeltaI(t *testing.T) {
   231  	n1 := num.NewUint(10)
   232  	n2 := num.NewUint(25)
   233  
   234  	r1 := num.UintZero().DeltaI(n1.Clone(), n2.Clone())
   235  	assert.Equal(t, "-15", r1.String())
   236  
   237  	r2 := num.UintZero().DeltaI(n2.Clone(), n1.Clone())
   238  	assert.Equal(t, "15", r2.String())
   239  }
   240  
   241  func TestMedian(t *testing.T) {
   242  	require.Nil(t, num.Median(nil))
   243  	require.Equal(t, "10", num.Median([]*num.Uint{num.NewUint(10)}).String())
   244  	require.Equal(t, "10", num.Median([]*num.Uint{num.NewUint(10), num.NewUint(5), num.NewUint(17)}).String())
   245  	require.Equal(t, "11", num.Median([]*num.Uint{num.NewUint(10), num.NewUint(5), num.NewUint(12), num.NewUint(17)}).String())
   246  }
   247  
   248  func TestSqrt(t *testing.T) {
   249  	n := num.NewUint(123456789)
   250  
   251  	rt := n.Sqrt(n)
   252  	assert.Equal(t, "11111.1110605555554406", rt.String())
   253  
   254  	rt = n.Sqrt(num.UintZero())
   255  	assert.Equal(t, "0", rt.String())
   256  
   257  	rt = n.Sqrt(num.UintOne())
   258  	assert.Equal(t, "1", rt.String())
   259  
   260  	n.SqrtInt(n)
   261  	assert.Equal(t, "11111", n.String())
   262  }