diff --git a/core/tests/test_trezor.ui.text.py b/core/tests/test_trezor.ui.text.py new file mode 100644 index 000000000..086cf0bb5 --- /dev/null +++ b/core/tests/test_trezor.ui.text.py @@ -0,0 +1,149 @@ +import mock +from common import * + +from trezor import ui +from trezor.ui import text, display + +if False: + from typing import List, Tuple + + +class TestTextSpan(unittest.TestCase): + def lines(self, span: text.Span) -> List[Tuple[str, int, bool]]: + result = [] + while True: + should_continue = span.next_line() + substr = span.string[span.start : span.start + span.length] + result.append((substr, span.width, span.word_break)) + if not should_continue: + break + return result + + def checkSpanWithoutWidths( + self, span: text.Span, expected: List[Tuple[str, bool]] + ) -> None: + expected_with_calculated_widths = [ + (string, ui.display.text_width(string, span.font), word_break) + for string, word_break in expected + ] + self.assertListEqual(self.lines(span), expected_with_calculated_widths) + + def test_basic(self): + span = text.Span("hello") + self.checkSpanWithoutWidths( + span, + [("hello", False)], + ) + + span.reset("world", start=0, font=ui.NORMAL) + self.checkSpanWithoutWidths( + span, + [("world", False)], + ) + + span.reset("", start=0, font=ui.NORMAL) + self.checkSpanWithoutWidths( + span, + [("", False)], + ) + + def test_two_lines(self): + line_width = display.text_width("hello world", ui.NORMAL) - 1 + span = text.Span("hello world", line_width=line_width) + self.checkSpanWithoutWidths( + span, + [ + ("hello", False), + ("world", False), + ], + ) + + def test_newlines(self): + span = text.Span("hello\nworld") + self.checkSpanWithoutWidths( + span, + [ + ("hello", False), + ("world", False), + ], + ) + + span = text.Span("\nhello\nworld\n") + self.checkSpanWithoutWidths( + span, + [ + ("", False), + ("hello", False), + ("world", False), + ("", False), + ], + ) + + def test_break_words(self): + line_width = display.text_width("hello w", ui.NORMAL) + text.DASH_WIDTH + span = text.Span("hello world", line_width=line_width, break_words=True) + self.checkSpanWithoutWidths( + span, + [ + ("hello w", True), + ("orld", False), + ], + ) + + def test_long_word(self): + line_width = display.text_width("establishme", ui.NORMAL) + text.DASH_WIDTH + span = text.Span( + "Down with the establishment!", line_width=line_width, break_words=False + ) + self.checkSpanWithoutWidths( + span, + [ + ("Down with", False), + ("the", False), + ("establishme", True), + ("nt!", False), + ], + ) + + def test_has_more_content(self): + line_width = display.text_width("hello world", ui.NORMAL) - 1 + span = text.Span("hello world", line_width=line_width) + self.assertTrue(span.has_more_content()) + self.assertTrue(span.next_line()) + self.assertEqual("hello", span.string[span.start : span.start + span.length]) + + # has_more_content is True because there's text remaining on the line + self.assertTrue(span.has_more_content()) + # next_line is False because we should not continue iterating + self.assertFalse(span.next_line()) + self.assertEqual("world", span.string[span.start : span.start + span.length]) + + self.assertFalse(span.has_more_content()) + self.assertFalse(span.next_line()) + self.assertEqual("world", span.string[span.start : span.start + span.length]) + + + def test_has_more_content_trailing_newline(self): + span = text.Span("1\n2\n3\n") + + self.assertTrue(span.has_more_content()) + self.assertTrue(span.next_line()) + self.assertEqual("1", span.string[span.start : span.start + span.length]) + + self.assertTrue(span.has_more_content()) + self.assertTrue(span.next_line()) + self.assertEqual("2", span.string[span.start : span.start + span.length]) + + self.assertTrue(span.has_more_content()) + self.assertTrue(span.next_line()) + self.assertEqual("3", span.string[span.start : span.start + span.length]) + + # has_more_content is False because the "remaining" text is empty + self.assertFalse(span.has_more_content()) + # next_line is False because we should not continue iterating + self.assertFalse(span.next_line()) + self.assertEqual("", span.string[span.start : span.start + span.length]) + + +if __name__ == "__main__": + unittest.main()