chiark / gitweb /
Add some rendering unit tests
authorSimon Tatham <anakin@pobox.com>
Sat, 2 Dec 2023 13:37:01 +0000 (13:37 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 2 Dec 2023 13:37:01 +0000 (13:37 +0000)
mastodonochrome
text.py

index b5fa0e45370a418d7dea0272a72f643c6ffced61..09971df16e569e0355a3636844a8daf9f6d8e8cb 100755 (executable)
@@ -8,7 +8,9 @@ import argparse
 import calendar
 import requests
 import string
+import sys
 import time
+import unittest
 
 import text
 
@@ -79,14 +81,27 @@ class MainUI(Client):
                 for line in thing.render(80):
                     print(line.ecma48())
 
+class MyTestLoader(unittest.TestLoader):
+    def loadTestsFromModule(self, module):
+        suite = super().loadTestsFromModule(module)
+        if module.__name__ == '__main__':
+            suite.addTests(super().loadTestsFromModule(text))
+        return suite
+
 def main():
     parser = argparse.ArgumentParser(
         description=__doc__,
         formatter_class=argparse.RawDescriptionHelpFormatter)
     parser.add_argument("--log", help="File to log debug information to.")
+    parser.add_argument("--test", nargs=argparse.REMAINDER,
+                        help="Run unit tests.")
     parser.set_defaults(action=MainUI)
     args = parser.parse_args()
 
+    if args.test is not None:
+        return unittest.main(argv=[sys.argv[0]] + args.test,
+                             testLoader=MyTestLoader())
+
     instance = "hachyderm.io" # FIXME
     if "://" not in instance:
         instance = "https://" + instance
diff --git a/text.py b/text.py
index 4821b5792255b753ba86e20054a563ec5ff57df8..a99a61def05d3ea376145988ebcabef1f989fd12 100644 (file)
--- a/text.py
+++ b/text.py
@@ -4,6 +4,7 @@ import html.parser
 import io
 import itertools
 import time
+import unittest
 import wcwidth
 
 class ColouredString:
@@ -34,7 +35,10 @@ class ColouredString:
         return self.s
 
     def __repr__(self):
-        return f"ColouredString({self.s!r}, {self.c!r})"
+        if self.c.rstrip(" ") == "":
+            return f"ColouredString({self.s!r})"
+        else:
+            return f"ColouredString({self.s!r}, {self.c!r})"
 
     def __eq__(self, rhs):
         rhs = type(self)(rhs)
@@ -104,7 +108,7 @@ class Paragraph:
                 yield line
                 line, space = ColouredString(''), ColouredString('')
 
-        if len(line) != 0:
+        if len(line) != 0 or len(self.words) == 0:
             yield line
 
     def empty(self):
@@ -122,6 +126,9 @@ class Paragraph:
             else:
                 self.unfinished_word += c
 
+    def __repr__(self):
+        return f"Paragraph({self.words!r}, unfinished={self.unfinished_word!r})"
+
 class HTMLParser(html.parser.HTMLParser):
     def __init__(self):
         super().__init__()
@@ -136,7 +143,7 @@ class HTMLParser(html.parser.HTMLParser):
         if tag == "p":
             if not self.paras[-1].empty():
                 self.paras.append(Paragraph())
-                self.paras.append(Paragraph())
+            self.paras.append(Paragraph())
             return
 
         if tag == "br":
@@ -164,3 +171,56 @@ class HTMLParser(html.parser.HTMLParser):
             self.paras.pop(0)
         while len(self.paras) > 0 and self.paras[-1].empty():
             self.paras.pop()
+
+class RenderTests(unittest.TestCase):
+    def testBlank(self):
+        bl = BlankLine()
+        self.assertEqual(list(bl.render(80)), [ColouredString('')])
+
+    def testSeparator(self):
+        sl = SeparatorLine(time.mktime((2023,12,2,13,14,15,-1,-1,-1)))
+        self.assertEqual(list(sl.render(40)), [
+            ColouredString('-----------[Sat Dec  2 13:14:15 2023]--',
+                           'SSSSSSSSSSSSDDDDDDDDDDDDDDDDDDDDDDDDSSS'),
+        ])
+
+    def testFrom(self):
+        fl = FromLine("@a@b.c", "abc abc")
+        self.assertEqual(list(fl.render(80)), [
+            ColouredString('From: abc abc (@a@b.c)',
+                           '      FFFFFFFFFFFFFFFF'),
+        ])
+
+    def parse_html(self, html, width=50):
+        pp = HTMLParser()
+        pp.feed(html)
+        pp.done()
+        return list(itertools.chain(*[para.render(width)
+                                      for para in pp.paras]))
+
+    def testHTML(self):
+        html = "<p>Testing, testing, 1, 2, 3</p>"
+        self.assertEqual(self.parse_html(html), [
+            ColouredString('Testing, testing, 1, 2, 3'),
+        ])
+
+        html = "<p>First para</p><p>Second para</p>"
+        self.assertEqual(self.parse_html(html), [
+            ColouredString('First para'),
+            ColouredString(''),
+            ColouredString('Second para'),
+        ])
+
+        html = "<p>First line<br>Second line</p>"
+        self.assertEqual(self.parse_html(html), [
+            ColouredString('First line'),
+            ColouredString('Second line'),
+        ])
+
+    def testWrap(self):
+        html = ("<p>Pease porridge hot, pease porridge cold, pease porridge "
+                "in the pot, nine days old</p>")
+        self.assertEqual(self.parse_html(html), [
+            ColouredString('Pease porridge hot, pease porridge cold, pease'),
+            ColouredString('porridge in the pot, nine days old'),
+        ])