Coverage for /usr/local/lib/python3.12/site-packages/prefect/testing/standard_test_suites/blocks.py: 0%
40 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 10:48 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 10:48 +0000
1import re
2from abc import ABC, abstractmethod
3from urllib.request import urlopen
5import pytest
7from prefect.blocks.core import Block
9try:
10 from PIL import Image
12 HAS_PIL = True
13except ImportError:
14 HAS_PIL = False
17class BlockStandardTestSuite(ABC):
18 @pytest.fixture
19 @abstractmethod
20 def block(self) -> type[Block]:
21 pass
23 def test_has_a_description(self, block: type[Block]) -> None:
24 assert block.get_description()
26 def test_has_a_documentation_url(self, block: type[Block]) -> None:
27 assert block._documentation_url
29 def test_all_fields_have_a_description(self, block: type[Block]) -> None:
30 for name, field in block.model_fields.items():
31 if Block.annotation_refers_to_block_class(field.annotation):
32 # TODO: Block field descriptions aren't currently handled by the UI, so
33 # block fields are currently excluded from this test. Once block field
34 # descriptions are supported by the UI, remove this clause.
35 continue
36 assert field.description, (
37 f"{block.__name__} is missing a description on {name}"
38 )
39 assert field.description.endswith("."), (
40 f"{name} description on {block.__name__} does not end with a period"
41 )
43 def test_has_a_valid_code_example(self, block: type[Block]) -> None:
44 code_example = block.get_code_example()
45 assert code_example is not None, f"{block.__name__} is missing a code example"
47 # Extract base name without generic parameters
48 base_name = block.__name__.partition("[")[0]
50 # Check for proper import statement
51 import_pattern = rf"from .* import {base_name}"
52 assert re.search(import_pattern, code_example) is not None, (
53 f"The code example for {base_name} is missing an import statement"
54 f" matching the pattern {import_pattern}"
55 )
57 # Check for proper load statement
58 block_load_pattern = rf'.* = {base_name}\.load\("BLOCK_NAME"\)'
59 assert re.search(block_load_pattern, code_example), (
60 f"The code example for {base_name} is missing a .load statement"
61 f" matching the pattern {block_load_pattern}"
62 )
64 @pytest.mark.skipif(not HAS_PIL, reason="PIL/Pillow is not available")
65 def test_has_a_valid_image(self, block: type[Block]) -> None:
66 logo_url = block._logo_url
67 assert logo_url is not None, (
68 f"{block.__name__} is missing a value for _logo_url"
69 )
70 img = Image.open(urlopen(str(logo_url)))
71 assert img.width == img.height, "Logo should be a square image"
72 assert 1000 > img.width > 45, (
73 f"Logo should be between 200px and 1000px wid, but is {img.width}px wide"
74 )