|
18 | 18 | from frequenz.quantities import Quantity |
19 | 19 |
|
20 | 20 | from frequenz.sdk.timeseries import Sample |
21 | | -from frequenz.sdk.timeseries.formulas._exceptions import FormulaSyntaxError |
22 | 21 | from frequenz.sdk.timeseries.formulas._formula import Formula, FormulaBuilder |
23 | 22 | from frequenz.sdk.timeseries.formulas._parser import parse |
24 | 23 | from frequenz.sdk.timeseries.formulas._resampled_stream_fetcher import ( |
@@ -345,180 +344,6 @@ async def test_max_min_coalesce(self) -> None: |
345 | 344 | ) |
346 | 345 |
|
347 | 346 |
|
348 | | -class TestFormulaValidation: |
349 | | - """Tests for Formula validation.""" |
350 | | - |
351 | | - @pytest.mark.parametrize( |
352 | | - ("formula_str", "parsed_formula_str"), |
353 | | - [ |
354 | | - ("#1", "[f](#1)"), |
355 | | - ("-(1+#1)", "[f](0.0 - (1.0 + #1))"), |
356 | | - ("1*(2+3)", "[f](1.0 * (2.0 + 3.0))"), |
357 | | - ], |
358 | | - ) |
359 | | - async def test_parser_validation( |
360 | | - self, |
361 | | - formula_str: str, |
362 | | - parsed_formula_str: str, |
363 | | - ) -> None: |
364 | | - """Test formula parser validation.""" |
365 | | - try: |
366 | | - formula = parse( |
367 | | - name="f", |
368 | | - formula=formula_str, |
369 | | - create_method=Quantity, |
370 | | - telemetry_fetcher=MagicMock(spec=ResampledStreamFetcher), |
371 | | - ) |
372 | | - assert str(formula) == parsed_formula_str |
373 | | - except FormulaSyntaxError: |
374 | | - assert False, "Parser should not raise an error for this formula" |
375 | | - |
376 | | - @pytest.mark.parametrize( |
377 | | - ("formula_str", "expected_error_line"), |
378 | | - [ |
379 | | - ( |
380 | | - "1++", |
381 | | - " ^ Expected expression", |
382 | | - ), |
383 | | - ( |
384 | | - "1**", |
385 | | - " ^ Expected expression", |
386 | | - ), |
387 | | - ( |
388 | | - "--1", |
389 | | - " ^ Expected expression", |
390 | | - ), |
391 | | - ( |
392 | | - "(", |
393 | | - " ^ Expected expression", |
394 | | - ), |
395 | | - ( |
396 | | - "(1", |
397 | | - "^ Unmatched parenthesis", |
398 | | - ), |
399 | | - ( |
400 | | - "max", |
401 | | - " ^ Expected '(' after function name", |
402 | | - ), |
403 | | - ( |
404 | | - "max()", |
405 | | - " ^ Expected argument", |
406 | | - ), |
407 | | - ( |
408 | | - "max(1(", |
409 | | - " ^ Expected ',' or ')'", |
410 | | - ), |
411 | | - ( |
412 | | - "max(1", |
413 | | - " ^ Unmatched parenthesis", |
414 | | - ), |
415 | | - ( |
416 | | - "foo", |
417 | | - "^^^ Unknown function name", |
418 | | - ), |
419 | | - ( |
420 | | - "foo(1)", |
421 | | - "^^^ Unknown function name", |
422 | | - ), |
423 | | - ( |
424 | | - "max(1,,2)", |
425 | | - " ^ Expected argument", |
426 | | - ), |
427 | | - ( |
428 | | - "1 2", |
429 | | - " ^ Unexpected token", |
430 | | - ), |
431 | | - ( |
432 | | - "1, 2", |
433 | | - " ^ Unexpected token", |
434 | | - ), |
435 | | - ( |
436 | | - "max(1, 2,)", |
437 | | - " ^ Expected argument", |
438 | | - ), |
439 | | - ( |
440 | | - "max(1, 2))", |
441 | | - " ^ Unexpected token", |
442 | | - ), |
443 | | - ( |
444 | | - "max(1, 2),", |
445 | | - " ^ Unexpected token", |
446 | | - ), |
447 | | - ], |
448 | | - ) |
449 | | - async def test_parser_validation_errors( |
450 | | - self, formula_str: str, expected_error_line: str |
451 | | - ) -> None: |
452 | | - """Test formula parser validation.""" |
453 | | - with pytest.raises(FormulaSyntaxError) as error: |
454 | | - _ = parse( |
455 | | - name="f", |
456 | | - formula=formula_str, |
457 | | - create_method=Quantity, |
458 | | - telemetry_fetcher=MagicMock(spec=ResampledStreamFetcher), |
459 | | - ) |
460 | | - |
461 | | - assert str(error.value) == ( |
462 | | - "Formula syntax error:\n" |
463 | | - f" Formula: {formula_str}\n" |
464 | | - f" {expected_error_line}" |
465 | | - ) |
466 | | - |
467 | | - @pytest.mark.parametrize( |
468 | | - ("formula_str", "expected_error"), |
469 | | - [ |
470 | | - # Long formula with error near start -> Ellipsize end |
471 | | - ( |
472 | | - "max(coalesce(#1001, %1002, 0), coalesce(#1003, #1004, 0), coalesce(#1005, #1006, 0), coalesce(#1007, #1008, 0))", # noqa: E501 |
473 | | - "Formula syntax error:\n" |
474 | | - " Formula: max(coalesce(#1001, %1002, 0), coalesce(#1003, #1004, 0), coalesc ...\n" |
475 | | - " ^ Unexpected character", |
476 | | - ), |
477 | | - # Long formula with error near the end -> Ellipsize start |
478 | | - ( |
479 | | - "max(coalesce(#1001, #1002, 0), coalesce(#1003, #1004, 0), coalesce(#1005, #1006, 0), coalesce(#10.07, #1008, 0))", # noqa: E501 |
480 | | - "Formula syntax error:\n" |
481 | | - " Formula: ... 0), coalesce(#1005, #1006, 0), coalesce(#10.07, #1008, 0))\n" |
482 | | - " ^ Unexpected character", |
483 | | - ), |
484 | | - # Very long formula with error in the middle -> Ellipsize both sides |
485 | | - ( |
486 | | - "max(coalesce(#1001, #1002, 0), coalesce(#1003, #1004, 0), coalesce(#1005, #1006, 0), coalesce(#1007, #1008, 0)) :) " # noqa: E501 |
487 | | - "min(coalesce(#2001, #2002, 0), coalesce(#2003, #2004, 0), coalesce(#2005, #2006, 0), coalesce(#2007, #2008, 0))", # noqa: E501 |
488 | | - "Formula syntax error:\n" |
489 | | - " Formula: ... 005, #1006, 0), coalesce(#1007, #1008, 0)) :) min(coalesce(#2 ...\n" |
490 | | - " ^ Unexpected character", |
491 | | - ), |
492 | | - ], |
493 | | - ) |
494 | | - async def test_parser_validation_errors_in_long_formulas( |
495 | | - self, formula_str: str, expected_error: str |
496 | | - ) -> None: |
497 | | - """Test formula parser validation for long formulas.""" |
498 | | - with pytest.raises(FormulaSyntaxError) as error: |
499 | | - _ = parse( |
500 | | - name="f", |
501 | | - formula=formula_str, |
502 | | - create_method=Quantity, |
503 | | - telemetry_fetcher=MagicMock(spec=ResampledStreamFetcher), |
504 | | - ) |
505 | | - |
506 | | - assert str(error.value) == expected_error |
507 | | - assert all(len(line) <= 80 for line in str(error.value).splitlines()) |
508 | | - |
509 | | - async def test_empty_formula(self) -> None: |
510 | | - """Test formula parser validation.""" |
511 | | - with pytest.raises(FormulaSyntaxError) as error: |
512 | | - _ = parse( |
513 | | - name="f", |
514 | | - formula="", |
515 | | - create_method=Quantity, |
516 | | - telemetry_fetcher=MagicMock(spec=ResampledStreamFetcher), |
517 | | - ) |
518 | | - |
519 | | - assert str(error.value) == "Empty formula" |
520 | | - |
521 | | - |
522 | 347 | class TestFormulaComposition: |
523 | 348 | """Tests for formula channels.""" |
524 | 349 |
|
|
0 commit comments