OILS / display / pretty_test.py View on Github | oilshell.org

130 lines, 94 significant
1#!/usr/bin/env python2
2# coding=utf8
3
4import os
5import unittest
6
7from display import ansi
8from display import pretty # module under test
9from display import pp_value
10from display import ui
11from data_lang import j8
12from mycpp import mylib
13from typing import Optional
14
15import libc
16
17TEST_DATA_FILENAME = os.path.join(os.path.dirname(__file__), "pretty_test.txt")
18
19
20def _PrintCase(actual, expected, lineno=None):
21 if actual != expected:
22 # Print the different with real newlines, for easier reading.
23 print("ACTUAL:")
24 print(actual)
25 print("EXPECTED:")
26 print(expected)
27 print("END")
28 if lineno is not None:
29 print("ON LINE " + str(lineno + 1))
30
31
32class UiTest(unittest.TestCase):
33 """Test higher level ui.PrettyPrintValue()."""
34
35 def assertPretty(self, width, value_str, expected):
36 # type: (int, str, str, Optional[int]) -> None
37 parser = j8.Parser(value_str, True)
38 val = parser.ParseValue()
39
40 buf = mylib.BufWriter()
41 ui.PrettyPrintValue('', val, buf, max_width=width)
42
43 actual = buf.getvalue()
44 _PrintCase(actual, expected)
45 self.assertEqual(actual, expected)
46
47 def testTypePrefix(self):
48 self.assertPretty(24, '[null, "ok", 15]', "(List) [null, 'ok', 15]\n")
49 self.assertPretty(23, '[null, "ok", 15]', "(List)\n[null, 'ok', 15]\n")
50
51
52class PrettyTest(unittest.TestCase):
53
54 def setUp(self):
55 # Use settings that make testing easier.
56 self.encoder = pp_value.ValueEncoder()
57 self.encoder.SetUseStyles(False)
58
59 def assertPretty(self, width, value_str, expected, lineno=None):
60 # type: (int, str, str, Optional[int]) -> None
61 parser = j8.Parser(value_str, True)
62 val = parser.ParseValue()
63
64 buf = mylib.BufWriter()
65
66 doc = self.encoder.Value(val)
67
68 printer = pretty.PrettyPrinter(width)
69 printer.PrintDoc(doc, buf)
70
71 actual = buf.getvalue()
72 _PrintCase(actual, expected, lineno=lineno)
73 self.assertEqual(actual, expected)
74
75 def testsFromFile(self):
76 # TODO: convert tests to this new style
77 self.encoder.ysh_style = False
78
79 chunks = [(None, -1, [])]
80 for lineno, line in enumerate(
81 open(TEST_DATA_FILENAME).read().splitlines()):
82 if line.startswith("> "):
83 chunks[-1][2].append(line[2:])
84 elif line.startswith("#"):
85 pass
86 elif line.strip() == "":
87 pass
88 else:
89 for keyword in ["Width", "Input", "Expect"]:
90 if line.startswith(keyword):
91 if chunks[-1][0] != keyword:
92 chunks.append((keyword, lineno, []))
93 parts = line.split(" > ", 1)
94 if len(parts) == 2:
95 chunks[-1][2].append(parts[1])
96 break
97 else:
98 raise Exception(
99 "Invalid pretty printing test case line. Lines must start with one of: Width, Input, Expect, >, #",
100 line)
101
102 test_cases = []
103 width = 80
104 value = ""
105 for (keyword, lineno, lines) in chunks:
106 block = "\n".join(lines)
107 if keyword == "Width":
108 width = int(block)
109 elif keyword == "Input":
110 value = block
111 elif keyword == "Expect":
112 test_cases.append((width, value, block, lineno))
113 else:
114 pass
115
116 for (width, value, expected, lineno) in test_cases:
117 self.assertPretty(width, value, expected, lineno)
118
119 def testStyles(self):
120 self.encoder.SetUseStyles(True)
121 self.assertPretty(
122 20, '[null, "ok", 15]',
123 '[' + ansi.RED + 'null' + ansi.RESET + ", " + ansi.GREEN + "'ok'" +
124 ansi.RESET + ", " + ansi.YELLOW + '15' + ansi.RESET + ']')
125
126
127if __name__ == '__main__':
128 # To simulate the OVM_MAIN patch in pythonrun.c
129 libc.cpython_reset_locale()
130 unittest.main()