github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/cli/cmdargs/parser_test.go (about)

     1  package cmdargs
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/nspcc-dev/neo-go/internal/random"
     8  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
     9  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    10  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    11  	"github.com/nspcc-dev/neo-go/pkg/util"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestParseCosigner(t *testing.T) {
    16  	acc := util.Uint160{1, 3, 5, 7}
    17  	c1, c2 := random.Uint160(), random.Uint160()
    18  	priv, err := keys.NewPrivateKey()
    19  	require.NoError(t, err)
    20  
    21  	testCases := map[string]transaction.Signer{
    22  		acc.StringLE(): {
    23  			Account: acc,
    24  			Scopes:  transaction.CalledByEntry,
    25  		},
    26  		"0x" + acc.StringLE(): {
    27  			Account: acc,
    28  			Scopes:  transaction.CalledByEntry,
    29  		},
    30  		acc.StringLE() + ":Global": {
    31  			Account: acc,
    32  			Scopes:  transaction.Global,
    33  		},
    34  		acc.StringLE() + ":CalledByEntry": {
    35  			Account: acc,
    36  			Scopes:  transaction.CalledByEntry,
    37  		},
    38  		acc.StringLE() + ":None": {
    39  			Account: acc,
    40  			Scopes:  transaction.None,
    41  		},
    42  		acc.StringLE() + ":CalledByEntry,CustomContracts:" + c1.StringLE() + ":0x" + c2.StringLE(): {
    43  			Account:          acc,
    44  			Scopes:           transaction.CalledByEntry | transaction.CustomContracts,
    45  			AllowedContracts: []util.Uint160{c1, c2},
    46  		},
    47  		acc.StringLE() + ":CustomGroups:" + priv.PublicKey().StringCompressed(): {
    48  			Account:       acc,
    49  			Scopes:        transaction.CustomGroups,
    50  			AllowedGroups: keys.PublicKeys{priv.PublicKey()},
    51  		},
    52  	}
    53  	for s, expected := range testCases {
    54  		actual, err := parseCosigner(s)
    55  		require.NoError(t, err)
    56  		require.Equal(t, expected, actual, s)
    57  	}
    58  	errorCases := []string{
    59  		acc.StringLE() + "0",
    60  		acc.StringLE() + ":Unknown",
    61  		acc.StringLE() + ":Global,CustomContracts",
    62  		acc.StringLE() + ":Global,None",
    63  		acc.StringLE() + ":CustomContracts:" + acc.StringLE() + ",Global",
    64  		acc.StringLE() + ":CustomContracts",
    65  		acc.StringLE() + ":CustomContracts:xxx",
    66  		acc.StringLE() + ":CustomGroups",
    67  		acc.StringLE() + ":CustomGroups:xxx",
    68  	}
    69  	for _, s := range errorCases {
    70  		_, err := parseCosigner(s)
    71  		require.Error(t, err, s)
    72  	}
    73  }
    74  
    75  func TestParseParams_CalledFromItself(t *testing.T) {
    76  	testCases := map[string]struct {
    77  		WordsRead int
    78  		Value     []smartcontract.Parameter
    79  	}{
    80  		"]": {
    81  			WordsRead: 1,
    82  			Value:     []smartcontract.Parameter{},
    83  		},
    84  		"[ [ ] ] ]": {
    85  			WordsRead: 5,
    86  			Value: []smartcontract.Parameter{
    87  				{
    88  					Type: smartcontract.ArrayType,
    89  					Value: []smartcontract.Parameter{
    90  						{
    91  							Type:  smartcontract.ArrayType,
    92  							Value: []smartcontract.Parameter{},
    93  						},
    94  					},
    95  				},
    96  			},
    97  		},
    98  		"a b c ]": {
    99  			WordsRead: 4,
   100  			Value: []smartcontract.Parameter{
   101  				{
   102  					Type:  smartcontract.StringType,
   103  					Value: "a",
   104  				},
   105  				{
   106  					Type:  smartcontract.StringType,
   107  					Value: "b",
   108  				},
   109  				{
   110  					Type:  smartcontract.StringType,
   111  					Value: "c",
   112  				},
   113  			},
   114  		},
   115  		"a [ b [ [ c d ] e ] ] f ] extra items": {
   116  			WordsRead: 13, // the method should return right after the last bracket, as calledFromMain == false
   117  			Value: []smartcontract.Parameter{
   118  				{
   119  					Type:  smartcontract.StringType,
   120  					Value: "a",
   121  				},
   122  				{
   123  					Type: smartcontract.ArrayType,
   124  					Value: []smartcontract.Parameter{
   125  						{
   126  							Type:  smartcontract.StringType,
   127  							Value: "b",
   128  						},
   129  						{
   130  							Type: smartcontract.ArrayType,
   131  							Value: []smartcontract.Parameter{
   132  								{
   133  									Type: smartcontract.ArrayType,
   134  									Value: []smartcontract.Parameter{
   135  										{
   136  											Type:  smartcontract.StringType,
   137  											Value: "c",
   138  										},
   139  										{
   140  											Type:  smartcontract.StringType,
   141  											Value: "d",
   142  										},
   143  									},
   144  								},
   145  								{
   146  									Type:  smartcontract.StringType,
   147  									Value: "e",
   148  								},
   149  							},
   150  						},
   151  					},
   152  				},
   153  				{
   154  					Type:  smartcontract.StringType,
   155  					Value: "f",
   156  				},
   157  			},
   158  		},
   159  	}
   160  
   161  	for str, expected := range testCases {
   162  		input := strings.Split(str, " ")
   163  		offset, actual, err := ParseParams(input, false)
   164  		require.NoError(t, err)
   165  		require.Equal(t, expected.WordsRead, offset)
   166  		require.Equal(t, expected.Value, actual)
   167  	}
   168  
   169  	errorCases := []string{
   170  		"[ ]",
   171  		"[ a b [ c ] d ]",
   172  		"[ ] --",
   173  		"--",
   174  		"not-int:integer ]",
   175  	}
   176  
   177  	for _, str := range errorCases {
   178  		input := strings.Split(str, " ")
   179  		_, _, err := ParseParams(input, false)
   180  		require.Error(t, err)
   181  	}
   182  }
   183  
   184  func TestParseParams_CalledFromOutside(t *testing.T) {
   185  	testCases := map[string]struct {
   186  		WordsRead  int
   187  		Parameters []smartcontract.Parameter
   188  	}{
   189  		"-- cosigner1": {
   190  			WordsRead:  1, // the `--` only
   191  			Parameters: []smartcontract.Parameter{},
   192  		},
   193  		"a b c": {
   194  			WordsRead: 3,
   195  			Parameters: []smartcontract.Parameter{
   196  				{
   197  					Type:  smartcontract.StringType,
   198  					Value: "a",
   199  				},
   200  				{
   201  					Type:  smartcontract.StringType,
   202  					Value: "b",
   203  				},
   204  				{
   205  					Type:  smartcontract.StringType,
   206  					Value: "c",
   207  				},
   208  			},
   209  		},
   210  		"a b c -- cosigner1": {
   211  			WordsRead: 4,
   212  			Parameters: []smartcontract.Parameter{
   213  				{
   214  					Type:  smartcontract.StringType,
   215  					Value: "a",
   216  				},
   217  				{
   218  					Type:  smartcontract.StringType,
   219  					Value: "b",
   220  				},
   221  				{
   222  					Type:  smartcontract.StringType,
   223  					Value: "c",
   224  				},
   225  			},
   226  		},
   227  		"a [ b [ [ c d ] e ] ] f": {
   228  			WordsRead: 12,
   229  			Parameters: []smartcontract.Parameter{
   230  				{
   231  					Type:  smartcontract.StringType,
   232  					Value: "a",
   233  				},
   234  				{
   235  					Type: smartcontract.ArrayType,
   236  					Value: []smartcontract.Parameter{
   237  						{
   238  							Type:  smartcontract.StringType,
   239  							Value: "b",
   240  						},
   241  						{
   242  							Type: smartcontract.ArrayType,
   243  							Value: []smartcontract.Parameter{
   244  								{
   245  									Type: smartcontract.ArrayType,
   246  									Value: []smartcontract.Parameter{
   247  										{
   248  											Type:  smartcontract.StringType,
   249  											Value: "c",
   250  										},
   251  										{
   252  											Type:  smartcontract.StringType,
   253  											Value: "d",
   254  										},
   255  									},
   256  								},
   257  								{
   258  									Type:  smartcontract.StringType,
   259  									Value: "e",
   260  								},
   261  							},
   262  						},
   263  					},
   264  				},
   265  				{
   266  					Type:  smartcontract.StringType,
   267  					Value: "f",
   268  				},
   269  			},
   270  		},
   271  		"a [ b ] -- cosigner1 cosigner2": {
   272  			WordsRead: 5,
   273  			Parameters: []smartcontract.Parameter{
   274  				{
   275  					Type:  smartcontract.StringType,
   276  					Value: "a",
   277  				},
   278  				{
   279  					Type: smartcontract.ArrayType,
   280  					Value: []smartcontract.Parameter{
   281  						{
   282  							Type:  smartcontract.StringType,
   283  							Value: "b",
   284  						},
   285  					},
   286  				},
   287  			},
   288  		},
   289  		"a [ b ]": {
   290  			WordsRead: 4,
   291  			Parameters: []smartcontract.Parameter{
   292  				{
   293  					Type:  smartcontract.StringType,
   294  					Value: "a",
   295  				},
   296  				{
   297  					Type: smartcontract.ArrayType,
   298  					Value: []smartcontract.Parameter{
   299  						{
   300  							Type:  smartcontract.StringType,
   301  							Value: "b",
   302  						},
   303  					},
   304  				},
   305  			},
   306  		},
   307  		"a [ b ] [ [ c ] ] [ [ [ d ] ] ]": {
   308  			WordsRead: 16,
   309  			Parameters: []smartcontract.Parameter{
   310  				{
   311  					Type:  smartcontract.StringType,
   312  					Value: "a",
   313  				},
   314  				{
   315  					Type: smartcontract.ArrayType,
   316  					Value: []smartcontract.Parameter{
   317  						{
   318  							Type:  smartcontract.StringType,
   319  							Value: "b",
   320  						},
   321  					},
   322  				},
   323  				{
   324  					Type: smartcontract.ArrayType,
   325  					Value: []smartcontract.Parameter{
   326  						{
   327  							Type: smartcontract.ArrayType,
   328  							Value: []smartcontract.Parameter{
   329  								{
   330  									Type:  smartcontract.StringType,
   331  									Value: "c",
   332  								},
   333  							},
   334  						},
   335  					},
   336  				},
   337  				{
   338  					Type: smartcontract.ArrayType,
   339  					Value: []smartcontract.Parameter{
   340  						{
   341  							Type: smartcontract.ArrayType,
   342  							Value: []smartcontract.Parameter{
   343  								{
   344  									Type: smartcontract.ArrayType,
   345  									Value: []smartcontract.Parameter{
   346  										{
   347  											Type:  smartcontract.StringType,
   348  											Value: "d",
   349  										},
   350  									},
   351  								},
   352  							},
   353  						},
   354  					},
   355  				},
   356  			},
   357  		},
   358  	}
   359  	for str, expected := range testCases {
   360  		input := strings.Split(str, " ")
   361  		offset, arr, err := ParseParams(input, true)
   362  		require.NoError(t, err)
   363  		require.Equal(t, expected.WordsRead, offset)
   364  		require.Equal(t, expected.Parameters, arr)
   365  	}
   366  
   367  	errorCases := []string{
   368  		"[",
   369  		"]",
   370  		"[ [ ]",
   371  		"[ [ ] --",
   372  		"[ -- ]",
   373  	}
   374  	for _, str := range errorCases {
   375  		input := strings.Split(str, " ")
   376  		_, _, err := ParseParams(input, true)
   377  		require.Error(t, err)
   378  	}
   379  }