|
6 | 6 | from utils import scenarios |
7 | 7 | from utils._context.component_version import Version |
8 | 8 | from utils.manifest import Manifest, SkipDeclaration, TestDeclaration |
9 | | -from utils.manifest._internal.types import SemverRange as CustomSpec |
| 9 | +from utils.manifest._internal.types import ManifestData, SemverRange as CustomSpec, Condition |
10 | 10 | from utils.manifest._internal.validate import assert_nodeids_exist |
11 | 11 | from utils.scripts.activate_easy_wins._internal.manifest_editor import ManifestEditor |
12 | 12 | from utils.scripts.activate_easy_wins._internal.types import Context |
13 | 13 |
|
14 | 14 |
|
15 | 15 | def manifest_init( |
16 | | - components: dict[str, Version], |
| 16 | + components: dict[str, Version | str], |
17 | 17 | weblog: str = "some_variant", |
18 | 18 | path: Path = Path("tests/test_the_test/manifests/manifests_parser_test/"), |
19 | | -): |
20 | | - return Manifest(components, weblog, path) |
| 19 | + manifest_data: dict[str, list[Condition]] | None = None, |
| 20 | +) -> Manifest: |
| 21 | + result = Manifest(components, weblog, path) |
| 22 | + if manifest_data: |
| 23 | + result.data = ManifestData() |
| 24 | + for key, value in manifest_data.items(): |
| 25 | + result.data[key] = value |
| 26 | + |
| 27 | + return result |
21 | 28 |
|
22 | 29 |
|
23 | 30 | @scenarios.test_the_test |
@@ -403,3 +410,126 @@ def test_selects_correct_component_when_converting_inline_to_list(self): |
403 | 410 | first_entry = python_manifest_rule[0] |
404 | 411 | assert first_entry == {"declaration": "bug (TICKET-123)"} |
405 | 412 | assert "excluded_component_version" not in first_entry |
| 413 | + |
| 414 | + |
| 415 | +def _get_manifest_errors(component: str, *, declared_version: str, components: dict[str, Version | str]) -> list[str]: |
| 416 | + manifest = manifest_init( |
| 417 | + components, |
| 418 | + manifest_data={ |
| 419 | + "tests/foo.py::TestFoo": [ |
| 420 | + { |
| 421 | + "component": component, |
| 422 | + "component_version": CustomSpec(declared_version), |
| 423 | + "excluded_component_version": CustomSpec(declared_version), |
| 424 | + "declaration": SkipDeclaration("missing_feature"), |
| 425 | + } |
| 426 | + ] |
| 427 | + }, |
| 428 | + ) |
| 429 | + |
| 430 | + return manifest.assert_versions_not_ahead_of_current() |
| 431 | + |
| 432 | + |
| 433 | +@scenarios.test_the_test |
| 434 | +class Test_VersionsNotAheadOfCurrent: |
| 435 | + def test_declared_version_below_current_is_ok(self): |
| 436 | + """A declared version lower than the current version produces no errors.""" |
| 437 | + errors = _get_manifest_errors( |
| 438 | + "nodejs", |
| 439 | + declared_version=">=5.0.0", |
| 440 | + components={"nodejs": Version("5.2.0")}, |
| 441 | + ) |
| 442 | + assert errors == [] |
| 443 | + |
| 444 | + def test_declared_version_equals_current_is_ok(self): |
| 445 | + """A declared version equal to the current version produces no errors.""" |
| 446 | + errors = _get_manifest_errors( |
| 447 | + "nodejs", |
| 448 | + declared_version=">=5.2.0", |
| 449 | + components={"nodejs": Version("5.2.0")}, |
| 450 | + ) |
| 451 | + assert errors == [] |
| 452 | + |
| 453 | + def test_declared_version_with_prerelease(self): |
| 454 | + """Declaring v5.2.0 while testing 5.2.0-dev is not allowed.""" |
| 455 | + errors = _get_manifest_errors( |
| 456 | + "nodejs", |
| 457 | + declared_version=">=5.2.0", |
| 458 | + components={"nodejs": Version("5.2.0-dev")}, |
| 459 | + ) |
| 460 | + assert len(errors) == 2 |
| 461 | + |
| 462 | + def test_declared_version_above_current_is_an_error(self): |
| 463 | + """A declared version higher than the current version produces an error per field.""" |
| 464 | + errors = _get_manifest_errors( |
| 465 | + "nodejs", |
| 466 | + declared_version=">=6.0.0", |
| 467 | + components={"nodejs": Version("5.2.0-dev")}, |
| 468 | + ) |
| 469 | + assert len(errors) == 2 |
| 470 | + assert all("nodejs" in e for e in errors) |
| 471 | + assert all("6.0.0" in e for e in errors) |
| 472 | + assert all("5.2.0" in e for e in errors) |
| 473 | + |
| 474 | + def test_caret_notation_above_current_is_an_error(self): |
| 475 | + """^X.Y.Z is treated as a lower bound; flagged for each field when it exceeds current version.""" |
| 476 | + errors = _get_manifest_errors( |
| 477 | + "nodejs", |
| 478 | + declared_version="^6.0.0", |
| 479 | + components={"nodejs": Version("5.2.0")}, |
| 480 | + ) |
| 481 | + assert len(errors) == 2 |
| 482 | + |
| 483 | + def test_or_expression_is_treated(self): |
| 484 | + """Multi-branch OR expressions are not ignored.""" |
| 485 | + errors = _get_manifest_errors( |
| 486 | + "nodejs", |
| 487 | + declared_version=">=6.0.0 || ^3.0.0", |
| 488 | + components={"nodejs": Version("5.2.0-dev")}, |
| 489 | + ) |
| 490 | + assert len(errors) == 2 |
| 491 | + |
| 492 | + def test_no_excluded_component_version_is_ok(self): |
| 493 | + """Conditions without excluded_component_version (plain skip declarations) are ignored.""" |
| 494 | + manifest = manifest_init( |
| 495 | + components={"nodejs": Version("5.2.0")}, |
| 496 | + manifest_data={ |
| 497 | + "tests/foo.py::TestFoo": [{"component": "nodejs", "declaration": SkipDeclaration("missing_feature")}] |
| 498 | + }, |
| 499 | + ) |
| 500 | + |
| 501 | + errors = manifest.assert_versions_not_ahead_of_current() |
| 502 | + assert errors == [] |
| 503 | + |
| 504 | + def test_unknown_component_is_skipped(self): |
| 505 | + """Conditions for components not in the tested set are ignored.""" |
| 506 | + errors = _get_manifest_errors( |
| 507 | + "java", |
| 508 | + declared_version=">=6.0.0", |
| 509 | + components={"nodejs": Version("5.2.0")}, |
| 510 | + ) |
| 511 | + assert errors == [] |
| 512 | + |
| 513 | + def test_multiple_violations_are_all_reported(self): |
| 514 | + """Every offending condition is reported, not just the first.""" |
| 515 | + manifest = manifest_init( |
| 516 | + components={"nodejs": Version("5.2.0")}, |
| 517 | + manifest_data={ |
| 518 | + "tests/foo.py::TestFoo": [ |
| 519 | + { |
| 520 | + "component": "nodejs", |
| 521 | + "excluded_component_version": CustomSpec(">=6.0.0"), |
| 522 | + "declaration": SkipDeclaration("missing_feature"), |
| 523 | + } |
| 524 | + ], |
| 525 | + "tests/bar.py::TestBar": [ |
| 526 | + { |
| 527 | + "component": "nodejs", |
| 528 | + "component_version": CustomSpec(">=7.0.0"), |
| 529 | + "declaration": SkipDeclaration("missing_feature"), |
| 530 | + } |
| 531 | + ], |
| 532 | + }, |
| 533 | + ) |
| 534 | + errors = manifest.assert_versions_not_ahead_of_current() |
| 535 | + assert len(errors) == 2 |
0 commit comments