From 368364a13aaf4933eb9d19bf49fea9f069d67e6e Mon Sep 17 00:00:00 2001 From: deathaxe Date: Sat, 23 Mar 2024 22:09:39 +0100 Subject: [PATCH] Add DeferrabbleViewTestCase (#247) This commit ... 1. adds `DeferrabbleViewTestCase` class 2. extends `ViewTestCase` class 3. bases various existing unit self tests on them --- tests/_Deferred/tests/test.py | 35 ++++------------ tests/_Failure/tests/test.py | 21 ++-------- tests/_Output/tests/test.py | 21 ++-------- tests/_Success/tests/test.py | 21 ++-------- unittesting/__init__.py | 2 + unittesting/core/py33/case.py | 6 +++ unittesting/core/py38/case.py | 5 +++ unittesting/helpers/__init__.py | 8 ++-- unittesting/helpers/view_test_case.py | 59 +++++++++++++++++++++++++-- 9 files changed, 92 insertions(+), 86 deletions(-) diff --git a/tests/_Deferred/tests/test.py b/tests/_Deferred/tests/test.py index 60430ae7..e986c838 100644 --- a/tests/_Deferred/tests/test.py +++ b/tests/_Deferred/tests/test.py @@ -1,35 +1,14 @@ -import sublime -from unittest import TestCase # FIXME Import unused? # noqa: F401 -from unittesting import DeferrableTestCase, expectedFailure +from unittesting import DeferrableViewTestCase, expectedFailure -class TestDeferrable(DeferrableTestCase): - - def setUp(self): - self.view = sublime.active_window().new_file() - # make sure we have a window to work with - s = sublime.load_settings("Preferences.sublime-settings") - s.set("close_windows_when_empty", False) - - def tearDown(self): - if self.view: - self.view.set_scratch(True) - self.view.window().focus_view(self.view) - self.view.window().run_command("close_file") - - def setText(self, string): - self.view.run_command("insert", {"characters": string}) - - def getRow(self, row): - return self.view.substr(self.view.line(self.view.text_point(row, 0))) +class TestDeferrable(DeferrableViewTestCase): def test_defer(self): self.setText("foo") - self.view.sel().clear() - self.view.sel().add(sublime.Region(0, 0)) - sublime.set_timeout(lambda: self.setText("foo"), 100) + self.setCaretTo(0, 0) + self.defer(100, self.insertText, "foo") yield 200 - self.assertEqual(self.getRow(0), "foofoo") + self.assertEqual(self.getRowText(0), "foofoo") def test_condition(self): x = [] @@ -40,7 +19,7 @@ def append(): def condition(): return len(x) == 1 - sublime.set_timeout(append, 100) + self.defer(100, append) # wait until `condition()` is true yield condition @@ -54,7 +33,7 @@ def test_condition_timeout(self): def append(): x.append(1) - sublime.set_timeout(append, 100) + self.defer(100, append) # wait until condition timeout yield {"condition": lambda: False, "timeout": 500} diff --git a/tests/_Failure/tests/test.py b/tests/_Failure/tests/test.py index 43c9f073..bedcd729 100644 --- a/tests/_Failure/tests/test.py +++ b/tests/_Failure/tests/test.py @@ -1,22 +1,9 @@ -import sublime -from unittest import TestCase +from unittesting import ViewTestCase -class TestHelloWorld(TestCase): - - def setUp(self): - self.view = sublime.active_window().new_file() - # make sure we have a window to work with - s = sublime.load_settings("Preferences.sublime-settings") - s.set("close_windows_when_empty", False) - - def tearDown(self): - if self.view: - self.view.set_scratch(True) - self.view.window().focus_view(self.view) - self.view.window().run_command("close_file") +class TestHelloWorld(ViewTestCase): def test_hello_world(self): - self.view.run_command("insert", {"characters": "hello world"}) - first_row = self.view.substr(self.view.line(0)) + self.setText("hello world") + first_row = self.getRowText(0) self.assertEqual(first_row, "hello world!") diff --git a/tests/_Output/tests/test.py b/tests/_Output/tests/test.py index 041cbf4b..619cf01a 100644 --- a/tests/_Output/tests/test.py +++ b/tests/_Output/tests/test.py @@ -1,22 +1,9 @@ -import sublime -from unittest import TestCase +from unittesting import ViewTestCase -class TestHelloWorld(TestCase): - - def setUp(self): - self.view = sublime.active_window().new_file() - # make sure we have a window to work with - s = sublime.load_settings("Preferences.sublime-settings") - s.set("close_windows_when_empty", False) - - def tearDown(self): - if self.view: - self.view.set_scratch(True) - self.view.window().focus_view(self.view) - self.view.window().run_command("close_file") +class TestHelloWorld(ViewTestCase): def test_hello_world(self): - self.view.run_command("insert", {"characters": "hello world"}) - first_row = self.view.substr(self.view.line(0)) + self.setText("hello world") + first_row = self.getRowText(0) self.assertEqual(first_row, "hello world") diff --git a/tests/_Success/tests/test.py b/tests/_Success/tests/test.py index 041cbf4b..619cf01a 100644 --- a/tests/_Success/tests/test.py +++ b/tests/_Success/tests/test.py @@ -1,22 +1,9 @@ -import sublime -from unittest import TestCase +from unittesting import ViewTestCase -class TestHelloWorld(TestCase): - - def setUp(self): - self.view = sublime.active_window().new_file() - # make sure we have a window to work with - s = sublime.load_settings("Preferences.sublime-settings") - s.set("close_windows_when_empty", False) - - def tearDown(self): - if self.view: - self.view.set_scratch(True) - self.view.window().focus_view(self.view) - self.view.window().run_command("close_file") +class TestHelloWorld(ViewTestCase): def test_hello_world(self): - self.view.run_command("insert", {"characters": "hello world"}) - first_row = self.view.substr(self.view.line(0)) + self.setText("hello world") + first_row = self.getRowText(0) self.assertEqual(first_row, "hello world") diff --git a/unittesting/__init__.py b/unittesting/__init__.py index 1f43c687..f4cea726 100644 --- a/unittesting/__init__.py +++ b/unittesting/__init__.py @@ -1,6 +1,7 @@ from .core import AWAIT_WORKER from .core import DeferrableTestCase from .core import expectedFailure +from .helpers import DeferrableViewTestCase from .helpers import OverridePreferencesTestCase from .helpers import TempDirectoryTestCase from .helpers import ViewTestCase @@ -12,6 +13,7 @@ "DeferrableTestCase", "expectedFailure", "run_scheduler", + "DeferrableViewTestCase", "OverridePreferencesTestCase", "TempDirectoryTestCase", "ViewTestCase", diff --git a/unittesting/core/py33/case.py b/unittesting/core/py33/case.py index bf4c65fa..617bd359 100644 --- a/unittesting/core/py33/case.py +++ b/unittesting/core/py33/case.py @@ -3,7 +3,9 @@ import warnings from functools import wraps from unittest.case import _ExpectedFailure, _UnexpectedSuccess, SkipTest, _Outcome + from ...utils import isiterable +from .runner import defer def expectedFailure(func): @@ -52,6 +54,10 @@ def _executeTestPart(self, function, outcome, isTest=False): outcome.success = False outcome.errors.append(sys.exc_info()) + @staticmethod + def defer(delay, callback, *args, **kwargs): + defer(delay, callback, *args, **kwargs) + def run(self, result=None): orig_result = result if result is None: diff --git a/unittesting/core/py38/case.py b/unittesting/core/py38/case.py index a4df5018..6f43a76e 100644 --- a/unittesting/core/py38/case.py +++ b/unittesting/core/py38/case.py @@ -1,6 +1,7 @@ import sys import unittest from unittest.case import _Outcome +from .runner import defer from ...utils import isiterable @@ -26,6 +27,10 @@ def _callCleanup(self, function, *args, **kwargs): if isiterable(deferred): yield from deferred + @staticmethod + def defer(delay, callback, *args, **kwargs): + defer(delay, callback, *args, **kwargs) + def run(self, result=None): orig_result = result if result is None: diff --git a/unittesting/helpers/__init__.py b/unittesting/helpers/__init__.py index 2c4a039a..12085652 100644 --- a/unittesting/helpers/__init__.py +++ b/unittesting/helpers/__init__.py @@ -1,3 +1,5 @@ -from .override_preferences_test_cast import OverridePreferencesTestCase # noqa: F401 -from .temp_directory_test_case import TempDirectoryTestCase # noqa: F401 -from .view_test_case import ViewTestCase # noqa: F401 +# noqa: F401 +from .override_preferences_test_cast import OverridePreferencesTestCase +from .temp_directory_test_case import TempDirectoryTestCase +from .view_test_case import DeferrableViewTestCase +from .view_test_case import ViewTestCase diff --git a/unittesting/helpers/view_test_case.py b/unittesting/helpers/view_test_case.py index 402c6c2e..5df3d292 100644 --- a/unittesting/helpers/view_test_case.py +++ b/unittesting/helpers/view_test_case.py @@ -1,14 +1,24 @@ import sublime from unittest import TestCase +from .. import DeferrableTestCase +__all__ = [ + "DeferrableViewTestCase", + "ViewTestCase", +] -class ViewTestCase(TestCase): + +class ViewTestCaseMixin: def setUp(self): self.view = sublime.active_window().new_file() + # make sure we have a window to work with + settings = sublime.load_settings("Preferences.sublime-settings") + settings.set("close_windows_when_empty", False) + settings = self.view.settings() - default_settings = getattr(self.__class__, 'view_settings', {}) + default_settings = getattr(self.__class__, "view_settings", {}) for key, value in default_settings.items(): settings.set(key, value) @@ -17,8 +27,49 @@ def tearDown(self): self.view.set_scratch(True) self.view.close() - def _viewContents(self): + def addCaretAt(self, row, col): + """Add caret to given point (row, col).""" + self.view.sel().add(self.textPoint(row, col)) + + def setCaretTo(self, row, col): + """Move caret to given point (row, col).""" + self.view.sel().clear() + self.view.sel().add(self.textPoint(row, col)) + + def textPoint(self, row, col): + """Return textpoint for given row,col coordinats.""" + return self.view.text_point(row, col) + + def getRowText(self, row): + """Return given row's content text.""" + return self.view.substr(self.view.line(self.view.text_point(row, 0))) + + def getText(self): + """Return view's content text.""" return self.view.substr(sublime.Region(0, self.view.size())) + def setText(self, text): + """Set whole view's content, replacing anything existing.""" + self.clearText() + self.insertText(text) + + def clearText(self): + """Clear whole view's content.""" + self.view.run_command("select_all") + self.view.run_command("right_delete") + + def insertText(self, text): + """Insert text at current position.""" + self.view.run_command("insert", {"characters": text}) + def assertViewContentsEqual(self, text): - self.assertEqual(self._viewContents(), text) + self.assertEqual(self.getText(), text) + + + +class ViewTestCase(ViewTestCaseMixin, TestCase): + pass + + +class DeferrableViewTestCase(ViewTestCaseMixin, DeferrableTestCase): + pass