commit e9576a7a9812d63abfaf03227a8c6074271296ca Author: Damian Johnson atagar@torproject.org Date: Sat Apr 2 15:39:31 2016 -0700
Unit test rendering about popup
Hell yeah, we can unit test curses! Just a proof of concept for our simplest draw function but this can be applied to anything, opening a brave new world of testability!
/me does a little happy dance --- nyx/curses.py | 16 ++++++++++++++++ nyx/popups.py | 4 ++-- test/__init__.py | 38 ++++++++++++++++++++++++++++++++++++++ test/popups.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/nyx/curses.py b/nyx/curses.py index 909a055..6d3b170 100644 --- a/nyx/curses.py +++ b/nyx/curses.py @@ -15,6 +15,7 @@ if we want Windows support in the future too. raw_screen - provides direct access to the curses screen key_input - get keypress by user curses_attr - curses encoded text attribute + screenshot - dump of the present on-screen content
is_color_supported - checks if terminal supports color output get_color_override - provides color we override requests with @@ -250,6 +251,21 @@ def curses_attr(*attributes): return encoded
+def screenshot(): + """ + Provides a dump of the present content of the screen. + + :returns: **str** with the present content shown on the screen + """ + + lines = [] + + for y in range(CURSES_SCREEN.getmaxyx()[0]): + lines.append(CURSES_SCREEN.instr(y, 0).rstrip()) + + return '\n'.join(lines).rstrip() + + def is_color_supported(): """ Checks if curses currently supports rendering colors. diff --git a/nyx/popups.py b/nyx/popups.py index c56cb25..e65be70 100644 --- a/nyx/popups.py +++ b/nyx/popups.py @@ -147,7 +147,7 @@ def show_about():
with nyx.curses.CURSES_LOCK: nyx.curses.draw(_render, top = nyx.controller.get_controller().header_panel().get_height(), width = 80, height = 9) - keypress = nyx.curses.key_input() + nyx.curses.key_input()
def show_counts(title, counts): @@ -195,7 +195,7 @@ def show_counts(title, counts): else: nyx.curses.draw(_render_stats, top = top, width = 80, height = 4 + max(1, len(counts)))
- keypress = nyx.curses.key_input() + nyx.curses.key_input()
def show_sort_dialog(title, options, old_selection, option_colors): diff --git a/test/__init__.py b/test/__init__.py index e64593c..44a53b0 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -2,8 +2,12 @@ Unit tests for nyx. """
+import collections +import time import unittest
+import nyx.curses + from nyx import expand_path, join, uses_settings
from mock import patch, Mock @@ -16,6 +20,40 @@ __all__ = [ 'tracker', ]
+# If set we make test content we render for this many seconds. + +SHOW_RENDERED_CONTENT = None + +RenderResult = collections.namedtuple('RenderResult', ['content', 'return_value', 'runtime']) + + +def render(func): + """ + Runs the given curses function, providing content that's rendered on the + screen. + + :param function func: draw function to be invoked + + :returns: :data:`~test.RenderResult` with information about what was rendered + """ + + attr = {} + + def draw_func(): + nyx.curses.disable_acs() + start_time = time.time() + attr['return_value'] = func() + attr['runtime'] = time.time() - start_time + attr['content'] = nyx.curses.screenshot() + + if SHOW_RENDERED_CONTENT: + time.sleep(SHOW_RENDERED_CONTENT) + + with patch('nyx.curses.key_input', return_value = Mock()): + nyx.curses.start(draw_func, transparent_background = True, cursor = False) + + return RenderResult(attr.get('content'), attr.get('return_value'), attr.get('runtime')) +
class TestBaseUtil(unittest.TestCase): @patch('nyx.tor_controller') diff --git a/test/popups.py b/test/popups.py new file mode 100644 index 0000000..c4f56ea --- /dev/null +++ b/test/popups.py @@ -0,0 +1,31 @@ +""" +Unit tests for nyx.popups. +""" + +import unittest + +import nyx.popups +import test + +from mock import patch + +EXPECTED_ABOUT_POPUP = """ +About:-------------------------------------------------------------------------+ +| Nyx, version 1.4.6-dev (released April 28, 2011) | +| Written by Damian Johnson (atagar@torproject.org) | +| Project page: http://www.atagar.com/arm/ | +| | +| Released under the GPL v3 (http://www.gnu.org/licenses/gpl.html) | +| | +| Press any key... | ++------------------------------------------------------------------------------+ +""".strip() + + +class TestPopups(unittest.TestCase): + @patch('nyx.controller.get_controller') + def test_about(self, get_controller_mock): + get_controller_mock().header_panel().get_height.return_value = 0 + + rendered = test.render(nyx.popups.show_about) + self.assertEqual(EXPECTED_ABOUT_POPUP, rendered.content)
tor-commits@lists.torproject.org