2022-07-04 20:53:53 +01:00
from __future__ import annotations
2022-07-04 14:48:28 +01:00
from rich . segment import Segment
from textual . _styles_cache import StylesCache
2022-10-13 11:15:15 +01:00
from textual . color import Color
from textual . css . styles import Styles
from textual . geometry import Region , Size
2022-12-26 18:06:35 +00:00
from textual . strip import Strip
2022-07-04 14:48:28 +01:00
2023-02-04 15:53:00 +01:00
def _extract_content ( lines : list [ Strip ] ) - > list [ str ] :
2022-07-04 14:48:28 +01:00
""" Extract the text content from lines. """
content = [ " " . join ( segment . text for segment in line ) for line in lines ]
return content
def test_set_dirty ( ) :
cache = StylesCache ( )
cache . set_dirty ( Region ( 3 , 4 , 10 , 2 ) )
assert not cache . is_dirty ( 3 )
assert cache . is_dirty ( 4 )
assert cache . is_dirty ( 5 )
assert not cache . is_dirty ( 6 )
def test_border ( ) :
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
styles = Styles ( )
styles . border = ( " heavy " , " white " )
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 5 , 5 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
content . __getitem__ ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
text_content = _extract_content ( lines )
expected_text = [
" ┏━━━┓ " ,
" ┃foo┃ " ,
" ┃bar┃ " ,
" ┃baz┃ " ,
" ┗━━━┛ " ,
]
assert text_content == expected_text
def test_padding ( ) :
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
styles = Styles ( )
styles . padding = 1
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 5 , 5 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
content . __getitem__ ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
text_content = _extract_content ( lines )
expected_text = [
" " ,
" foo " ,
" bar " ,
" baz " ,
" " ,
]
assert text_content == expected_text
def test_padding_border ( ) :
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
styles = Styles ( )
styles . padding = 1
styles . border = ( " heavy " , " white " )
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 7 , 7 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
content . __getitem__ ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
text_content = _extract_content ( lines )
expected_text = [
" ┏━━━━━┓ " ,
" ┃ ┃ " ,
" ┃ foo ┃ " ,
" ┃ bar ┃ " ,
" ┃ baz ┃ " ,
" ┃ ┃ " ,
" ┗━━━━━┛ " ,
]
assert text_content == expected_text
def test_outline ( ) :
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
styles = Styles ( )
styles . outline = ( " heavy " , " white " )
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 3 , 3 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
content . __getitem__ ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
text_content = _extract_content ( lines )
expected_text = [
" ┏━┓ " ,
" ┃a┃ " ,
" ┗━┛ " ,
]
assert text_content == expected_text
def test_crop ( ) :
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
styles = Styles ( )
styles . padding = 1
styles . border = ( " heavy " , " white " )
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 7 , 7 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
content . __getitem__ ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
crop = Region ( 2 , 2 , 3 , 3 ) ,
)
text_content = _extract_content ( lines )
expected_text = [
" foo " ,
" bar " ,
" baz " ,
]
assert text_content == expected_text
2023-02-04 15:53:00 +01:00
def test_dirty_cache ( ) - > None :
2022-07-04 14:48:28 +01:00
""" Check that we only render content once or if it has been marked as dirty. """
content = [
2023-02-04 15:53:00 +01:00
Strip ( [ Segment ( " foo " ) ] ) ,
Strip ( [ Segment ( " bar " ) ] ) ,
Strip ( [ Segment ( " baz " ) ] ) ,
2022-07-04 14:48:28 +01:00
]
rendered_lines : list [ int ] = [ ]
2023-02-04 15:53:00 +01:00
def get_content_line ( y : int ) - > Strip :
2022-07-04 14:48:28 +01:00
rendered_lines . append ( y )
return content [ y ]
styles = Styles ( )
styles . padding = 1
styles . border = ( " heavy " , " white " )
cache = StylesCache ( )
lines = cache . render (
styles ,
Size ( 7 , 7 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
get_content_line ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2023-03-22 11:07:38 +00:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
assert rendered_lines == [ 0 , 1 , 2 ]
del rendered_lines [ : ]
text_content = _extract_content ( lines )
2023-02-04 16:10:33 +01:00
2022-07-04 14:48:28 +01:00
expected_text = [
" ┏━━━━━┓ " ,
" ┃ ┃ " ,
" ┃ foo ┃ " ,
" ┃ bar ┃ " ,
" ┃ baz ┃ " ,
" ┃ ┃ " ,
" ┗━━━━━┛ " ,
]
assert text_content == expected_text
# Re-render styles, check that content was not requested
lines = cache . render (
styles ,
Size ( 7 , 7 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
get_content_line ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
assert rendered_lines == [ ]
del rendered_lines [ : ]
text_content = _extract_content ( lines )
assert text_content == expected_text
# Mark 2 lines as dirty
cache . set_dirty ( Region ( 0 , 2 , 7 , 2 ) )
lines = cache . render (
styles ,
Size ( 7 , 7 ) ,
Color . parse ( " blue " ) ,
Color . parse ( " green " ) ,
get_content_line ,
2025-08-20 21:37:58 +01:00
[ ] ,
2023-04-16 12:31:39 +01:00
None ,
None ,
2022-07-04 20:37:59 +01:00
content_size = Size ( 3 , 3 ) ,
2022-07-04 14:48:28 +01:00
)
assert rendered_lines == [ 0 , 1 ]
text_content = _extract_content ( lines )
assert text_content == expected_text