Merge branch 'update-tests' (early part) into develop

Missing most recent commit which disabled stages because
1. Disabling stages is not important.
2. Need not to close relevant PR.
This commit is contained in:
Foo 2018-08-12 22:39:48 +03:00
commit 1bed167d8e
27 changed files with 634 additions and 111 deletions

5
.gitignore vendored
View File

@ -10,4 +10,7 @@ build
message.fail message.fail
client/powerline /client/powerline
/tests/tmp
/tests/status

View File

@ -1,4 +1,5 @@
sudo: false sudo: false
dist: trusty
cache: cache:
directories: directories:
- $HOME/.cache/pip - $HOME/.cache/pip
@ -17,19 +18,25 @@ addons:
language: python language: python
install: tests/install.sh install: tests/install.sh
script: tests/test.sh script: tests/test.sh
matrix: jobs:
include: include:
- python: "2.6" - stage: UCS2 python
- python: "2.7" python: "2.7"
- python: "3.2"
- python: "3.3"
- python: "3.4"
- python: "3.5"
- python: "pypy"
- python: "pypy3"
- python: "2.7"
env: >- env: >-
USE_UCS2_PYTHON=1 USE_UCS2_PYTHON=1
UCS2_PYTHON_VARIANT="2.7" UCS2_PYTHON_VARIANT="2.7"
- stage: Old Python
python: "2.6"
- python: "3.2"
- stage: PyPy
python: "pypy"
- python: "pypy3"
- stage: Latest Python
python: "2.7"
- python: "3.6"
- stage: Intermediate versions
python: "3.3"
- python: "3.4"
- python: "3.5"
# vim: et # vim: et

View File

@ -159,7 +159,8 @@ username = False
_geteuid = getattr(os, 'geteuid', lambda: 1) _geteuid = getattr(os, 'geteuid', lambda: 1)
def user(pl, hide_user=None, hide_domain=False): @requires_segment_info
def user(pl, segment_info, hide_user=None, hide_domain=False):
'''Return the current user. '''Return the current user.
:param str hide_user: :param str hide_user:
@ -172,6 +173,11 @@ def user(pl, hide_user=None, hide_domain=False):
Highlight groups used: ``superuser`` or ``user``. It is recommended to define all highlight groups. Highlight groups used: ``superuser`` or ``user``. It is recommended to define all highlight groups.
''' '''
global username global username
if (
segment_info['environ'].get('_POWERLINE_RUNNING_SHELL_TESTS')
== 'ee5bcdc6-b749-11e7-9456-50465d597777'
):
return 'user'
if username is False: if username is False:
username = _get_user() username = _get_user()
if username is None: if username is None:

View File

@ -22,6 +22,11 @@ def hostname(pl, segment_info, only_if_ssh=False, exclude_domain=False):
:param bool exclude_domain: :param bool exclude_domain:
return the hostname without domain if there is one return the hostname without domain if there is one
''' '''
if (
segment_info['environ'].get('_POWERLINE_RUNNING_SHELL_TESTS')
== 'ee5bcdc6-b749-11e7-9456-50465d597777'
):
return 'hostname'
if only_if_ssh and not segment_info['environ'].get('SSH_CLIENT'): if only_if_ssh and not segment_info['environ'].get('SSH_CLIENT'):
return None return None
if exclude_domain: if exclude_domain:

View File

@ -46,13 +46,13 @@ if test -n "$USE_UCS2_PYTHON" ; then
mkvirtualenv -p "$PYTHON" cpython-ucs2-$UCS2_PYTHON_VARIANT mkvirtualenv -p "$PYTHON" cpython-ucs2-$UCS2_PYTHON_VARIANT
set -e set -e
. tests/bot-ci/scripts/common/main.sh . tests/bot-ci/scripts/common/main.sh
pip install . pip install --verbose --verbose --verbose .
if test "$UCS2_PYTHON_VARIANT" = "2.6" ; then if test "$UCS2_PYTHON_VARIANT" = "2.6" ; then
rm tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/pyuv*.whl rm tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/pyuv*.whl
fi fi
pip install --no-deps tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/*.whl pip install --no-deps tests/bot-ci/deps/wheels/ucs2-CPython-${UCS2_PYTHON_VARIANT}*/*.whl
else else
pip install . pip install --verbose --verbose --verbose .
# FIXME Uv watcher sometimes misses events and INotify is not available in # FIXME Uv watcher sometimes misses events and INotify is not available in
# Python-2.6, thus pyuv should be removed in order for VCS tests to # Python-2.6, thus pyuv should be removed in order for VCS tests to
# pass. # pass.

View File

@ -2,10 +2,93 @@
from __future__ import (unicode_literals, division, absolute_import, print_function) from __future__ import (unicode_literals, division, absolute_import, print_function)
import sys import sys
import os
if sys.version_info < (2, 7): if sys.version_info < (2, 7):
from unittest2 import TestCase, main # NOQA from unittest2 import TestCase as _TestCase # NOQA
from unittest2 import main as _main # NOQA
from unittest2.case import SkipTest # NOQA from unittest2.case import SkipTest # NOQA
else: else:
from unittest import TestCase, main # NOQA from unittest import TestCase as _TestCase # NOQA
from unittest import main as _main # NOQA
from unittest.case import SkipTest # NOQA from unittest.case import SkipTest # NOQA
from tests.modules.lib import PowerlineSingleTest
class PowerlineDummyTest(object):
def __enter__(self):
return self
def __exit__(self, *args):
pass
def fail(self, *args, **kwargs):
pass
def exception(self, *args, **kwargs):
pass
class PowerlineTestSuite(object):
def __init__(self, name):
self.name = name
def __enter__(self):
self.saved_current_suite = os.environ['POWERLINE_CURRENT_SUITE']
os.environ['POWERLINE_CURRENT_SUITE'] = (
self.saved_current_suite + '/' + self.name)
self.suite = self.saved_current_suite + '/' + self.name
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
self.exception(
'suite_noexcept',
'Exception while running test suite: {0!r}'.format(exc_value),
)
os.environ['POWERLINE_CURRENT_SUITE'] = self.saved_current_suite
def record_test_failure(self, fail_char, test_name, message, allow_failure=False):
if allow_failure:
fail_char = 'A' + fail_char
full_msg = '{fail_char} {suite}|{test_name} :: {message}'.format(
fail_char=fail_char,
suite=self.suite,
test_name=test_name,
message=message,
)
with open(os.environ['FAILURES_FILE'], 'a') as ffd:
ffd.write(full_msg + '\n')
return False
def exception(self, test_name, message, allow_failure=False):
return self.record_test_failure('E', test_name, message, allow_failure)
def fail(self, test_name, message, allow_failure=False):
return self.record_test_failure('F', test_name, message, allow_failure)
def test(self, name, attempts_left=0):
if not attempts_left:
return PowerlineSingleTest(self, name)
else:
return PowerlineDummyTest()
def subsuite(self, name):
return PowerlineTestSuite(name)
suite = None
def main(*args, **kwargs):
global suite
suite = PowerlineTestSuite(sys.argv[0])
_main(*args, **kwargs)
class TestCase(_TestCase):
def fail(self, msg=None):
suite.fail(self.__class__.__name__,
msg or 'Test failed without message')
super(TestCase, self).fail(*args, **kwargs)

View File

@ -161,3 +161,23 @@ def replace_env(key, new, environ=None, **kwargs):
r = kwargs.copy() r = kwargs.copy()
r['environ'] = environ or {} r['environ'] = environ or {}
return ItemReplace(r['environ'], key, new, r) return ItemReplace(r['environ'], key, new, r)
class PowerlineSingleTest(object):
def __init__(self, suite, name):
self.suite = suite
self.name = name
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
self.exception('Exception while running test: {0!r}'.format(
exc_value))
def fail(self, message, allow_failure=False):
return self.suite.fail(self.name, message, allow_failure)
def exception(self, message, allow_failure=False):
return self.suite.exception(self.name, message, allow_failure)

View File

@ -61,6 +61,7 @@ class ExpectProcess(threading.Thread):
self.buffer = [] self.buffer = []
self.child_lock = threading.Lock() self.child_lock = threading.Lock()
self.shutdown_event = threading.Event() self.shutdown_event = threading.Event()
self.started_event = threading.Event()
def run(self): def run(self):
with self.child_lock: with self.child_lock:
@ -70,6 +71,7 @@ class ExpectProcess(threading.Thread):
child.setwinsize(self.dim.rows, self.dim.cols) child.setwinsize(self.dim.rows, self.dim.cols)
sleep(0.5) sleep(0.5)
self.child = child self.child = child
self.started_event.set()
status = None status = None
while status is None and not self.shutdown_event.is_set(): while status is None and not self.shutdown_event.is_set():
try: try:
@ -111,21 +113,33 @@ class ExpectProcess(threading.Thread):
with self.child_lock: with self.child_lock:
self.child.send(data) self.child.send(data)
def get_highlighted_text(self, text, attrs, default_props=()): def get_highlighted_text(self, text, attrs, default_props=(),
use_escapes=False):
ret = [] ret = []
new_attrs = attrs.copy() new_attrs = attrs.copy()
for cell_properties, segment_text in text: for cell_properties, segment_text in text:
segment_text = segment_text.translate({'{': '{{', '}': '}}'}) if use_escapes:
if cell_properties not in new_attrs: escapes = ('\033[38;2;{0};{1};{2};48;2;{3};{4};{5}'.format(
new_attrs[cell_properties] = len(new_attrs) + 1 *(cell_properties[0] + cell_properties[1]))) + (
props_name = new_attrs[cell_properties] ';1' if cell_properties[2] else ''
if props_name in default_props: ) + (
ret.append(segment_text) ';3' if cell_properties[3] else ''
) + (
';4' if cell_properties[4] else ''
) + 'm'
ret.append(escapes + segment_text + '\033[0m')
else: else:
ret.append('{' + str(props_name) + ':' + segment_text + '}') segment_text = segment_text.translate({'{': '{{', '}': '}}'})
if cell_properties not in new_attrs:
new_attrs[cell_properties] = len(new_attrs) + 1
props_name = new_attrs[cell_properties]
if props_name in default_props:
ret.append(segment_text)
else:
ret.append('{' + str(props_name) + ':' + segment_text + '}')
return ''.join(ret), new_attrs return ''.join(ret), new_attrs
def get_row(self, row, attrs, default_props=()): def get_row(self, row, attrs, default_props=(), use_escapes=False):
with self.lock: with self.lock:
return self.get_highlighted_text(( return self.get_highlighted_text((
(key, ''.join((cell.text for cell in subline))) (key, ''.join((cell.text for cell in subline)))
@ -133,34 +147,48 @@ class ExpectProcess(threading.Thread):
self.vterm.vtscreen[row, col] self.vterm.vtscreen[row, col]
for col in range(self.dim.cols) for col in range(self.dim.cols)
), lambda cell: cell.cell_properties_key) ), lambda cell: cell.cell_properties_key)
), attrs, default_props) ), attrs, default_props, use_escapes)
def get_screen(self, attrs, default_props=()): def get_screen(self, attrs, default_props=(), use_escapes=False):
lines = [] lines = []
for row in range(self.dim.rows): for row in range(self.dim.rows):
line, attrs = self.get_row(row, attrs, default_props) line, attrs = self.get_row(row, attrs, default_props, use_escapes)
lines.append(line) lines.append(line)
return '\n'.join(lines), attrs return '\n'.join(lines), attrs
def test_expected_result(p, test, last_attempt, last_attempt_cb, attempts): def test_expected_result(p, test, last_attempt, last_attempt_cb, attempts):
debugging_tests = not not os.environ.get('_POWERLINE_DEBUGGING_TESTS')
expected_text, attrs = test['expected_result'] expected_text, attrs = test['expected_result']
result = None result = None
while attempts: while attempts:
actual_text, all_attrs = p.get_row(test['row'], attrs) if 'row' in test:
row = test['row']
else:
row = p.dim.rows - 1
while row >= 0 and not p[row, 0].text:
row -= 1
if row < 0:
row = 0
actual_text, all_attrs = p.get_row(row, attrs)
if actual_text == expected_text: if actual_text == expected_text:
return True return True
attempts -= 1 attempts -= 1
print('Actual result does not match expected. Attempts left: {0}.'.format(attempts)) print('Actual result does not match expected for row {0}. Attempts left: {1}.'.format(
row, attempts))
sleep(2) sleep(2)
print('Result:') print('Result (row {0}):'.format(row))
print(actual_text) print(actual_text)
print('Expected:') print('Expected:')
print(expected_text) print(expected_text)
print('Attributes:') print('Attributes:')
print(all_attrs) for v, k in sorted(
((v, k) for k, v in all_attrs.items()),
key=(lambda t: '%02u'.format(t[0]) if isinstance(t[0], int) else t[0]),
):
print('{k!r}: {v!r},'.format(v=v, k=k))
print('Screen:') print('Screen:')
screen, screen_attrs = p.get_screen(attrs) screen, screen_attrs = p.get_screen(attrs, use_escapes=debugging_tests)
print(screen) print(screen)
print(screen_attrs) print(screen_attrs)
print('_' * 80) print('_' * 80)
@ -220,8 +248,12 @@ def get_env(vterm_path, test_dir, *args, **kwargs):
return env return env
def do_terminal_tests(tests, cmd, dim, args, env, cwd=None, fin_cb=None, def do_terminal_tests(tests, cmd, dim, args, env, suite, cwd=None, fin_cb=None,
last_attempt_cb=None, attempts=3): last_attempt_cb=None, attempts=None):
debugging_tests = not not os.environ.get('_POWERLINE_DEBUGGING_TESTS')
default_attempts = 2 if debugging_tests else 3
if attempts is None:
attempts = default_attempts
lib = os.environ.get('POWERLINE_LIBVTERM') lib = os.environ.get('POWERLINE_LIBVTERM')
if not lib: if not lib:
if os.path.exists('tests/bot-ci/deps/libvterm/libvterm.so'): if os.path.exists('tests/bot-ci/deps/libvterm/libvterm.so'):
@ -240,22 +272,26 @@ def do_terminal_tests(tests, cmd, dim, args, env, cwd=None, fin_cb=None,
env=env, env=env,
) )
p.start() p.start()
p.started_event.wait()
ret = True ret = True
for test in tests: for i, test in enumerate(tests):
try: with suite.test(test.get('name', 'test_{0}'.format(i)),
test_prep = test['prep_cb'] attempts - 1) as ptest:
except KeyError: try:
pass test_prep = test['prep_cb']
else: except KeyError:
test_prep(p) pass
ret = ( else:
ret test_prep(p)
and test_expected_result(p, test, attempts == 0, test_result = test_expected_result(
last_attempt_cb, p, test, attempts == 0, last_attempt_cb,
test.get('attempts', 3)) test.get('attempts', default_attempts)
) )
if not test_result:
ptest.fail('Result does not match expected')
ret = ret and test_result
if ret: if ret:
return ret return ret

View File

@ -116,6 +116,7 @@ def get_functions(lib):
('cell', ctypes.POINTER(VTermScreenCell_s)) ('cell', ctypes.POINTER(VTermScreenCell_s))
)), )),
vterm_free=(None, (('vt', VTerm_p),)), vterm_free=(None, (('vt', VTerm_p),)),
vterm_set_utf8=(None, (('vt', VTerm_p), ('is_utf8', ctypes.c_int))),
) )
@ -173,6 +174,7 @@ class VTerm(object):
def __init__(self, lib, dim): def __init__(self, lib, dim):
self.functions = get_functions(lib) self.functions = get_functions(lib)
self.vt = self.functions.vterm_new(dim.rows, dim.cols) self.vt = self.functions.vterm_new(dim.rows, dim.cols)
self.functions.vterm_set_utf8(self.vt, 1)
self.vtscreen = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt)) self.vtscreen = VTermScreen(self.functions, self.functions.vterm_obtain_screen(self.vt))
self.vtscreen.reset(True) self.vtscreen.reset(True)

View File

@ -1,10 +1,29 @@
. tests/bot-ci/scripts/common/main.sh
set +x
: ${PYTHON:=python}
: ${USER:=`id -un`} : ${USER:=`id -un`}
: ${HOME:=`getent passwd $USER | cut -d: -f6`} : ${HOME:=`getent passwd $USER | cut -d: -f6`}
if test -z "${PYTHON}" ; then
if test -n "$USE_UCS2_PYTHON" ; then
LD_LIBRARY_PATH="$HOME/opt/cpython-ucs2-$UCS2_PYTHON_VARIANT/lib${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}"
fi
fi
export LD_LIBRARY_PATH
export USER
export HOME
if test -n "$USE_UCS2_PYTHON" ; then
POWERLINE_VIRTUALENV="cpython-ucs2-$UCS2_PYTHON_VARIANT"
PYTHON="$HOME/.virtualenvs/$POWERLINE_VIRTUALENV/bin/python"
if test -n "$BASH_VERSION" ; then
set +e
. virtualenvwrapper.sh
workon "$POWERLINE_VIRTUALENV"
set -e
fi
fi
. tests/bot-ci/scripts/common/main.sh silent
export USER HOME export USER HOME
if test -z "$FAILED" ; then if test -z "$FAILED" ; then
@ -13,7 +32,7 @@ if test -z "$FAILED" ; then
FAIL_SUMMARY="" FAIL_SUMMARY=""
TMP_ROOT="$ROOT/tests/tmp" TMP_ROOT="$ROOT/tests/tmp"
FAILURES_FILE="$ROOT/tests/failures" export FAILURES_FILE="$ROOT/tests/status"
fi fi
ANSI_CLEAR="\033[0K" ANSI_CLEAR="\033[0K"
@ -26,10 +45,29 @@ travis_fold() {
echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}" echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}"
} }
print_environ() {
echo "Using $PYTHON_IMPLEMENTATION version $PYTHON_VERSION."
echo "Path to Python executable: $PYTHON."
echo "Root: $ROOT."
echo "Branch: $BRANCH_NAME."
echo "sys.path:"
"$PYTHON" -c "for path in __import__('sys').path: print(' %r' % path)"
}
enter_suite() { enter_suite() {
set +x
local suite_name="$1" ; shift local suite_name="$1" ; shift
local final="$1"
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE}/$suite_name" export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE}/$suite_name"
travis_fold start "$POWERLINE_CURRENT_SUITE" travis_fold start "$POWERLINE_CURRENT_SUITE"
print_environ
if test "$final" = final ; then
if test -n "$POWERLINE_SUITE_FINAL" ; then
fail __suite__/enter/final E "Final suites do not allow nesting"
fi
export POWERLINE_SUITE_FINAL=1
# set -x
fi
} }
exit_suite() { exit_suite() {
@ -40,14 +78,17 @@ exit_suite() {
echo "Suite ${POWERLINE_CURRENT_SUITE} failed, summary:" echo "Suite ${POWERLINE_CURRENT_SUITE} failed, summary:"
echo "${FAIL_SUMMARY}" echo "${FAIL_SUMMARY}"
fi fi
set +x
travis_fold end "$POWERLINE_CURRENT_SUITE" travis_fold end "$POWERLINE_CURRENT_SUITE"
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}" export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}"
if test "$1" != "--continue" ; then if test "$1" != "--continue" ; then
exit $FAILED exit $FAILED
else
unset POWERLINE_SUITE_FINAL
fi fi
} }
fail() { _fail() {
local allow_failure= local allow_failure=
if test "$1" = "--allow-failure" ; then if test "$1" = "--allow-failure" ; then
shift shift
@ -56,15 +97,26 @@ fail() {
local test_name="$1" ; shift local test_name="$1" ; shift
local fail_char="$allow_failure$1" ; shift local fail_char="$allow_failure$1" ; shift
local message="$1" ; shift local message="$1" ; shift
local verb="$1" ; shift
local full_msg="$fail_char $POWERLINE_CURRENT_SUITE|$test_name :: $message" local full_msg="$fail_char $POWERLINE_CURRENT_SUITE|$test_name :: $message"
FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}" FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
echo "Failed: $full_msg" echo "$verb: $full_msg"
echo "$full_msg" >> "$FAILURES_FILE" echo "$full_msg" >> "$FAILURES_FILE"
if test -z "$allow_failure" ; then if test -z "$allow_failure" ; then
FAILED=1 FAILED=1
fi fi
} }
fail() {
_fail "$@" "Failed"
}
skip() {
local test_name="$1" ; shift
local message="$1" ; shift
_fail --allow-failure "$test_name" S "$message" "Skipped"
}
make_test_root() { make_test_root() {
local suffix="${POWERLINE_CURRENT_SUITE##*/}" local suffix="${POWERLINE_CURRENT_SUITE##*/}"

View File

@ -33,10 +33,10 @@ for script in "$ROOT"/tests/test_*/test.sh ; do
fi fi
done done
if test -e tests/failures ; then if test -e "$FAILURES_FILE" ; then
echo "Some tests failed. Summary:" echo "Fails and skips summary:"
cat tests/failures cat "$FAILURES_FILE"
rm tests/failures rm "$FAILURES_FILE"
fi fi
exit_suite exit_suite

View File

@ -102,7 +102,7 @@ if ! test -e "$DEPRECATED_SCRIPT" ; then
# skip "deprecated" "Missing deprecated bar bindings script" # skip "deprecated" "Missing deprecated bar bindings script"
: :
else else
enter_suite "deprecated" enter_suite "deprecated" final
for args in "" "0.5"; do for args in "" "0.5"; do
rm -rf "$TEST_ROOT/results" rm -rf "$TEST_ROOT/results"
mkdir "$TEST_ROOT/results" mkdir "$TEST_ROOT/results"
@ -132,7 +132,7 @@ else
exit_suite --continue exit_suite --continue
fi fi
enter_suite "awesome" enter_suite "awesome" final
ADDRESS="powerline-ipc-test-$$" ADDRESS="powerline-ipc-test-$$"
echo "Powerline address: $ADDRESS" echo "Powerline address: $ADDRESS"
rm -rf "$TEST_ROOT/results" rm -rf "$TEST_ROOT/results"

View File

@ -94,7 +94,7 @@ if ! test -e "$DEPRECATED_SCRIPT" ; then
# skip "deprecated" "Missing deprecated bar bindings script" # skip "deprecated" "Missing deprecated bar bindings script"
: :
else else
enter_suite "deprecated" enter_suite "deprecated" final
run python "$DEPRECATED_SCRIPT" $args > "$TEST_ROOT/deprecated.log" 2>&1 & run python "$DEPRECATED_SCRIPT" $args > "$TEST_ROOT/deprecated.log" 2>&1 &
SPID=$! SPID=$!
sleep 5 sleep 5
@ -122,7 +122,7 @@ else
sleep 5 sleep 5
killscript $SPID killscript $SPID
sleep 0.5 sleep 0.5
enter_suite "args($args)" enter_suite "args($args)" final
fnum=0 fnum=0
for file in "$TEST_ROOT/results"/*.log ; do for file in "$TEST_ROOT/results"/*.log ; do
if ! test -e "$file" ; then if ! test -e "$file" ; then

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
. tests/shlib/common.sh . tests/shlib/common.sh
enter_suite daemon enter_suite daemon final
export ADDRESS="powerline-ipc-test-$$" export ADDRESS="powerline-ipc-test-$$"
echo "Powerline address: $ADDRESS" echo "Powerline address: $ADDRESS"

View File

@ -0,0 +1,16 @@
# vim: ft=sh
set_theme_option() {
export POWERLINE_THEME_OVERRIDES="${POWERLINE_THEME_OVERRIDES};$1=$2"
}
set_theme() {
export POWERLINE_CONFIG_OVERRIDES="ext.shell.theme=$1"
}
set_virtual_env() {
export VIRTUAL_ENV="$HOME/.virtenvs/$1"
}
set_theme_option default_leftonly.segment_data.hostname.args.only_if_ssh false
set_theme default_leftonly
. "$ROOT/powerline/bindings/shell/powerline.sh"
export VIRTUAL_ENV=
cd "$TEST_ROOT/3rd"

View File

@ -0,0 +1,162 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys
from time import sleep
from subprocess import check_call
from glob import glob1
from traceback import print_exc
from argparse import ArgumentParser
from powerline.lib.dict import updated
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
def get_parser():
parser = ArgumentParser()
parser.add_argument('--type', action='store')
parser.add_argument('--client', action='store')
parser.add_argument('--binding', action='store')
parser.add_argument('args', action='append')
return parser
BINDING_OPTIONS = {
'dash': {
'cmd': 'dash',
'args': ['-i'],
'init': [
'. "$ROOT/tests/test_in_vterm/shell/inits/dash"',
],
},
}
def main(argv):
script_args = get_parser().parse_args(argv)
vterm_path = os.path.join(TEST_ROOT, 'path')
env = get_env(vterm_path, TEST_ROOT)
env['ROOT'] = os.path.abspath('.')
env['TEST_ROOT'] = TEST_ROOT
env['TEST_TYPE'] = script_args.type
env['TEST_CLIENT'] = script_args.client
env['LANG'] = 'en_US.UTF_8'
env['_POWERLINE_RUNNING_SHELL_TESTS'] = (
'ee5bcdc6-b749-11e7-9456-50465d597777')
dim = MutableDimensions(rows=50, cols=200)
binding_opts = BINDING_OPTIONS[script_args.binding]
cmd = os.path.join(vterm_path, binding_opts['cmd'])
args = binding_opts['args']
def gen_init(binding):
def init(p):
for line in binding_opts['init']:
p.send(line + '\n')
sleep(1)
return init
def gen_feed(line):
def feed(p):
p.send(line + '\n')
sleep(0.1)
return feed
base_attrs = {
((255, 204,0), (204, 51, 0), 0, 0, 0): 'H',
((204, 51, 0), (0, 102, 153), 0, 0, 0): 'sHU',
((255, 255, 255), (0, 102, 153), 1, 0, 0): 'U',
((0, 102, 153), (44, 44, 44), 0, 0, 0): 'sUB',
((199, 199, 199), (44, 44, 44), 0, 0, 0): 'B',
((44, 44, 44), (88, 88, 88), 0, 0, 0): 'sBD',
((199, 199, 199), (88, 88, 88), 0, 0, 0): 'D',
((144, 144, 144), (88, 88, 88), 0, 0, 0): 'sD',
((221, 221, 221), (88, 88, 88), 1, 0, 0): 'C',
((88, 88, 88), (0, 0, 0), 0, 0, 0): 'sDN',
((240, 240, 240), (0, 0, 0), 0, 0, 0): 'N',
((0, 102, 153), (51, 153, 204), 0, 0, 0): 'sUE',
((255, 255, 255), (51, 153, 204), 0, 0, 0): 'E',
((51, 153, 204), (44, 44, 44), 0, 0, 0): 'sEB',
}
tests = (
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_init(script_args.binding),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:vshells }{sD: }{D:3rd }{sD: }{C:.git }{sDN: }'
'{N:}',
base_attrs
),
'prep_cb': gen_feed('cd .git'),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_feed('cd ..'),
},
{
'expected_result': (
'{H:  hostname }{sHU: }'
'{U:user }{sUE: }'
'{E:(e) some-venv }{sEB: }'
'{B: BRANCH }{sBD: }'
'{D:… }{sD: }{D:tmp }{sD: }{D:vshells }{sD: }{C:3rd }{sDN: }'
'{N:}',
base_attrs,
),
'prep_cb': gen_feed('set_virtual_env some-venv'),
},
)
with PowerlineTestSuite('shell') as suite:
return do_terminal_tests(
tests=tests,
cmd=cmd,
dim=dim,
args=args,
env=env,
cwd=TEST_ROOT,
suite=suite,
)
if __name__ == '__main__':
if main(sys.argv[1:]):
raise SystemExit(0)
else:
raise SystemExit(1)

View File

@ -0,0 +1,119 @@
#!/bin/bash
. tests/shlib/common.sh
. tests/shlib/vterm.sh
enter_suite vshells
vterm_setup
HAS_SOCAT=
HAS_C_CLIENT=
git init "$TEST_ROOT/3rd"
git --git-dir="$TEST_ROOT/3rd/.git" checkout -b BRANCH
export DIR1=""
export DIR2=""
mkdir "$TEST_ROOT/3rd/$DIR1"
mkdir "$TEST_ROOT/3rd/$DIR2"
mkdir "$TEST_ROOT"/3rd/'\[\]'
mkdir "$TEST_ROOT"/3rd/'%%'
mkdir "$TEST_ROOT"/3rd/'#[bold]'
mkdir "$TEST_ROOT"/3rd/'(echo)'
mkdir "$TEST_ROOT"/3rd/'$(echo)'
mkdir "$TEST_ROOT"/3rd/'`echo`'
mkdir "$TEST_ROOT"/3rd/'«Unicode!»'
mkdir "$TEST_ROOT/fish_home"
mkdir "$TEST_ROOT/fish_home/fish"
mkdir "$TEST_ROOT/fish_home/fish/generated_completions"
cp -r "$ROOT/tests/test_shells/ipython_home" "$TEST_ROOT"
ln -s "$(which env)" "$TEST_ROOT/path"
ln -s "$(which git)" "$TEST_ROOT/path"
ln -s "$(which sleep)" "$TEST_ROOT/path"
ln -s "$(which cat)" "$TEST_ROOT/path"
ln -s "$(which false)" "$TEST_ROOT/path"
ln -s "$(which true)" "$TEST_ROOT/path"
ln -s "$(which kill)" "$TEST_ROOT/path"
ln -s "$(which echo)" "$TEST_ROOT/path"
ln -s "$(which which)" "$TEST_ROOT/path"
ln -s "$(which dirname)" "$TEST_ROOT/path"
ln -s "$(which wc)" "$TEST_ROOT/path"
ln -s "$(which stty)" "$TEST_ROOT/path"
ln -s "$(which cut)" "$TEST_ROOT/path"
ln -s "$(which bc)" "$TEST_ROOT/path"
ln -s "$(which expr)" "$TEST_ROOT/path"
ln -s "$(which mktemp)" "$TEST_ROOT/path"
ln -s "$(which grep)" "$TEST_ROOT/path"
ln -s "$(which sed)" "$TEST_ROOT/path"
ln -s "$(which rm)" "$TEST_ROOT/path"
ln -s "$(which tr)" "$TEST_ROOT/path"
ln -s "$(which uname)" "$TEST_ROOT/path"
ln -s "$(which test)" "$TEST_ROOT/path"
ln -s "$(which pwd)" "$TEST_ROOT/path"
ln -s "$(which hostname)" "$TEST_ROOT/path"
ln -s "$ROOT/tests/test_shells/bgscript.sh" "$TEST_ROOT/path"
ln -s "$ROOT/tests/test_shells/waitpid.sh" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-config" "$TEST_ROOT/path"
ln -s "$ROOT/scripts/powerline-render" "$TEST_ROOT/path"
ln -s "$ROOT/client/powerline.py" "$TEST_ROOT/path"
if test -e "$ROOT/scripts/powerline" ; then
ln -s "$ROOT/scripts/powerline" "$TEST_ROOT/path"
elif test -e client/powerline ; then
ln -s "$ROOT/client/powerline" "$TEST_ROOT/path"
elif which powerline ; then
ln -s "$(which powerline)" "$TEST_ROOT/path"
else
echo "Executable powerline was not found"
exit 1
fi
if test "$(
file --mime-type --brief --dereference "$TEST_ROOT/path/powerline" \
| cut -d/ -f1)" = "application" ; then
HAS_C_CLIENT=1
fi
if which socat ; then
HAS_SOCAT=1
ln -s "$(which socat)" "$TEST_ROOT/path"
ln -s "$ROOT/client/powerline.sh" "$TEST_ROOT/path"
fi
# Test type: daemon, renderer, …
# Test client: python, shell, c, none
# Test binding: *sh, ipython, pdb, …
test_shell() {
local test_type="$1" ; shift
local test_client="$1" ; shift
local test_binding="$1" ; shift
if test "$test_client" = shell && test -z "$HAS_SOCAT" ; then
echo "Skipping test, socat not available"
return
fi
if test "$test_client" = c && test -z "$HAS_C_CLIENT" ; then
echo "Skipping test, C client not available"
return
fi
if which "$test_binding" ; then
ln -s "$(which "$test_binding")" "$TEST_ROOT/path"
fi
if ! "${PYTHON}" "$ROOT/tests/test_in_vterm/test_shells.py" \
--type=$test_type \
--client=$test_client \
--binding=$test_binding \
-- "$@"
then
local test_name="$test_type-$test_client-$test_binding"
fail "$test_name" F "Failed vterm shell test"
fi
}
test_shell renderer python dash -i || true
vterm_shutdown
exit_suite

View File

@ -17,6 +17,7 @@ from powerline import get_fallback_logger
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions, from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env) do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT']) TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
@ -229,16 +230,18 @@ def main(attempts=3):
'new-window', 'bash --norc --noprofile -i', ';', 'new-window', 'bash --norc --noprofile -i', ';',
] ]
return do_terminal_tests( with PowerlineTestSuite('tmux') as suite:
tests=tests, return do_terminal_tests(
cmd=tmux_exe, tests=tests,
dim=dim, cmd=tmux_exe,
args=args, dim=dim,
env=env, args=args,
cwd=TEST_ROOT, env=env,
fin_cb=tmux_fin_cb, cwd=TEST_ROOT,
last_attempt_cb=print_tmux_logs, fin_cb=tmux_fin_cb,
) last_attempt_cb=print_tmux_logs,
suite=suite,
)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,8 +1,8 @@
#!/bin/sh #!/bin/bash
. tests/shlib/common.sh . tests/shlib/common.sh
. tests/shlib/vterm.sh . tests/shlib/vterm.sh
enter_suite tmux enter_suite tmux final
vterm_setup vterm_setup

View File

@ -14,6 +14,7 @@ from powerline.lib.dict import updated
from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions, from tests.modules.lib.terminal import (ExpectProcess, MutableDimensions,
do_terminal_tests, get_env) do_terminal_tests, get_env)
from tests.modules import PowerlineTestSuite
TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT']) TEST_ROOT = os.path.abspath(os.environ['TEST_ROOT'])
@ -53,14 +54,16 @@ def main(attempts=3):
tests = ( tests = (
) )
return do_terminal_tests( with PowerlineTestSuite('vim') as suite:
tests=tests, return do_terminal_tests(
cmd=vim_exe, tests=tests,
dim=dim, cmd=vim_exe,
args=args, dim=dim,
env=env, args=args,
cwd=TEST_ROOT, env=env,
) cwd=TEST_ROOT,
suite=suite,
)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -3,7 +3,7 @@
. tests/shlib/vterm.sh . tests/shlib/vterm.sh
. tests/shlib/vim.sh . tests/shlib/vim.sh
enter_suite vvim enter_suite vvim final
vterm_setup vterm_setup
@ -18,7 +18,7 @@ test_vim() {
ln -sf "$(which "${POWERLINE_VIM_EXE}")" "$TEST_ROOT/path/vim" ln -sf "$(which "${POWERLINE_VIM_EXE}")" "$TEST_ROOT/path/vim"
f="$ROOT/tests/test_in_vterm/test_vim.py" f="$ROOT/tests/test_in_vterm/test_vim.py"
if ! "${PYTHON}" "$f" ; then if ! "${PYTHON}" "$f" ; then
local test_name="$(LANG=C "$POWERLINE_VIM_EXE" --cmd 'echo version' --cmd qa 2>&1)" local test_name="$(LANG=C "$POWERLINE_VIM_EXE" --cmd 'echo version' --cmd qa 2>&1 | tail -n2)"
fail "$test_name" F "Failed vterm test $f" fail "$test_name" F "Failed vterm test $f"
fi fi
} }

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
. tests/shlib/common.sh . tests/shlib/common.sh
enter_suite lint enter_suite lint final
if ! "$PYTHON" "$ROOT/scripts/powerline-lint" -p "$ROOT/powerline/config_files" ; then if ! "$PYTHON" "$ROOT/scripts/powerline-lint" -p "$ROOT/powerline/config_files" ; then
fail "test" F "Running powerline-lint failed" fail "test" F "Running powerline-lint failed"

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
. tests/shlib/common.sh . tests/shlib/common.sh
enter_suite python enter_suite python final
for file in "$ROOT"/tests/test_python/test_*.py ; do for file in "$ROOT"/tests/test_python/test_*.py ; do
test_name="${file##*/test_}" test_name="${file##*/test_}"

View File

@ -6,6 +6,7 @@ import os
import sys import sys
import re import re
import shutil import shutil
import unicodedata
from time import sleep from time import sleep
from subprocess import call, PIPE from subprocess import call, PIPE
@ -497,22 +498,14 @@ class TestUnicode(TestCase):
if sys.maxunicode < 0x10FFFF: if sys.maxunicode < 0x10FFFF:
raise SkipTest('Can only test strwidth_ucs_4 in UCS-4 Pythons') raise SkipTest('Can only test strwidth_ucs_4 in UCS-4 Pythons')
def east_asian_width(ch): self.assertEqual(1, plu.strwidth_ucs_4(width_data, '\U0001F063'))
assert (len(ch) == 1)
assert ord(ch) == 0x1F48E
return 'F'
with replace_attr(plu, 'east_asian_width', east_asian_width):
# Warning: travis unicodedata.east_asian_width for some reason
# thinks this character is 5 symbols wide.
self.assertEqual(2, plu.strwidth_ucs_4(width_data, '\U0001F48E'))
def test_strwidth_ucs_2(self): def test_strwidth_ucs_2(self):
self.assertEqual(4, plu.strwidth_ucs_2(width_data, 'abcd')) self.assertEqual(4, plu.strwidth_ucs_2(width_data, 'abcd'))
self.assertEqual(4, plu.strwidth_ucs_2(width_data, '')) self.assertEqual(4, plu.strwidth_ucs_2(width_data, ''))
if not sys.maxunicode < 0x10FFFF: if not sys.maxunicode < 0x10FFFF:
raise SkipTest('Can only test strwidth_ucs_2 in UCS-2 Pythons') raise SkipTest('Can only test strwidth_ucs_2 in UCS-2 Pythons')
self.assertEqual(2, plu.strwidth_ucs_2(width_data, '\ud83d\udc8e')) self.assertEqual(1, plu.strwidth_ucs_2(width_data, '\ud83c\udc30'))
class TestVCS(TestCase): class TestVCS(TestCase):

View File

@ -527,6 +527,11 @@ class TestEnv(TestCommon):
if hasattr(self.module, 'psutil') and not callable(self.module.psutil.Process.username): if hasattr(self.module, 'psutil') and not callable(self.module.psutil.Process.username):
username = property(username) username = property(username)
segment_info = {'environ': {}}
def user(*args, **kwargs):
return self.module.user(pl=pl, segment_info=segment_info, *args, **kwargs)
struct_passwd = namedtuple('struct_passwd', ('pw_name',)) struct_passwd = namedtuple('struct_passwd', ('pw_name',))
new_psutil = new_module('psutil', Process=Process) new_psutil = new_module('psutil', Process=Process)
new_pwd = new_module('pwd', getpwuid=lambda uid: struct_passwd(pw_name='def@DOMAIN.COM')) new_pwd = new_module('pwd', getpwuid=lambda uid: struct_passwd(pw_name='def@DOMAIN.COM'))
@ -537,21 +542,21 @@ class TestEnv(TestCommon):
with replace_attr(self.module, 'os', new_os): with replace_attr(self.module, 'os', new_os):
with replace_attr(self.module, 'psutil', new_psutil): with replace_attr(self.module, 'psutil', new_psutil):
with replace_attr(self.module, '_geteuid', lambda: 5): with replace_attr(self.module, '_geteuid', lambda: 5):
self.assertEqual(self.module.user(pl=pl), [ self.assertEqual(user(), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']} {'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
]) ])
self.assertEqual(self.module.user(pl=pl, hide_user='abc'), [ self.assertEqual(user(hide_user='abc'), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']} {'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
]) ])
self.assertEqual(self.module.user(pl=pl, hide_domain=False), [ self.assertEqual(user(hide_domain=False), [
{'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']} {'contents': 'def@DOMAIN.COM', 'highlight_groups': ['user']}
]) ])
self.assertEqual(self.module.user(pl=pl, hide_user='def@DOMAIN.COM'), None) self.assertEqual(user(hide_user='def@DOMAIN.COM'), None)
self.assertEqual(self.module.user(pl=pl, hide_domain=True), [ self.assertEqual(user(hide_domain=True), [
{'contents': 'def', 'highlight_groups': ['user']} {'contents': 'def', 'highlight_groups': ['user']}
]) ])
with replace_attr(self.module, '_geteuid', lambda: 0): with replace_attr(self.module, '_geteuid', lambda: 0):
self.assertEqual(self.module.user(pl=pl), [ self.assertEqual(user(), [
{'contents': 'def', 'highlight_groups': ['superuser', 'user']} {'contents': 'def', 'highlight_groups': ['superuser', 'user']}
]) ])

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
. tests/shlib/common.sh . tests/shlib/common.sh
enter_suite shell enter_suite shell final
if test $# -eq 0 ; then if test $# -eq 0 ; then
FAST=1 FAST=1
@ -453,7 +453,7 @@ if test -z "${ONLY_SHELL}" || test "${ONLY_SHELL}" = "pdb" ; then
if ! run_test subclass python $PDB_PYTHON \ if ! run_test subclass python $PDB_PYTHON \
"$ROOT/tests/test_shells/pdb-main.py" "$ROOT/tests/test_shells/pdb-main.py"
then then
fail "pdb-subclass:test" F \ fail --allow-failure "pdb-subclass:test" F \
"Failed checking $PDB_PYTHON $ROOT/tests/test_shells/pdb-main.py" "Failed checking $PDB_PYTHON $ROOT/tests/test_shells/pdb-main.py"
fi fi
fi fi
@ -466,7 +466,7 @@ if test -z "${ONLY_SHELL}" || test "${ONLY_SHELL}" = "pdb" ; then
if ! run_test module python "$PDB_PYTHON" -m"$MODULE" \ if ! run_test module python "$PDB_PYTHON" -m"$MODULE" \
"$ROOT/tests/test_shells/pdb-script.py" "$ROOT/tests/test_shells/pdb-script.py"
then then
fail "pdb-module:test" F \ fail --allow-failure "pdb-module:test" F \
"Failed checking $PDB_PYTHON -m$MODULE $ROOT/tests/test_shells/pdb-script" "Failed checking $PDB_PYTHON -m$MODULE $ROOT/tests/test_shells/pdb-script"
fi fi
fi fi

View File

@ -3,7 +3,7 @@
. tests/shlib/vterm.sh . tests/shlib/vterm.sh
. tests/shlib/vim.sh . tests/shlib/vim.sh
enter_suite vim enter_suite vim final
vterm_setup vim vterm_setup vim
@ -15,6 +15,7 @@ export POWERLINE_THEME_OVERRIDES='default.segments.left=[]'
test_script() { test_script() {
local vim="$1" ; shift local vim="$1" ; shift
local script="$1" ; shift local script="$1" ; shift
local allow_failure_arg="$1" ; shift
echo "Running script $script with $vim" echo "Running script $script with $vim"
if ! test -e "$vim" ; then if ! test -e "$vim" ; then
return 0 return 0
@ -23,7 +24,8 @@ test_script() {
|| test -f message.fail || test -f message.fail
then then
local test_name="${script##*/}" local test_name="${script##*/}"
fail "${test_name%.vim}" F "Failed script $script run with $vim" fail $allow_failure_arg "${test_name%.vim}" \
F "Failed script $script run with $vim"
if test -e message.fail ; then if test -e message.fail ; then
cat message.fail >&2 cat message.fail >&2
rm message.fail rm message.fail
@ -37,13 +39,19 @@ cd "$TEST_ROOT"
for script in "$TEST_SCRIPT_ROOT"/*.vim ; do for script in "$TEST_SCRIPT_ROOT"/*.vim ; do
if test "${script%.old.vim}" = "${script}" ; then if test "${script%.old.vim}" = "${script}" ; then
test_script "$NEW_VIM" "$script" test_script "$NEW_VIM" "$script" ""
fi fi
done done
if test "$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR" = "2.7" ; then
ALLOW_FAILURE_ARG=--allow-failure
else
ALLOW_FAILURE_ARG=
fi
if test -e "$OLD_VIM" ; then if test -e "$OLD_VIM" ; then
for script in "$TEST_SCRIPT_ROOT"/*.old.vim ; do for script in "$TEST_SCRIPT_ROOT"/*.old.vim ; do
test_script "$OLD_VIM" "$script" test_script "$OLD_VIM" "$script" "$ALLOW_FAILURE_ARG"
done done
fi fi