github.com/stellar/stellar-etl@v1.0.1-0.20240312145900-4874b6bf2b89/internal/toid/main_test.go (about)

     1  package toid
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  var ledger = int64(4294967296) // ledger sequence 1
    12  var tx = int64(4096)           // tx index 1
    13  var op = int64(1)              // op index 1
    14  
    15  func TestID_ToInt64(t *testing.T) {
    16  	testCases := []struct {
    17  		id          *ID
    18  		expected    int64
    19  		shouldPanic bool
    20  	}{
    21  		// accomodates 12-bits of precision for the operation field
    22  		{
    23  			id:       &ID{0, 0, 1},
    24  			expected: 1,
    25  		},
    26  		{
    27  			id:       &ID{0, 0, 4095},
    28  			expected: 4095,
    29  		},
    30  		{
    31  			id:          &ID{0, 0, 4096},
    32  			shouldPanic: true,
    33  		},
    34  		// accomodates 20-bits of precision for the transaction field
    35  		{
    36  			id:       &ID{0, 1, 0},
    37  			expected: 4096,
    38  		},
    39  		{
    40  			id:       &ID{0, 1048575, 0},
    41  			expected: 4294963200,
    42  		},
    43  		{
    44  			id:          &ID{0, 1048576, 0},
    45  			shouldPanic: true,
    46  		},
    47  		// accomodates 32-bits of precision for the ledger field
    48  		{
    49  			id:       &ID{1, 0, 0},
    50  			expected: 4294967296,
    51  		},
    52  		{
    53  			id:       &ID{math.MaxInt32, 0, 0},
    54  			expected: 9223372032559808512,
    55  		},
    56  		{
    57  			id:          &ID{-1, 0, 0},
    58  			shouldPanic: true,
    59  		},
    60  		{
    61  			id:          &ID{math.MinInt32, 0, 0},
    62  			shouldPanic: true,
    63  		},
    64  		// works as expected
    65  		{
    66  			id:       &ID{1, 1, 1},
    67  			expected: ledger + tx + op,
    68  		},
    69  		{
    70  			id:       &ID{1, 1, 0},
    71  			expected: ledger + tx,
    72  		},
    73  		{
    74  			id:       &ID{1, 0, 1},
    75  			expected: ledger + op,
    76  		},
    77  		{
    78  			id:       &ID{1, 0, 0},
    79  			expected: ledger,
    80  		},
    81  		{
    82  			id:       &ID{0, 1, 0},
    83  			expected: tx,
    84  		},
    85  		{
    86  			id:       &ID{0, 0, 1},
    87  			expected: op,
    88  		},
    89  		{
    90  			id:       &ID{0, 0, 0},
    91  			expected: 0,
    92  		},
    93  	}
    94  	for _, tc := range testCases {
    95  		t.Run("Testing ToInt64", func(t *testing.T) {
    96  			if tc.shouldPanic {
    97  				assert.Panics(t, func() {
    98  					tc.id.ToInt64()
    99  				})
   100  				return
   101  			}
   102  			assert.Equal(t, tc.expected, tc.id.ToInt64())
   103  		})
   104  	}
   105  }
   106  
   107  func TestParse(t *testing.T) {
   108  	testCases := []struct {
   109  		parsed   ID
   110  		expected ID
   111  	}{
   112  		{Parse(ledger + tx + op), ID{1, 1, 1}},
   113  		{Parse(ledger + tx), ID{1, 1, 0}},
   114  		{Parse(ledger + op), ID{1, 0, 1}},
   115  		{Parse(ledger), ID{1, 0, 0}},
   116  		{Parse(tx), ID{0, 1, 0}},
   117  		{Parse(op), ID{0, 0, 1}},
   118  	}
   119  	for _, tc := range testCases {
   120  		t.Run("Testing Parse", func(t *testing.T) {
   121  			assert.Equal(t, tc.expected, tc.parsed)
   122  		})
   123  	}
   124  }
   125  
   126  // Test InOperationOrder to make sure it rolls over to the next ledger sequence if overflow occurs.
   127  func TestID_IncOperationOrder(t *testing.T) {
   128  	tid := ID{0, 0, 0}
   129  	tid.IncOperationOrder()
   130  	assert.Equal(t, int32(1), tid.OperationOrder)
   131  	tid.OperationOrder = OperationMask
   132  	tid.IncOperationOrder()
   133  	assert.Equal(t, int32(0), tid.OperationOrder)
   134  	assert.Equal(t, int32(1), tid.LedgerSequence)
   135  }
   136  
   137  func ExampleParse() {
   138  	toid := Parse(12884910080)
   139  	fmt.Printf("ledger:%d, tx:%d, op:%d", toid.LedgerSequence, toid.TransactionOrder, toid.OperationOrder)
   140  	// Output: ledger:3, tx:2, op:0
   141  }
   142  
   143  func TestLedgerRangeInclusive(t *testing.T) {
   144  	testCases := []struct {
   145  		from int32
   146  		to   int32
   147  
   148  		fromLedger int32
   149  		toLedger   int32
   150  	}{
   151  		{1, 1, 0, 2},
   152  		{1, 2, 0, 3},
   153  		{2, 2, 2, 3},
   154  		{2, 3, 2, 4},
   155  	}
   156  	for _, tc := range testCases {
   157  		t.Run("Testing TestLedgerRangeInclusive", func(t *testing.T) {
   158  			toidFrom, toidTo, err := LedgerRangeInclusive(tc.from, tc.to)
   159  			assert.NoError(t, err)
   160  
   161  			id := Parse(toidFrom)
   162  			assert.Equal(t, tc.fromLedger, id.LedgerSequence)
   163  			assert.Equal(t, int32(0), id.TransactionOrder)
   164  			assert.Equal(t, int32(0), id.OperationOrder)
   165  
   166  			id = Parse(toidTo)
   167  			assert.Equal(t, tc.toLedger, id.LedgerSequence)
   168  			assert.Equal(t, int32(0), id.TransactionOrder)
   169  			assert.Equal(t, int32(0), id.OperationOrder)
   170  		})
   171  	}
   172  
   173  	_, _, err := LedgerRangeInclusive(2, 1)
   174  	assert.Error(t, err)
   175  
   176  	_, _, err = LedgerRangeInclusive(-1, 1)
   177  	assert.Error(t, err)
   178  
   179  	_, _, err = LedgerRangeInclusive(-3, -5)
   180  	assert.Error(t, err)
   181  }