github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/functions_test.go (about)

     1  package lang
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/lmorg/murex/test/count"
     7  	"github.com/lmorg/murex/utils/json"
     8  )
     9  
    10  type testFuncParseDataTypesT struct {
    11  	Parameters string
    12  	Error      bool
    13  	Expected   []MxFunctionParams
    14  }
    15  
    16  func testFuncParseDataTypes(t *testing.T, tests []testFuncParseDataTypesT) {
    17  	t.Helper()
    18  	count.Tests(t, len(tests))
    19  
    20  	for i := range tests {
    21  		actual, err := ParseMxFunctionParameters(tests[i].Parameters)
    22  		if (err == nil) == tests[i].Error {
    23  			t.Errorf("Unexpected error raised in test %d", i)
    24  			t.Logf("Parameters: %s", tests[i].Parameters)
    25  			t.Logf("Expected:   %s", json.LazyLogging(tests[i].Expected))
    26  			t.Logf("Actual:     %s", json.LazyLogging(actual))
    27  			t.Logf("exp err:    %v", tests[i].Error)
    28  			t.Logf("act err:    %s", err)
    29  		}
    30  
    31  		if json.LazyLogging(tests[i].Expected) != json.LazyLogging(actual) {
    32  			t.Errorf("Unexpected error raised in test %d", i)
    33  			t.Logf("Parameters: %s", tests[i].Parameters)
    34  			t.Logf("Expected:   %s", json.LazyLogging(tests[i].Expected))
    35  			t.Logf("Actual:     %s", json.LazyLogging(actual))
    36  			t.Logf("exp err:    %v", tests[i].Error)
    37  			t.Logf("act err:    %s", err)
    38  		}
    39  	}
    40  }
    41  
    42  func TestFuncParseDataTypes(t *testing.T) {
    43  	tests := []testFuncParseDataTypesT{
    44  		{
    45  			Parameters: `name, age`,
    46  			Expected: []MxFunctionParams{{
    47  				Name:     "name",
    48  				DataType: "str",
    49  			}, {
    50  				Name:     "age",
    51  				DataType: "str",
    52  			}},
    53  		},
    54  		{
    55  			Parameters: `name: str, age: int`,
    56  			Expected: []MxFunctionParams{{
    57  				Name:     "name",
    58  				DataType: "str",
    59  			}, {
    60  				Name:     "age",
    61  				DataType: "int",
    62  			}},
    63  		},
    64  		{
    65  			Parameters: `name: str "What is your name?", age: int "How old are you?"`,
    66  			Expected: []MxFunctionParams{{
    67  				Name:        "name",
    68  				DataType:    "str",
    69  				Description: "What is your name?",
    70  			}, {
    71  				Name:        "age",
    72  				DataType:    "int",
    73  				Description: "How old are you?",
    74  			}},
    75  		},
    76  		{
    77  			Parameters: `name: str [Bob], age: int [100]`,
    78  			Expected: []MxFunctionParams{{
    79  				Name:     "name",
    80  				DataType: "str",
    81  				Default:  "Bob",
    82  			}, {
    83  				Name:     "age",
    84  				DataType: "int",
    85  				Default:  "100",
    86  			}},
    87  		},
    88  		{
    89  			Parameters: `name: str "What is your name?" [Bob], age: int "How old are you?" [100]`,
    90  			Expected: []MxFunctionParams{{
    91  				Name:        "name",
    92  				DataType:    "str",
    93  				Description: "What is your name?",
    94  				Default:     "Bob",
    95  			}, {
    96  				Name:        "age",
    97  				DataType:    "int",
    98  				Description: "How old are you?",
    99  				Default:     "100",
   100  			}},
   101  		},
   102  		{
   103  			Parameters: `name: str [Bob]`,
   104  			Expected: []MxFunctionParams{{
   105  				Name:     "name",
   106  				DataType: "str",
   107  				Default:  "Bob",
   108  			}},
   109  		},
   110  		{
   111  			Parameters: `colon: str ":" [:]`,
   112  			Expected: []MxFunctionParams{{
   113  				Name:        "colon",
   114  				DataType:    "str",
   115  				Description: ":",
   116  				Default:     ":",
   117  			}},
   118  		},
   119  		{
   120  			Parameters: `quote: str "'" ["]`,
   121  			Expected: []MxFunctionParams{{
   122  				Name:        "quote",
   123  				DataType:    "str",
   124  				Description: "'",
   125  				Default:     "\"",
   126  			}},
   127  		},
   128  		{
   129  			Parameters: `square: str "[" [[]`,
   130  			Expected: []MxFunctionParams{{
   131  				Name:        "square",
   132  				DataType:    "str",
   133  				Description: "[",
   134  				Default:     "[",
   135  			}},
   136  		},
   137  		{
   138  			Parameters: `square: str "]" [square]`,
   139  			Expected: []MxFunctionParams{{
   140  				Name:        "square",
   141  				DataType:    "str",
   142  				Description: "]",
   143  				Default:     "square",
   144  			}},
   145  		},
   146  		{
   147  			Parameters: `comma: str "," [,]`,
   148  			Expected: []MxFunctionParams{{
   149  				Name:        "comma",
   150  				DataType:    "str",
   151  				Description: ",",
   152  				Default:     ",",
   153  			}},
   154  		},
   155  	}
   156  
   157  	testFuncParseDataTypes(t, tests)
   158  }
   159  
   160  func TestFuncParseDataTypesErrorOutOfOrder(t *testing.T) {
   161  	tests := []testFuncParseDataTypesT{
   162  		{
   163  			Parameters: `foo baz [bar]`,
   164  			Error:      true,
   165  			/*Expected: []MxFunctionParams{{
   166  				Name:     "foo",
   167  				DataType: "baz",
   168  				Default:  "bar",
   169  			}},*/
   170  		},
   171  		{
   172  			Parameters: `foo "baz" [bar]`,
   173  			Error:      true,
   174  			/*Expected: []MxFunctionParams{{
   175  				Name:        "foo",
   176  				Description: "baz",
   177  				Default:     "bar",
   178  			}},*/
   179  		},
   180  		{
   181  			Parameters: `foo [bar]`,
   182  			Error:      true,
   183  			/*Expected: []MxFunctionParams{{
   184  				Name:     "foo",
   185  				DataType: "str",
   186  				Default:  "bar",
   187  			}},*/
   188  		},
   189  	}
   190  
   191  	testFuncParseDataTypes(t, tests)
   192  }
   193  
   194  func TestFuncParseDataTypesErrorCrLf(t *testing.T) {
   195  	tests := []testFuncParseDataTypesT{
   196  		{
   197  			Parameters: `\nname: str, age: int`,
   198  			Error:      true,
   199  		},
   200  		{
   201  			Parameters: `\r\nname: str, age: int`,
   202  			Error:      true,
   203  		},
   204  
   205  		{
   206  			Parameters: `na\nme: str, age: int`,
   207  			Error:      true,
   208  		},
   209  		{
   210  			Parameters: `na\r\nme: str, age: int`,
   211  			Error:      true,
   212  		},
   213  
   214  		{
   215  			Parameters: `name\n: str, age: int`,
   216  			Error:      true,
   217  		},
   218  		{
   219  			Parameters: `name\r\n: str, age: int`,
   220  			Error:      true,
   221  		},
   222  
   223  		{
   224  			Parameters: `name: \nstr, age: int`,
   225  			Error:      true,
   226  		},
   227  		{
   228  			Parameters: `name: \r\nstr, age: int`,
   229  			Error:      true,
   230  		},
   231  
   232  		{
   233  			Parameters: `name: str, age: int\nname: str, age: int`,
   234  			Error:      true,
   235  		},
   236  		{
   237  			Parameters: `name: str, age: int\r\nname: str, age: int`,
   238  			Error:      true,
   239  		},
   240  
   241  		{
   242  			Parameters: `name: str, age: int\nname\n: str, age: int`,
   243  			Error:      true,
   244  		},
   245  		{
   246  			Parameters: `name: str, age: int\r\nname\r\n str, age: int`,
   247  			Error:      true,
   248  		},
   249  
   250  		{
   251  			Parameters: `name: str, age: int\r\nname: \nstr, age: int`,
   252  			Error:      true,
   253  		},
   254  		{
   255  			Parameters: `name: str, age: int\r\nname: \r\nstr, age: int`,
   256  			Error:      true,
   257  		},
   258  	}
   259  
   260  	testFuncParseDataTypes(t, tests)
   261  }
   262  
   263  func TestFuncParseDataTypesErrorSpaceTab(t *testing.T) {
   264  	tests := []testFuncParseDataTypesT{
   265  		{
   266  			Parameters: `name : str, age: int`,
   267  			Error:      true,
   268  		},
   269  		{
   270  			Parameters: `name\t: str, age: int`,
   271  			Error:      true,
   272  		},
   273  	}
   274  
   275  	testFuncParseDataTypes(t, tests)
   276  }
   277  
   278  func TestFuncParseDataTypesErrorColon(t *testing.T) {
   279  	tests := []testFuncParseDataTypesT{
   280  		{
   281  			Parameters: `name: str, age: int :`,
   282  			Error:      true,
   283  		},
   284  	}
   285  
   286  	testFuncParseDataTypes(t, tests)
   287  }
   288  
   289  func TestFuncParseDataTypesErrorQuote(t *testing.T) {
   290  	tests := []testFuncParseDataTypesT{
   291  		{
   292  			Parameters: `"name": str`,
   293  			Error:      true,
   294  		},
   295  		{
   296  			Parameters: `name: "str"`,
   297  			Error:      true,
   298  		},
   299  	}
   300  
   301  	testFuncParseDataTypes(t, tests)
   302  }
   303  
   304  func TestFuncParseDataTypesErrorSquare(t *testing.T) {
   305  	tests := []testFuncParseDataTypesT{
   306  		{
   307  			Parameters: `]: str`,
   308  			Error:      true,
   309  		},
   310  		{
   311  			Parameters: `name: ]`,
   312  			Error:      true,
   313  		},
   314  		{
   315  			Parameters: `name: str ]`,
   316  			Error:      true,
   317  		},
   318  	}
   319  
   320  	testFuncParseDataTypes(t, tests)
   321  }
   322  
   323  func TestFuncParseDataTypesErrorComma(t *testing.T) {
   324  	tests := []testFuncParseDataTypesT{
   325  		{
   326  			Parameters: `,name`,
   327  			Error:      true,
   328  		},
   329  		{
   330  			Parameters: `name: ,`,
   331  			Error:      true,
   332  		},
   333  		{
   334  			Parameters: `name,,`,
   335  			Error:      true,
   336  		},
   337  	}
   338  
   339  	testFuncParseDataTypes(t, tests)
   340  }
   341  
   342  func TestFuncSummary(t *testing.T) {
   343  	tests := []struct {
   344  		Block   string
   345  		Summary string
   346  	}{
   347  		{
   348  			Block:   "",
   349  			Summary: "",
   350  		},
   351  		{
   352  			Block:   "hello world",
   353  			Summary: "",
   354  		},
   355  		{
   356  			Block:   "foo\nbar",
   357  			Summary: "",
   358  		},
   359  		{
   360  			Block:   "foo\n#bar",
   361  			Summary: "",
   362  		},
   363  		{
   364  			Block:   "{\n#bar",
   365  			Summary: "bar",
   366  		},
   367  		{
   368  			Block:   "foo\n\n#bar",
   369  			Summary: "",
   370  		},
   371  		{
   372  			Block:   "{\n\n#bar",
   373  			Summary: "",
   374  		},
   375  		{
   376  			Block:   "foo\nbar\nbaz",
   377  			Summary: "",
   378  		},
   379  		{
   380  			Block:   "{\nbar\nbaz",
   381  			Summary: "",
   382  		},
   383  		{
   384  			Block:   "foo\nbar\n#baz",
   385  			Summary: "",
   386  		},
   387  		{
   388  			Block:   "{\nbar\n#baz",
   389  			Summary: "",
   390  		},
   391  		{
   392  			Block:   "foo\n#bar\n#baz",
   393  			Summary: "",
   394  		},
   395  		{
   396  			Block:   "{\n#bar\n#baz",
   397  			Summary: "bar",
   398  		},
   399  		{
   400  			Block:   "\n#bar\n#baz",
   401  			Summary: "bar",
   402  		},
   403  		{
   404  			Block:   "\n\n#bar\n#baz",
   405  			Summary: "",
   406  		},
   407  		{
   408  			Block:   "foo\n# bar\n# baz",
   409  			Summary: "",
   410  		},
   411  		{
   412  			Block:   "{\n# bar\n# baz",
   413  			Summary: "bar",
   414  		},
   415  		{
   416  			Block:   "foo\n#  bar\n#  baz",
   417  			Summary: "",
   418  		},
   419  		{
   420  			Block:   "{\n#  bar\n#  baz",
   421  			Summary: "bar",
   422  		},
   423  		{
   424  			Block:   "foo\n#\tbar\n#\tbaz",
   425  			Summary: "",
   426  		},
   427  		{
   428  			Block:   "{\n#\tbar\n#\tbaz",
   429  			Summary: "bar",
   430  		},
   431  		{
   432  			Block:   "#\tbar",
   433  			Summary: "bar",
   434  		},
   435  		{
   436  			Block:   "# bar\t",
   437  			Summary: "bar",
   438  		},
   439  		{
   440  			Block:   "# foo bar",
   441  			Summary: "foo bar",
   442  		},
   443  		{
   444  			Block:   "# foo\tbar",
   445  			Summary: "foo    bar",
   446  		},
   447  		{
   448  			Block:   " # foo\tbar",
   449  			Summary: "foo    bar",
   450  		},
   451  		{
   452  			Block:   "\t# foo\tbar",
   453  			Summary: "foo    bar",
   454  		},
   455  		{
   456  			Block:   "baz # foo\tbar",
   457  			Summary: "",
   458  		},
   459  		{
   460  			Block:   "{ # foo\tbar",
   461  			Summary: "foo    bar",
   462  		},
   463  		{
   464  			Block:   "baz\n # foo\tbar",
   465  			Summary: "",
   466  		},
   467  		{
   468  			Block:   "{\n # foo\tbar",
   469  			Summary: "foo    bar",
   470  		},
   471  		{
   472  			Block:   "1\n2\n # foo\tbar",
   473  			Summary: "",
   474  		},
   475  		{
   476  			Block:   "{\n # foo\tbar\n}",
   477  			Summary: "foo    bar",
   478  		},
   479  		{
   480  			Block:   "\r\n",
   481  			Summary: "",
   482  		},
   483  		{
   484  			Block:   "\r\n# foo\r\nbar",
   485  			Summary: "foo",
   486  		},
   487  	}
   488  
   489  	count.Tests(t, len(tests))
   490  
   491  	for i, test := range tests {
   492  		actual := funcSummary([]rune(test.Block))
   493  		if actual != test.Summary {
   494  			t.Errorf("Summary mismatch in test %d", i)
   495  			t.Logf("  Block:\n'%s'", test.Block)
   496  			t.Logf("  Expected: '%s'", test.Summary)
   497  			t.Logf("  Actual:   '%s'", actual)
   498  		}
   499  	}
   500  }
   501  
   502  func TestFuncParseDocExamples(t *testing.T) {
   503  	tests := []testFuncParseDataTypesT{
   504  		{
   505  			Parameters: `var:datatype [default-value] "description"`,
   506  			Expected: []MxFunctionParams{
   507  				{
   508  					Name:        "var",
   509  					DataType:    "datatype",
   510  					Default:     "default-value",
   511  					Description: "description",
   512  				},
   513  			},
   514  		},
   515  		{
   516  			Parameters: `
   517  				variable1: data-type [default-value] "description",
   518  				variable2: data-type [default-value] "description"
   519  			`,
   520  			Expected: []MxFunctionParams{
   521  				{
   522  					Name:        "variable1",
   523  					DataType:    "data-type",
   524  					Default:     "default-value",
   525  					Description: "description",
   526  				},
   527  				{
   528  					Name:        "variable2",
   529  					DataType:    "data-type",
   530  					Default:     "default-value",
   531  					Description: "description",
   532  				},
   533  			},
   534  		},
   535  	}
   536  
   537  	testFuncParseDataTypes(t, tests)
   538  }