From 6fc2f771b1ad0ed63a6ea4dcd13ffd4a36f29776 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 29 Jul 2018 16:14:35 +0200 Subject: [PATCH 1/3] tests: move/rename/cleanup vspec based tests The main motivation is to being able to use normal/other pytest based tests. Therefore this moves everything from conftest into test_integration itself. --- conftest.py | 75 ----------------------- pytest.ini | 3 - setup.cfg | 3 + test/test_integration.py | 60 ++++++++++++++++++ test/{ => vspec}/completions.vim | 0 test/{ => vspec}/completions_disabled.vim | 0 test/{ => vspec}/documentation.vim | 0 test/{ => vspec}/goto.vim | 0 test/{ => vspec}/pyimport.vim | 0 test/{ => vspec}/signatures.vim | 0 test_integration.py | 2 - 11 files changed, 63 insertions(+), 80 deletions(-) delete mode 100644 conftest.py delete mode 100644 pytest.ini create mode 100644 test/test_integration.py rename test/{ => vspec}/completions.vim (100%) rename test/{ => vspec}/completions_disabled.vim (100%) rename test/{ => vspec}/documentation.vim (100%) rename test/{ => vspec}/goto.vim (100%) rename test/{ => vspec}/pyimport.vim (100%) rename test/{ => vspec}/signatures.vim (100%) delete mode 100644 test_integration.py diff --git a/conftest.py b/conftest.py deleted file mode 100644 index 17d923e0..00000000 --- a/conftest.py +++ /dev/null @@ -1,75 +0,0 @@ -import os -import subprocess -import urllib.request -import zipfile - -import pytest - -VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/1.4.1.zip' -CACHE_FOLDER = 'build' -VSPEC_FOLDER = os.path.join(CACHE_FOLDER, 'vim-vspec-1.4.1') -VSPEC_RUNNER = os.path.join(VSPEC_FOLDER, 'bin/vspec') -TEST_DIR = 'test' - - -class IntegrationTestFile(object): - def __init__(self, path): - self.path = path - - def run(self): - output = subprocess.check_output( - [VSPEC_RUNNER, '.', VSPEC_FOLDER, self.path]) - had_ok = False - for line in output.splitlines(): - if (line.startswith(b'not ok') or - line.startswith(b'Error') or - line.startswith(b'Bail out!')): - pytest.fail("{0} failed:\n{1}".format( - self.path, output.decode('utf-8')), pytrace=False) - if not had_ok and line.startswith(b'ok'): - had_ok = True - if not had_ok: - pytest.fail("{0} failed: no 'ok' found:\n{1}".format( - self.path, output.decode('utf-8')), pytrace=False) - - @property - def name(self): - name = os.path.basename(self.path) - name, _, _ = name.rpartition('.') - return name - - def __repr__(self): - return "<%s: %s>" % (type(self), self.path) - - -def pytest_configure(config): - if not os.path.isdir(CACHE_FOLDER): - os.mkdir(CACHE_FOLDER) - - if not os.path.exists(VSPEC_FOLDER): - name, hdrs = urllib.request.urlretrieve(VSPEC_URL) - z = zipfile.ZipFile(name) - for n in z.namelist(): - dest = os.path.join(CACHE_FOLDER, n) - destdir = os.path.dirname(dest) - if not os.path.isdir(destdir): - os.makedirs(destdir) - data = z.read(n) - if not os.path.isdir(dest): - with open(dest, 'wb') as f: - f.write(data) - z.close() - os.chmod(VSPEC_RUNNER, 0o777) - - -def pytest_generate_tests(metafunc): - """ - :type metafunc: _pytest.python.Metafunc - """ - def collect_tests(): - for f in os.listdir(TEST_DIR): - if f.endswith('.vim') and f != '_utils.vim': - yield IntegrationTestFile(os.path.join(TEST_DIR, f)) - - tests = list(collect_tests()) - metafunc.parametrize('case', tests, ids=[test.name for test in tests]) diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 16700c3c..00000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -# Ignore all files -norecursedirs = * diff --git a/setup.cfg b/setup.cfg index 7da1f960..93e190e5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,5 @@ +[tool:pytest] +testpaths = test + [flake8] max-line-length = 100 diff --git a/test/test_integration.py b/test/test_integration.py new file mode 100644 index 00000000..942fb033 --- /dev/null +++ b/test/test_integration.py @@ -0,0 +1,60 @@ +"""Runs tests from ./vspec in vim-vspec.""" +import os +import subprocess +import urllib.request +import zipfile + +import pytest + +VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/1.4.1.zip' +root = os.path.dirname(os.path.dirname(__file__)) +CACHE_FOLDER = os.path.join(root, 'build') +VSPEC_FOLDER = os.path.join(CACHE_FOLDER, 'vim-vspec-1.4.1') +VSPEC_RUNNER = os.path.join(VSPEC_FOLDER, 'bin/vspec') +TEST_DIR = os.path.join(root, 'test', 'vspec') + + +@pytest.fixture(scope='session') +def install_vspec(request): + if not os.path.isdir(CACHE_FOLDER): + os.mkdir(CACHE_FOLDER) + + if not os.path.exists(VSPEC_FOLDER): + name, hdrs = urllib.request.urlretrieve(VSPEC_URL) + z = zipfile.ZipFile(name) + for n in z.namelist(): + dest = os.path.join(CACHE_FOLDER, n) + destdir = os.path.dirname(dest) + if not os.path.isdir(destdir): + os.makedirs(destdir) + data = z.read(n) + if not os.path.isdir(dest): + with open(dest, 'wb') as f: + f.write(data) + z.close() + os.chmod(VSPEC_RUNNER, 0o777) + + +def get_vspec_tests(): + for f in os.listdir(TEST_DIR): + yield os.path.relpath(os.path.join(TEST_DIR, f)) + + +@pytest.mark.parametrize('path', get_vspec_tests()) +def test_integration(install_vspec, path): + output = subprocess.check_output( + [VSPEC_RUNNER, '.', VSPEC_FOLDER, os.path.relpath(path, root)], + cwd=root, + ) + had_ok = False + for line in output.splitlines(): + if (line.startswith(b'not ok') or + line.startswith(b'Error') or + line.startswith(b'Bail out!')): + pytest.fail("{0} failed:\n{1}".format( + path, output.decode('utf-8')), pytrace=False) + if not had_ok and line.startswith(b'ok'): + had_ok = True + if not had_ok: + pytest.fail("{0} failed: no 'ok' found:\n{1}".format( + path, output.decode('utf-8')), pytrace=False) diff --git a/test/completions.vim b/test/vspec/completions.vim similarity index 100% rename from test/completions.vim rename to test/vspec/completions.vim diff --git a/test/completions_disabled.vim b/test/vspec/completions_disabled.vim similarity index 100% rename from test/completions_disabled.vim rename to test/vspec/completions_disabled.vim diff --git a/test/documentation.vim b/test/vspec/documentation.vim similarity index 100% rename from test/documentation.vim rename to test/vspec/documentation.vim diff --git a/test/goto.vim b/test/vspec/goto.vim similarity index 100% rename from test/goto.vim rename to test/vspec/goto.vim diff --git a/test/pyimport.vim b/test/vspec/pyimport.vim similarity index 100% rename from test/pyimport.vim rename to test/vspec/pyimport.vim diff --git a/test/signatures.vim b/test/vspec/signatures.vim similarity index 100% rename from test/signatures.vim rename to test/vspec/signatures.vim diff --git a/test_integration.py b/test_integration.py deleted file mode 100644 index d47e06be..00000000 --- a/test_integration.py +++ /dev/null @@ -1,2 +0,0 @@ -def test_integration(case, monkeypatch, pytestconfig): - case.run() From bb9dec305fd178364791e7ed9797c3b4668ab1a7 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 29 Jul 2018 16:46:39 +0200 Subject: [PATCH 2/3] fixup! tests: move/rename/cleanup vspec based tests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ed049c6f..e5ad52a3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ test: - pytest test_*.py + pytest build: mkdir $@ From eba8a4d9be5c216dac6d2a2b6254896764394744 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 29 Jul 2018 16:54:41 +0200 Subject: [PATCH 3/3] WIP/RFC: Add base for testing via pytest directly This uses Vim's --remote-expr and --remote-send, which should allow for better testing of some things in the future. --- test/test_units.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 test/test_units.py diff --git a/test/test_units.py b/test/test_units.py new file mode 100644 index 00000000..38658ec1 --- /dev/null +++ b/test/test_units.py @@ -0,0 +1,77 @@ +import subprocess +import time +import shlex + +import pytest + + +class VimError(Exception): + pass + + +class Vim: + def __init__(self, exe, servername): + self.base_args = [exe, '-u', 'NONE', '--not-a-term', + '--servername', servername] + cmd = self.base_args + ['--startuptime', '/tmp/s'] + print('Running: %s' % ' '.join(shlex.quote(x) for x in cmd)) + self._server = self._popen_vim(cmd) + self._wait_for_server() + + def _popen_vim(self, cmd): + return subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.DEVNULL) + + def _wait_for_server(self): + waited = 0 + while not self._eval('1', ignore_error=True): + time.sleep(0.1) + waited += 0.1 + print('waited: %.2f' % waited) + + def _eval(self, expr, ignore_error=False): + proc = self._popen_vim(self.base_args + ['--remote-expr', expr]) + (stdout, stderr) = proc.communicate() + if not ignore_error: + if stderr: + raise VimError('Error with --remote-expr: %s' % (stderr,)) + assert proc.returncode == 0 + return stdout.decode('utf-8').rstrip('\n') + + def eval(self, expr): + return self._eval(expr) + + def sendkeys(self, keys): + proc = self._popen_vim(self.base_args + ['--remote-send', keys]) + (stdout, stderr) = proc.communicate() + if stderr: + raise VimError('Error with --remote-expr: %s' % (stderr,)) + assert proc.returncode == 0 + + +@pytest.fixture(scope='session') +def vim_exe(): + return 'vim' + + +@pytest.fixture(scope='session') +def vim_servername(): + return 'JEDI-VIM-TESTS' + + +@pytest.fixture(scope='session') +def vim(vim_exe, vim_servername): + return Vim(vim_exe, vim_servername) + + +def test_smoke(vim): + """Tests that this mechanism works.""" + assert vim.eval('1') + vim.sendkeys('ifoo') + assert vim.eval('getline(".")') == 'foo' + vim.sendkeys('dd') + assert vim.eval('getline(".")') == 'foodd' + vim.sendkeys(r'\dd') + assert vim.eval('getline(".")') == ''