1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
from unittest import skipUnless
from unittest.mock import PropertyMock, patch
from PIL import Image as PILImage
from PIL import ImageOps
from rich.console import Console
from rich.measure import Measurement
from tests.data import CONSOLE_OPTIONS, TEST_IMAGE, TEXTUAL_ENABLED
from tests.utils import load_non_seekable_bytes_io
@skipUnless(TEXTUAL_ENABLED, "Textual support disabled")
async def test_app() -> None:
from textual.app import App, ComposeResult
from textual_image.widget.sixel import Image
class TestApp(App[None]):
CSS = """
.auto {
width: auto;
height: auto;
}
.fixed {
width: 10;
height: 10;
}
"""
def compose(self) -> ComposeResult:
yield Image(TEST_IMAGE)
yield Image(TEST_IMAGE, classes="auto")
yield Image(TEST_IMAGE, classes="fixed")
yield Image()
yield Image(classes="auto")
app = TestApp()
# Not testing too much reasonable stuff, but, well, at least the code gets executed
async with app.run_test() as pilot:
with PILImage.open(TEST_IMAGE) as test_image:
app.query_one(Image).image = ImageOps.flip(test_image)
assert app.query_one(Image).image != TEST_IMAGE
await pilot.pause()
await pilot.app.run_action("app.command_palette")
await pilot.pause()
@skipUnless(TEXTUAL_ENABLED, "Textual support disabled")
async def test_unseekable_stream() -> None:
from textual.app import App, ComposeResult
from textual_image.widget.sixel import Image
image = Image(load_non_seekable_bytes_io(TEST_IMAGE))
class TestApp(App[None]):
def compose(self) -> ComposeResult:
yield image
yield image
yield image
app = TestApp()
# Not testing too much reasonable stuff, but, well, at least the code gets executed
async with app.run_test() as pilot:
with PILImage.open(TEST_IMAGE) as test_image:
app.query_one(Image).image = ImageOps.flip(test_image)
assert app.query_one(Image).image != TEST_IMAGE
await pilot.pause()
await pilot.app.run_action("app.command_palette")
await pilot.pause()
@skipUnless(TEXTUAL_ENABLED, "Textual support disabled")
def test_measure_noop_renderable() -> None:
from textual_image.widget.sixel import _NoopRenderable
assert _NoopRenderable(TEST_IMAGE).__rich_measure__(Console(), CONSOLE_OPTIONS) == Measurement(0, 0)
@skipUnless(TEXTUAL_ENABLED, "Textual support disabled")
async def test_handling_no_screen_on_render() -> None:
from textual.app import App, ComposeResult
from textual.dom import NoScreen
from textual.geometry import Region
from textual_image.widget.sixel import Image, _ImageSixelImpl
class TestApp(App[None]):
def compose(self) -> ComposeResult:
yield Image(TEST_IMAGE)
app = TestApp()
async with app.run_test():
sixel_impl = app.query_one(_ImageSixelImpl)
result = sixel_impl.render_lines(Region(10, 10, 10, 10))
assert result
with patch.object(_ImageSixelImpl, "screen", PropertyMock(side_effect=NoScreen)):
result = sixel_impl.render_lines(Region(10, 10, 10, 10))
assert not result
|