Skip to content

Commit

Permalink
Various UT fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbrittain committed Oct 22, 2023
1 parent f4ff3aa commit 285e82b
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ LATEST
- Fixed internal state of RadioButton values to be consistent with selection.
- Fixed handling of zero width modifiers.
- Fixed image conversion to use modern PIL API and sort off-by-one height error.
- Fixed parser bug returning list instead of colour tuple.

1.14.0
------
Expand Down
4 changes: 2 additions & 2 deletions asciimatics/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def parse(self):
:returns: a 3-tuple of (start offset in raw text, command to execute, parameters)
"""
if self._state.attributes:
yield (0, Parser.CHANGE_COLOURS, tuple(self._attributes))
yield (0, Parser.CHANGE_COLOURS, tuple(self._state.attributes))
offset = 0
while len(self._state.text) > 0:
letter = self._state.text[0]
Expand Down Expand Up @@ -352,7 +352,7 @@ def _handle_escape(st):

if self._state.init_colours:
self._state.init_colours = False
yield (0, Parser.CHANGE_COLOURS, self._state.attributes)
yield (0, Parser.CHANGE_COLOURS, tuple(self._state.attributes))
while len(self._state.text) > 0:
char = ord(self._state.text[0])
new_offset = 1
Expand Down
4 changes: 3 additions & 1 deletion asciimatics/renderers/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ def __init__(self, height, width):

@abstractmethod
def _render_now(self):
pass
"""
Render the next iteration.
"""

def _play_content(self, text):
"""
Expand Down
56 changes: 33 additions & 23 deletions tests/renderers/test_images.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import unittest
import os
import sys
from unittest.mock import MagicMock
from asciimatics.renderers import ImageFile, ColourImageFile
from asciimatics.screen import Screen
from asciimatics.screen import Screen, Canvas
if sys.platform != "win32":
import curses

Expand Down Expand Up @@ -39,20 +40,33 @@ def test_image_files(self):
' .:::;;;;9#r::2 ',
' s.::r:; '])

def test_image_files_256(self):
"""
Check that the ImageFile renderer works.
"""
renderer = ImageFile(
os.path.join(os.path.dirname(__file__), "globe.gif"), height=10, colours=256)

# Check an image looks plausible
image = next(renderer.images)
self.maxDiff = None
self.assertEqual(
image,
[' sA3h3h3Hr2 ',
' ;:;G#99G@&3;;;r ',
' :::#9&&@@G;rrrr;;3 ',
'.:;;A&@AAGsssssrr;#H',
'::;;;r39@srssssrr;A2',
'.::;;rrrrr@@@@9;r;;A',
's::;;;;rr2@@@@@@#;; ',
' s:::;;;;;;9&&&3;: ',
' .:::;;;;9#r::2 ',
' s.::r:; '])

def test_colour_image_file(self):
"""
Check that the ColourImageFile renderer works.
"""
# Skip for non-Windows if the terminal definition is incomplete.
# This typically means we're running inside a non-standard terminal.
# For example, this happens when embedded in PyCharm.
if sys.platform != "win32":
if not (("FORCE_TTY" in os.environ and os.environ["FORCE_TTY"] == "Y") or sys.stdout.isatty()):
self.skipTest("Not a valid TTY")
curses.initscr()
if curses.tigetstr("ri") is None:
self.skipTest("No valid terminal definition")

def internal_checks(screen):
# Check the original FG only rendering
renderer = ColourImageFile(
Expand Down Expand Up @@ -108,22 +122,15 @@ def internal_checks(screen):
self.assertEqual(attr1[0], attr2[0])
self.assertEqual(attr2[0], attr2[2])

Screen.wrapper(internal_checks, height=15)
# Mock screen for better coverage.
screen = MagicMock(spec=Screen, colours=16, unicode_aware=True, palette=Screen._8_palette)
canvas = Canvas(screen, 15, 40, 0, 0)
internal_checks(screen)

def test_uni_image_files(self):
"""
Check that the unicode ColourImageFile rendering works.
"""
# Skip for non-Windows if the terminal definition is incomplete.
# This typically means we're running inside a non-standard terminal.
# For example, this happens when embedded in PyCharm.
if sys.platform != "win32":
if not (("FORCE_TTY" in os.environ and os.environ["FORCE_TTY"] == "Y") or sys.stdout.isatty()):
self.skipTest("Not a valid TTY")
curses.initscr()
if curses.tigetstr("ri") is None:
self.skipTest("No valid terminal definition")

def internal_checks(screen):
# Check the original FG only rendering
renderer = ColourImageFile(
Expand Down Expand Up @@ -154,7 +161,10 @@ def internal_checks(screen):
'..▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄....',
'.....▄▄▄▄▄▄▄▄▄▄......'])

Screen.wrapper(internal_checks, height=15)
# Mock screen for better coverage.
screen = MagicMock(spec=Screen, colours=16, unicode_aware=True, palette=Screen._8_palette)
canvas = Canvas(screen, 15, 40, 0, 0)
internal_checks(screen)


if __name__ == '__main__':
Expand Down
30 changes: 29 additions & 1 deletion tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ def test_controlcode_parser(self):
Check ControlCodeParser works as expected
"""
parser = ControlCodeParser()
parser.reset("\0\b\ra[", None)
parser.reset("\0\b\ra[", colours=(1, 2, 3))
tokens = parser.parse()
self.assertEqual(next(tokens), (0, Parser.CHANGE_COLOURS, (1, 2, 3)))
self.assertEqual(next(tokens), (0, Parser.DISPLAY_TEXT, "^@"))
self.assertEqual(next(tokens), (1, Parser.DISPLAY_TEXT, "^H"))
self.assertEqual(next(tokens), (2, Parser.DISPLAY_TEXT, "^M"))
Expand Down Expand Up @@ -289,3 +290,30 @@ def test_ansi_terminal_parser_bell(self):
with self.assertRaises(StopIteration):
next(tokens)

def test_ansi_terminal_parser_start_colour(self):
"""
Check AnsiTerminalParser uses the starting colours.
"""
parser = AnsiTerminalParser()
parser.reset("a", colours=(1,2,3))
tokens = parser.parse()
self.assertEqual(next(tokens), (0, Parser.CHANGE_COLOURS, (1, 2, 3)))
self.assertEqual(next(tokens), (0, Parser.DISPLAY_TEXT, "a"))

def test_ansi_terminal_parser_unknown(self):
"""
Check AnsiTerminalParser ignores unknown codes.
"""
parser = AnsiTerminalParser()
parser.reset("a\x1B[2345£", None)
tokens = parser.parse()
self.assertEqual(next(tokens), (0, Parser.DISPLAY_TEXT, "a"))
with self.assertRaises(StopIteration):
next(tokens)

parser.reset("a\x1B", None)
tokens = parser.parse()
self.assertEqual(next(tokens), (0, Parser.DISPLAY_TEXT, "a"))
with self.assertRaises(StopIteration):
next(tokens)

2 changes: 1 addition & 1 deletion tests/test_particles.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_shoot_screen(self):
screen = MagicMock(spec=Screen, colours=8)
canvas = Canvas(screen, 10, 40, 0, 0)
canvas.centre("Hello World!", 5)
effect = ShootScreen(canvas, canvas.width // 2, canvas.height // 2, 100)
effect = ShootScreen(canvas, canvas.width // 2, canvas.height // 2, 100, diameter=10)
self.check_effect(canvas,
effect,
lambda value: self.assertIn(chr(value[0]),
Expand Down
1 change: 1 addition & 0 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def test_boxtool(self):
"└───┘\n")

# DOUBLE_LINE
self.assertEqual(tool.style, SINGLE_LINE)
tool.style = DOUBLE_LINE
self.assertEqual("╔═══╗", tool.box_top(5))
self.assertEqual("╚═══╝", tool.box_bottom(5))
Expand Down

0 comments on commit 285e82b

Please sign in to comment.