test_ansi_code_processor.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # Standard library imports
  2. import unittest
  3. # Local imports
  4. from qtconsole.ansi_code_processor import AnsiCodeProcessor
  5. class TestAnsiCodeProcessor(unittest.TestCase):
  6. def setUp(self):
  7. self.processor = AnsiCodeProcessor()
  8. def test_clear(self):
  9. """ Do control sequences for clearing the console work?
  10. """
  11. string = '\x1b[2J\x1b[K'
  12. i = -1
  13. for i, substring in enumerate(self.processor.split_string(string)):
  14. if i == 0:
  15. self.assertEqual(len(self.processor.actions), 1)
  16. action = self.processor.actions[0]
  17. self.assertEqual(action.action, 'erase')
  18. self.assertEqual(action.area, 'screen')
  19. self.assertEqual(action.erase_to, 'all')
  20. elif i == 1:
  21. self.assertEqual(len(self.processor.actions), 1)
  22. action = self.processor.actions[0]
  23. self.assertEqual(action.action, 'erase')
  24. self.assertEqual(action.area, 'line')
  25. self.assertEqual(action.erase_to, 'end')
  26. else:
  27. self.fail('Too many substrings.')
  28. self.assertEqual(i, 1, 'Too few substrings.')
  29. def test_colors(self):
  30. """ Do basic controls sequences for colors work?
  31. """
  32. string = 'first\x1b[34mblue\x1b[0mlast'
  33. i = -1
  34. for i, substring in enumerate(self.processor.split_string(string)):
  35. if i == 0:
  36. self.assertEqual(substring, 'first')
  37. self.assertEqual(self.processor.foreground_color, None)
  38. elif i == 1:
  39. self.assertEqual(substring, 'blue')
  40. self.assertEqual(self.processor.foreground_color, 4)
  41. elif i == 2:
  42. self.assertEqual(substring, 'last')
  43. self.assertEqual(self.processor.foreground_color, None)
  44. else:
  45. self.fail('Too many substrings.')
  46. self.assertEqual(i, 2, 'Too few substrings.')
  47. def test_colors_xterm(self):
  48. """ Do xterm-specific control sequences for colors work?
  49. """
  50. string = '\x1b]4;20;rgb:ff/ff/ff\x1b' \
  51. '\x1b]4;25;rgbi:1.0/1.0/1.0\x1b'
  52. substrings = list(self.processor.split_string(string))
  53. desired = { 20 : (255, 255, 255),
  54. 25 : (255, 255, 255) }
  55. self.assertEqual(self.processor.color_map, desired)
  56. string = '\x1b[38;5;20m\x1b[48;5;25m'
  57. substrings = list(self.processor.split_string(string))
  58. self.assertEqual(self.processor.foreground_color, 20)
  59. self.assertEqual(self.processor.background_color, 25)
  60. def test_true_color(self):
  61. """Do 24bit True Color control sequences?
  62. """
  63. string = '\x1b[38;2;255;100;0m\x1b[48;2;100;100;100m'
  64. substrings = list(self.processor.split_string(string))
  65. self.assertEqual(self.processor.foreground_color, [255, 100, 0])
  66. self.assertEqual(self.processor.background_color, [100, 100, 100])
  67. def test_scroll(self):
  68. """ Do control sequences for scrolling the buffer work?
  69. """
  70. string = '\x1b[5S\x1b[T'
  71. i = -1
  72. for i, substring in enumerate(self.processor.split_string(string)):
  73. if i == 0:
  74. self.assertEqual(len(self.processor.actions), 1)
  75. action = self.processor.actions[0]
  76. self.assertEqual(action.action, 'scroll')
  77. self.assertEqual(action.dir, 'up')
  78. self.assertEqual(action.unit, 'line')
  79. self.assertEqual(action.count, 5)
  80. elif i == 1:
  81. self.assertEqual(len(self.processor.actions), 1)
  82. action = self.processor.actions[0]
  83. self.assertEqual(action.action, 'scroll')
  84. self.assertEqual(action.dir, 'down')
  85. self.assertEqual(action.unit, 'line')
  86. self.assertEqual(action.count, 1)
  87. else:
  88. self.fail('Too many substrings.')
  89. self.assertEqual(i, 1, 'Too few substrings.')
  90. def test_formfeed(self):
  91. """ Are formfeed characters processed correctly?
  92. """
  93. string = '\f' # form feed
  94. self.assertEqual(list(self.processor.split_string(string)), [''])
  95. self.assertEqual(len(self.processor.actions), 1)
  96. action = self.processor.actions[0]
  97. self.assertEqual(action.action, 'scroll')
  98. self.assertEqual(action.dir, 'down')
  99. self.assertEqual(action.unit, 'page')
  100. self.assertEqual(action.count, 1)
  101. def test_carriage_return(self):
  102. """ Are carriage return characters processed correctly?
  103. """
  104. string = 'foo\rbar' # carriage return
  105. splits = []
  106. actions = []
  107. for split in self.processor.split_string(string):
  108. splits.append(split)
  109. actions.append([action.action for action in self.processor.actions])
  110. self.assertEqual(splits, ['foo', None, 'bar'])
  111. self.assertEqual(actions, [[], ['carriage-return'], []])
  112. def test_carriage_return_newline(self):
  113. """transform CRLF to LF"""
  114. string = 'foo\rbar\r\ncat\r\n\n' # carriage return and newline
  115. # only one CR action should occur, and '\r\n' should transform to '\n'
  116. splits = []
  117. actions = []
  118. for split in self.processor.split_string(string):
  119. splits.append(split)
  120. actions.append([action.action for action in self.processor.actions])
  121. self.assertEqual(splits, ['foo', None, 'bar', '\r\n', 'cat', '\r\n', '\n'])
  122. self.assertEqual(actions, [[], ['carriage-return'], [], ['newline'], [], ['newline'], ['newline']])
  123. def test_beep(self):
  124. """ Are beep characters processed correctly?
  125. """
  126. string = 'foo\abar' # bell
  127. splits = []
  128. actions = []
  129. for split in self.processor.split_string(string):
  130. splits.append(split)
  131. actions.append([action.action for action in self.processor.actions])
  132. self.assertEqual(splits, ['foo', None, 'bar'])
  133. self.assertEqual(actions, [[], ['beep'], []])
  134. def test_backspace(self):
  135. """ Are backspace characters processed correctly?
  136. """
  137. string = 'foo\bbar' # backspace
  138. splits = []
  139. actions = []
  140. for split in self.processor.split_string(string):
  141. splits.append(split)
  142. actions.append([action.action for action in self.processor.actions])
  143. self.assertEqual(splits, ['foo', None, 'bar'])
  144. self.assertEqual(actions, [[], ['backspace'], []])
  145. def test_combined(self):
  146. """ Are CR and BS characters processed correctly in combination?
  147. BS is treated as a change in print position, rather than a
  148. backwards character deletion. Therefore a BS at EOL is
  149. effectively ignored.
  150. """
  151. string = 'abc\rdef\b' # CR and backspace
  152. splits = []
  153. actions = []
  154. for split in self.processor.split_string(string):
  155. splits.append(split)
  156. actions.append([action.action for action in self.processor.actions])
  157. self.assertEqual(splits, ['abc', None, 'def', None])
  158. self.assertEqual(actions, [[], ['carriage-return'], [], ['backspace']])
  159. if __name__ == '__main__':
  160. unittest.main()