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