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 }