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