more examples
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
"""
|
||||
Test for pagination example (08_pagination_demo.py).
|
||||
|
||||
This test ensures the pagination example runs correctly and produces expected output.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import importlib.util
|
||||
|
||||
# Add examples to path
|
||||
examples_dir = Path(__file__).parent.parent.parent / "examples"
|
||||
sys.path.insert(0, str(examples_dir))
|
||||
|
||||
# Load the demo module
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"pagination_demo",
|
||||
examples_dir / "08_pagination_demo.py"
|
||||
)
|
||||
demo_module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(demo_module)
|
||||
|
||||
|
||||
def test_pagination_demo_imports():
|
||||
"""Test that the pagination demo can be imported without errors."""
|
||||
assert demo_module is not None
|
||||
|
||||
|
||||
def test_create_sample_paragraph():
|
||||
"""Test creating a sample paragraph."""
|
||||
create_sample_paragraph = demo_module.create_sample_paragraph
|
||||
from pyWebLayout.abstract.block import Paragraph
|
||||
|
||||
para = create_sample_paragraph("Hello world test")
|
||||
assert isinstance(para, Paragraph)
|
||||
assert len(para.words) == 3
|
||||
assert para.words[0].text == "Hello"
|
||||
assert para.words[1].text == "world"
|
||||
assert para.words[2].text == "test"
|
||||
|
||||
|
||||
def test_create_title_paragraph():
|
||||
"""Test creating a title paragraph."""
|
||||
create_title_paragraph = demo_module.create_title_paragraph
|
||||
from pyWebLayout.abstract.block import Paragraph
|
||||
|
||||
title = create_title_paragraph("Test Title")
|
||||
assert isinstance(title, Paragraph)
|
||||
assert len(title.words) == 2
|
||||
# Title should have larger font
|
||||
assert title.style.font_size == 24
|
||||
|
||||
|
||||
def test_create_heading_paragraph():
|
||||
"""Test creating a heading paragraph."""
|
||||
create_heading_paragraph = demo_module.create_heading_paragraph
|
||||
from pyWebLayout.abstract.block import Paragraph
|
||||
|
||||
heading = create_heading_paragraph("Test Heading")
|
||||
assert isinstance(heading, Paragraph)
|
||||
assert len(heading.words) == 2
|
||||
# Heading should have medium font
|
||||
assert heading.style.font_size == 18
|
||||
|
||||
|
||||
def test_create_placeholder_image():
|
||||
"""Test creating a placeholder image."""
|
||||
create_placeholder_image = demo_module.create_placeholder_image
|
||||
from pyWebLayout.abstract.block import Image as AbstractImage
|
||||
|
||||
img = create_placeholder_image(200, 150, "Test Image")
|
||||
assert isinstance(img, AbstractImage)
|
||||
assert img.source.size == (200, 150)
|
||||
|
||||
|
||||
def test_pagebreak_layouter_integration():
|
||||
"""Test that PageBreak properly forces new pages."""
|
||||
create_sample_paragraph = demo_module.create_sample_paragraph
|
||||
from pyWebLayout.abstract.block import PageBreak
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
from pyWebLayout.layout.document_layouter import DocumentLayouter
|
||||
|
||||
# Create a small page
|
||||
page_style = PageStyle(padding=(10, 10, 10, 10))
|
||||
page1 = Page(size=(200, 200), style=page_style)
|
||||
layouter1 = DocumentLayouter(page1)
|
||||
|
||||
# Add some content
|
||||
para1 = create_sample_paragraph("First paragraph")
|
||||
success, _, _ = layouter1.layout_paragraph(para1)
|
||||
assert success
|
||||
|
||||
# Record y offset before pagebreak
|
||||
y_before_break = page1._current_y_offset
|
||||
|
||||
# Simulating PageBreak by creating new page
|
||||
# (PageBreak doesn't get laid out - it signals page creation)
|
||||
page2 = Page(size=(200, 200), style=page_style)
|
||||
layouter2 = DocumentLayouter(page2)
|
||||
|
||||
# Verify new page starts at initial offset
|
||||
initial_offset = page2._current_y_offset
|
||||
|
||||
# Add content to new page
|
||||
para2 = create_sample_paragraph("Second paragraph")
|
||||
success, _, _ = layouter2.layout_paragraph(para2)
|
||||
assert success
|
||||
|
||||
# New page should start fresh (at border_size + padding)
|
||||
# Both pages should have same initial offset
|
||||
assert initial_offset == page1.border_size + page_style.padding_top
|
||||
|
||||
|
||||
def test_example_document_with_pagebreaks():
|
||||
"""Test creating the main example document with pagebreaks."""
|
||||
create_example_document_with_pagebreaks = demo_module.create_example_document_with_pagebreaks
|
||||
|
||||
pages = create_example_document_with_pagebreaks()
|
||||
|
||||
# Should create multiple pages
|
||||
assert len(pages) > 1
|
||||
# Should have created 5 pages (based on PageBreak placements)
|
||||
assert len(pages) == 5
|
||||
|
||||
# Each page should be valid
|
||||
for page in pages:
|
||||
assert page.size == (600, 800)
|
||||
# Page should have some content or be a clean break page
|
||||
assert page._current_y_offset >= page.border_size
|
||||
|
||||
|
||||
def test_auto_pagination_example():
|
||||
"""Test auto-pagination without explicit PageBreaks."""
|
||||
create_auto_pagination_example = demo_module.create_auto_pagination_example
|
||||
|
||||
pages = create_auto_pagination_example()
|
||||
|
||||
# Should create multiple pages due to content overflow
|
||||
assert len(pages) >= 1
|
||||
|
||||
# Each page should be valid
|
||||
for page in pages:
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_add_page_numbers():
|
||||
"""Test adding page numbers to rendered pages."""
|
||||
add_page_numbers = demo_module.add_page_numbers
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
|
||||
# Create a few simple pages
|
||||
page_style = PageStyle()
|
||||
pages = [
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style)
|
||||
]
|
||||
|
||||
# Add page numbers
|
||||
numbered = add_page_numbers(pages, start_number=1)
|
||||
|
||||
# Should return same number of pages
|
||||
assert len(numbered) == 3
|
||||
|
||||
# Each should be a rendered image
|
||||
from PIL import Image
|
||||
for img in numbered:
|
||||
assert isinstance(img, Image.Image)
|
||||
assert img.size == (200, 200)
|
||||
|
||||
|
||||
def test_combine_pages_vertically():
|
||||
"""Test combining pages into vertical strip."""
|
||||
combine_pages_vertically = demo_module.combine_pages_vertically
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
|
||||
# Create a few pages
|
||||
page_style = PageStyle()
|
||||
pages = [
|
||||
Page(size=(200, 200), style=page_style).render(),
|
||||
Page(size=(200, 200), style=page_style).render()
|
||||
]
|
||||
|
||||
combined = combine_pages_vertically(pages, title="Test Title")
|
||||
|
||||
# Should create a combined image
|
||||
from PIL import Image
|
||||
assert isinstance(combined, Image.Image)
|
||||
|
||||
# Should be taller than individual pages
|
||||
assert combined.size[1] > 200
|
||||
|
||||
|
||||
def test_main_function():
|
||||
"""Test that the main function runs without errors."""
|
||||
main = demo_module.main
|
||||
|
||||
# Run main (will create output files)
|
||||
result = main()
|
||||
|
||||
# Should return two combined images
|
||||
assert result is not None
|
||||
assert len(result) == 2
|
||||
|
||||
# Both should be PIL images
|
||||
from PIL import Image
|
||||
assert isinstance(result[0], Image.Image)
|
||||
assert isinstance(result[1], Image.Image)
|
||||
|
||||
# Output files should exist
|
||||
output_dir = Path("docs/images")
|
||||
assert (output_dir / "example_08_pagination_explicit.png").exists()
|
||||
assert (output_dir / "example_08_pagination_auto.png").exists()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
Test for link navigation example (09_link_navigation_demo.py).
|
||||
|
||||
This test ensures the link navigation example runs correctly and produces expected output.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import importlib.util
|
||||
|
||||
# Add examples to path
|
||||
examples_dir = Path(__file__).parent.parent.parent / "examples"
|
||||
sys.path.insert(0, str(examples_dir))
|
||||
|
||||
# Load the demo module
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"link_navigation_demo",
|
||||
examples_dir / "09_link_navigation_demo.py"
|
||||
)
|
||||
demo_module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(demo_module)
|
||||
|
||||
|
||||
def test_link_demo_imports():
|
||||
"""Test that the link demo can be imported without errors."""
|
||||
assert demo_module is not None
|
||||
|
||||
|
||||
def test_create_paragraph_with_links():
|
||||
"""Test creating a paragraph with mixed text and links."""
|
||||
create_paragraph_with_links = demo_module.create_paragraph_with_links
|
||||
from pyWebLayout.abstract.block import Paragraph
|
||||
from pyWebLayout.abstract.inline import LinkedWord, Word
|
||||
from pyWebLayout.abstract.functional import LinkType
|
||||
|
||||
text_parts = [
|
||||
('text', "Click"),
|
||||
('link', "here", "https://example.com", LinkType.EXTERNAL, "test_link"),
|
||||
('text', "to visit"),
|
||||
]
|
||||
|
||||
para = create_paragraph_with_links(text_parts)
|
||||
assert isinstance(para, Paragraph)
|
||||
assert len(para.words) == 4 # "Click", "here" (linked), "to", "visit"
|
||||
|
||||
# Check that the second word is a LinkedWord
|
||||
assert isinstance(para.words[1], LinkedWord)
|
||||
assert para.words[1].text == "here"
|
||||
assert para.words[1].location == "https://example.com"
|
||||
assert para.words[1]._link_type == LinkType.EXTERNAL
|
||||
|
||||
|
||||
def test_link_callback_function():
|
||||
"""Test that link callbacks work correctly."""
|
||||
link_callback = demo_module.link_callback
|
||||
demo_module.link_clicks = []
|
||||
|
||||
callback = link_callback("test_id")
|
||||
callback()
|
||||
|
||||
assert "test_id" in demo_module.link_clicks
|
||||
|
||||
|
||||
def test_create_example_1_internal_links():
|
||||
"""Test creating internal links example."""
|
||||
create_example_1 = demo_module.create_example_1_internal_links
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_1()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_2_external_links():
|
||||
"""Test creating external links example."""
|
||||
create_example_2 = demo_module.create_example_2_external_links
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_2()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_3_api_links():
|
||||
"""Test creating API links example."""
|
||||
create_example_3 = demo_module.create_example_3_api_links
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_3()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_4_function_links():
|
||||
"""Test creating function links example."""
|
||||
create_example_4 = demo_module.create_example_4_function_links
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_4()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_different_link_types():
|
||||
"""Test that different link types are created correctly."""
|
||||
create_paragraph_with_links = demo_module.create_paragraph_with_links
|
||||
from pyWebLayout.abstract.functional import LinkType
|
||||
|
||||
# Test each link type
|
||||
link_types = [
|
||||
(LinkType.INTERNAL, "#section1"),
|
||||
(LinkType.EXTERNAL, "https://example.com"),
|
||||
(LinkType.API, "/api/action"),
|
||||
(LinkType.FUNCTION, "function()"),
|
||||
]
|
||||
|
||||
for link_type, location in link_types:
|
||||
para = create_paragraph_with_links([
|
||||
('link', "test", location, link_type, f"test_{link_type.name}")
|
||||
])
|
||||
assert len(para.words) == 1
|
||||
assert para.words[0]._link_type == link_type
|
||||
assert para.words[0].location == location
|
||||
|
||||
|
||||
def test_combine_pages_into_grid():
|
||||
"""Test combining pages into grid."""
|
||||
combine_pages_into_grid = demo_module.combine_pages_into_grid
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
|
||||
# Create a few pages
|
||||
page_style = PageStyle()
|
||||
pages = [
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style)
|
||||
]
|
||||
|
||||
combined = combine_pages_into_grid(pages, "Test Title")
|
||||
|
||||
# Should create a combined image
|
||||
from PIL import Image
|
||||
assert isinstance(combined, Image.Image)
|
||||
|
||||
# Should be larger than individual pages
|
||||
assert combined.size[0] > 200
|
||||
assert combined.size[1] > 200
|
||||
|
||||
|
||||
def test_main_function():
|
||||
"""Test that the main function runs without errors."""
|
||||
main = demo_module.main
|
||||
|
||||
# Run main (will create output files)
|
||||
result = main()
|
||||
|
||||
# Should return combined image and link clicks
|
||||
assert result is not None
|
||||
assert len(result) == 2
|
||||
|
||||
combined_image, link_clicks = result
|
||||
|
||||
# Should be a PIL image
|
||||
from PIL import Image
|
||||
assert isinstance(combined_image, Image.Image)
|
||||
|
||||
# Link clicks should be a list (may be empty since we're not actually clicking)
|
||||
assert isinstance(link_clicks, list)
|
||||
|
||||
# Output file should exist
|
||||
output_dir = Path("docs/images")
|
||||
assert (output_dir / "example_09_link_navigation.png").exists()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
@@ -0,0 +1,159 @@
|
||||
"""
|
||||
Test for forms example (10_forms_demo.py).
|
||||
|
||||
This test ensures the forms example runs correctly and produces expected output.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import importlib.util
|
||||
|
||||
# Add examples to path
|
||||
examples_dir = Path(__file__).parent.parent.parent / "examples"
|
||||
sys.path.insert(0, str(examples_dir))
|
||||
|
||||
# Load the demo module
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"forms_demo",
|
||||
examples_dir / "10_forms_demo.py"
|
||||
)
|
||||
demo_module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(demo_module)
|
||||
|
||||
|
||||
def test_forms_demo_imports():
|
||||
"""Test that the forms demo can be imported without errors."""
|
||||
assert demo_module is not None
|
||||
|
||||
|
||||
def test_form_submit_callback():
|
||||
"""Test that form submit callbacks work correctly."""
|
||||
form_submit_callback = demo_module.form_submit_callback
|
||||
demo_module.form_submissions = []
|
||||
|
||||
callback = form_submit_callback("test_form")
|
||||
callback({"field1": "value1"})
|
||||
|
||||
assert len(demo_module.form_submissions) == 1
|
||||
assert demo_module.form_submissions[0][0] == "test_form"
|
||||
assert demo_module.form_submissions[0][1] == {"field1": "value1"}
|
||||
|
||||
|
||||
def test_create_example_1_text_fields():
|
||||
"""Test creating text fields example."""
|
||||
create_example_1 = demo_module.create_example_1_text_fields
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_1()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_2_number_fields():
|
||||
"""Test creating number fields example."""
|
||||
create_example_2 = demo_module.create_example_2_number_fields
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_2()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_3_selection_fields():
|
||||
"""Test creating selection fields example."""
|
||||
create_example_3 = demo_module.create_example_3_selection_fields
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_3()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 600)
|
||||
|
||||
|
||||
def test_create_example_4_complete_form():
|
||||
"""Test creating complete form example."""
|
||||
create_example_4 = demo_module.create_example_4_complete_form
|
||||
from pyWebLayout.concrete.page import Page
|
||||
|
||||
page = create_example_4()
|
||||
assert isinstance(page, Page)
|
||||
assert page.size == (500, 700)
|
||||
|
||||
|
||||
def test_all_form_field_types():
|
||||
"""Test that all FormFieldType values are demonstrated."""
|
||||
from pyWebLayout.abstract.functional import FormFieldType
|
||||
|
||||
# All field types that should be in examples
|
||||
expected_types = {
|
||||
FormFieldType.TEXT,
|
||||
FormFieldType.PASSWORD,
|
||||
FormFieldType.EMAIL,
|
||||
FormFieldType.URL,
|
||||
FormFieldType.TEXTAREA,
|
||||
FormFieldType.NUMBER,
|
||||
FormFieldType.DATE,
|
||||
FormFieldType.TIME,
|
||||
FormFieldType.RANGE,
|
||||
FormFieldType.COLOR,
|
||||
FormFieldType.CHECKBOX,
|
||||
FormFieldType.RADIO,
|
||||
FormFieldType.SELECT,
|
||||
FormFieldType.HIDDEN
|
||||
}
|
||||
|
||||
# This test verifies that the example includes all major field types
|
||||
# (the actual verification would happen by inspecting the forms,
|
||||
# but this confirms the enum exists)
|
||||
assert len(expected_types) == 14
|
||||
|
||||
|
||||
def test_combine_pages_into_grid():
|
||||
"""Test combining pages into grid."""
|
||||
combine_pages_into_grid = demo_module.combine_pages_into_grid
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
|
||||
# Create a few pages
|
||||
page_style = PageStyle()
|
||||
pages = [
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style),
|
||||
Page(size=(200, 200), style=page_style)
|
||||
]
|
||||
|
||||
combined = combine_pages_into_grid(pages, "Test Title")
|
||||
|
||||
# Should create a combined image
|
||||
from PIL import Image
|
||||
assert isinstance(combined, Image.Image)
|
||||
|
||||
|
||||
def test_main_function():
|
||||
"""Test that the main function runs without errors."""
|
||||
main = demo_module.main
|
||||
|
||||
# Run main (will create output files)
|
||||
result = main()
|
||||
|
||||
# Should return combined image and form submissions
|
||||
assert result is not None
|
||||
assert len(result) == 2
|
||||
|
||||
combined_image, form_submissions = result
|
||||
|
||||
# Should be a PIL image
|
||||
from PIL import Image
|
||||
assert isinstance(combined_image, Image.Image)
|
||||
|
||||
# Form submissions should be a list
|
||||
assert isinstance(form_submissions, list)
|
||||
|
||||
# Output file should exist
|
||||
output_dir = Path("docs/images")
|
||||
assert (output_dir / "example_10_forms.png").exists()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
Reference in New Issue
Block a user