babi: require 3.6.1+
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.3.0
|
||||
rev: v2.5.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
@@ -11,29 +11,30 @@ repos:
|
||||
- id: name-tests-test
|
||||
- id: requirements-txt-fixer
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.7.8
|
||||
rev: 3.7.9
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: [flake8-typing-imports==1.7.0]
|
||||
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||
rev: v1.4.4
|
||||
rev: v1.5
|
||||
hooks:
|
||||
- id: autopep8
|
||||
- repo: https://github.com/asottile/reorder_python_imports
|
||||
rev: v1.7.0
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: reorder-python-imports
|
||||
args: [--py3-plus]
|
||||
- repo: https://github.com/asottile/add-trailing-comma
|
||||
rev: v1.4.1
|
||||
rev: v1.5.0
|
||||
hooks:
|
||||
- id: add-trailing-comma
|
||||
args: [--py36-plus]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.24.0
|
||||
rev: v2.1.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py36-plus]
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.730
|
||||
rev: v0.761
|
||||
hooks:
|
||||
- id: mypy
|
||||
|
||||
@@ -21,7 +21,7 @@ classifiers =
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
python_requires = >=3.6
|
||||
python_requires = >=3.6.1
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
|
||||
@@ -3,8 +3,9 @@ import curses
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
from typing import Callable
|
||||
from typing import List
|
||||
from typing import NamedTuple
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Union
|
||||
from unittest import mock
|
||||
|
||||
@@ -14,6 +15,11 @@ from babi.main import main
|
||||
from babi.screen import VERSION_STR
|
||||
from testing.runner import PrintsErrorRunner
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Protocol
|
||||
else:
|
||||
Protocol = object
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def xdg_data_home(tmpdir):
|
||||
@@ -69,10 +75,14 @@ class Screen:
|
||||
self.width, self.height = width, height
|
||||
|
||||
|
||||
class Op(Protocol):
|
||||
def __call__(self, screen: Screen) -> None: ...
|
||||
|
||||
|
||||
class AwaitText(NamedTuple):
|
||||
text: str
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
if self.text not in screen.screenshot():
|
||||
raise AssertionError(f'expected: {self.text!r}')
|
||||
|
||||
@@ -80,7 +90,7 @@ class AwaitText(NamedTuple):
|
||||
class AwaitTextMissing(NamedTuple):
|
||||
text: str
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
if self.text in screen.screenshot():
|
||||
raise AssertionError(f'expected missing: {self.text!r}')
|
||||
|
||||
@@ -89,14 +99,14 @@ class AwaitCursorPosition(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
assert (self.x, self.y) == (screen.x, screen.y)
|
||||
|
||||
|
||||
class AssertCursorLineEquals(NamedTuple):
|
||||
line: str
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
assert screen.lines[screen.y].rstrip() == self.line
|
||||
|
||||
|
||||
@@ -104,14 +114,14 @@ class AssertScreenLineEquals(NamedTuple):
|
||||
n: int
|
||||
line: str
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
assert screen.lines[self.n].rstrip() == self.line
|
||||
|
||||
|
||||
class AssertFullContents(NamedTuple):
|
||||
contents: str
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
assert screen.screenshot() == self.contents
|
||||
|
||||
|
||||
@@ -119,19 +129,19 @@ class Resize(NamedTuple):
|
||||
width: int
|
||||
height: int
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
screen.resize(width=self.width, height=self.height)
|
||||
|
||||
|
||||
class KeyPress(NamedTuple):
|
||||
wch: Union[int, str]
|
||||
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
raise AssertionError('unreachable')
|
||||
|
||||
|
||||
class CursesError(NamedTuple):
|
||||
def __call__(self, screen):
|
||||
def __call__(self, screen: Screen) -> None:
|
||||
raise curses.error()
|
||||
|
||||
|
||||
@@ -223,7 +233,7 @@ class DeferredRunner:
|
||||
def __init__(self, command, width=80, height=24, colors=256):
|
||||
self.command = command
|
||||
self._i = 0
|
||||
self._ops: Callable[[Screen], None] = []
|
||||
self._ops: List[Op] = []
|
||||
self.screen = Screen(width, height)
|
||||
self._colors = colors
|
||||
|
||||
@@ -236,8 +246,10 @@ class DeferredRunner:
|
||||
self.screen.screenshot()
|
||||
raise
|
||||
self._i += 1
|
||||
print(f'KEY: {self._ops[self._i - 1].wch!r}')
|
||||
return self._ops[self._i - 1].wch
|
||||
keypress_event = self._ops[self._i - 1]
|
||||
assert isinstance(keypress_event, KeyPress)
|
||||
print(f'KEY: {keypress_event.wch!r}')
|
||||
return keypress_event.wch
|
||||
|
||||
def await_text(self, text):
|
||||
self._ops.append(AwaitText(text))
|
||||
@@ -312,7 +324,7 @@ class DeferredRunner:
|
||||
def _curses_initscr(self):
|
||||
curses.COLORS = self._colors
|
||||
self._curses_update_lines_cols()
|
||||
self.screen.enabled = True
|
||||
self.screen.disabled = False
|
||||
return CursesScreen(self)
|
||||
|
||||
def _curses_endwin(self):
|
||||
@@ -338,7 +350,7 @@ class DeferredRunner:
|
||||
# KeyPress with failing condition or error
|
||||
for i in range(self._i, len(self._ops)):
|
||||
if self._ops[i] != KeyPress('n'):
|
||||
raise AssertionError(self.ops[i:])
|
||||
raise AssertionError(self._ops[i:])
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
||||
Reference in New Issue
Block a user