-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trying to switch to pytest #165
base: master
Are you sure you want to change the base?
Conversation
First, thanks for the patch! I agree this is a change worth doing, though obviously I’m not spending time on blessings these days. Fortunately, the tty doesn’t change much. ;-) I wonder if pytest is calling decode to complain about an assertion failure (by printing something odd, like one of blessings’ str subclasses). Does that shake anything loose? |
@erikrose these are the full tests with tracebacks, the last one is clearly some sort of issue with the results produced by the software 🤔 the others seem to be none-type objects on which decode is being called. Not sure whether this is something pytest introduces. Or maybe pytest somehow interferes with something meaningful being generated, thus leading to the issue of
|
I unfortuantely don't have time to chase this right now, but thanks for what you've done so far. If you do get it working, I imagine it would be an easy merge. |
@@ -117,7 +115,7 @@ def test_zero_location(): | |||
t = TestTerminal(stream=StringIO(), force_styling=True) | |||
with t.location(0, 0): | |||
pass | |||
eq_(t.stream.getvalue(), unicode_cap('sc') + | |||
assert t.stream.getvalue() == unicode_cap('sc' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original line contained unicode_cap('sc') +
whilst your change brings unicode_cap('sc' +
. I wonder if this is the root cause of the test fail.
The fork https://github.com/jquast/blessed uses pytest and provides 95% test coverage and windows support if you need a reference |
Just tested this PR and looks like by default pytest is not able to find any units because it scans only tests_*.py files. After pass pytest fails with+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-blessings-1.7-24.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-blessings-1.7-24.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network' blessings/__init__.py blessings/tests.py
============================= test session starts ==============================
platform linux -- Python 3.8.18, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/tkloczko/rpmbuild/BUILD/blessings-1.7
collected 46 items
blessings/tests.py F..FF.FFFF.F...FF...F..F..FF.FFFF.F...FF...F..
=================================== FAILURES ===================================
_______________________________ test_capability ________________________________
def test_capability():
"""Check that a capability lookup works.
Also test that Terminal grabs a reasonable default stream. This test
assumes it will be run from a tty.
"""
t = TestTerminal()
> sc = unicode_cap('sc')
blessings/tests.py:44:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E _curses.error: must call (at least) setupterm() first
blessings/tests.py:28: error
_____________________________ test_parametrization _____________________________
def test_parametrization():
"""Test parametrizing a capability."""
> assert TestTerminal().cup(3, 4), unicode_parm('cup', 3 == 4)
E AssertionError: ESC[1;1H
E assert ''
E + where '' = ''(3, 4)
E + where '' = <blessings.Terminal object at 0x7f261850c9a0>.cup
E + where <blessings.Terminal object at 0x7f261850c9a0> = TestTerminal()
blessings/tests.py:65: AssertionError
____________________________ test_height_and_width _____________________________
def test_height_and_width():
"""Assert that ``height_and_width()`` returns ints."""
t = TestTerminal() # kind shouldn't matter.
> assert isinstance(t.height, int)
E assert False
E + where False = isinstance(None, int)
E + where None = <blessings.Terminal object at 0x7f2618593e50>.height
blessings/tests.py:71: AssertionError
________________________________ test_location _________________________________
def test_location():
"""Make sure ``location()`` does what it claims."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(3, 4):
t.stream.write(u'hi')
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('cup', 4, 3) +
u'hi' +
unicode_cap('rc'))
blessings/tests.py:88:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[5;4Hhi\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
___________________________ test_horizontal_location ___________________________
def test_horizontal_location():
"""Make sure we can move the cursor horizontally without changing rows."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(x=5):
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('hpa', 5) +
unicode_cap('rc'))
blessings/tests.py:99:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[6G\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
______________________________ test_null_location ______________________________
def test_null_location():
"""Make sure ``location()`` with no args just does position restoration."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location():
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_cap('rc'))
blessings/tests.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
______________________________ test_zero_location ______________________________
def test_zero_location():
"""Make sure ``location()`` pays attention to 0-valued args."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(0, 0):
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('cup', 0, 0) +
unicode_cap('rc'))
blessings/tests.py:118:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[1;1H\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
_____________________________ test_mnemonic_colors _____________________________
def test_mnemonic_colors():
"""Make sure color shortcuts work."""
def color(num):
return unicode_parm('setaf', num)
def on_color(num):
return unicode_parm('setab', num)
# Avoid testing red, blue, yellow, and cyan, since they might someday
# change depending on terminal type.
t = TestTerminal()
> assert t.white == color(7)
E AssertionError: assert '' == '\x1b[37m'
E - ESC[37m
blessings/tests.py:146: AssertionError
______________________ test_number_of_colors_without_tty _______________________
def test_number_of_colors_without_tty():
"""``number_of_colors`` should return 0 when there's no tty."""
# Hypothesis: once setupterm() has run and decided the tty supports 256
# colors, it never changes its mind.
t = TestTerminal(stream=StringIO())
assert t.number_of_colors == 0
t = TestTerminal(stream=StringIO(), force_styling=True)
> assert t.number_of_colors == 0
E assert 256 == 0
E + where 256 = <blessings.Terminal object at 0x7f2618199af0>.number_of_colors
blessings/tests.py:186: AssertionError
________________________ test_number_of_colors_with_tty ________________________
def test_number_of_colors_with_tty():
"""``number_of_colors`` should work."""
t = TestTerminal()
> assert t.number_of_colors == 256
E assert 0 == 256
E + where 0 = <blessings.Terminal object at 0x7f2618197a90>.number_of_colors
blessings/tests.py:192: AssertionError
_____________________ test_init_descriptor_always_initted ______________________
def test_init_descriptor_always_initted():
"""We should be able to get a height and width even on no-tty Terminals."""
t = Terminal(stream=StringIO())
> assert type(t.height) == int
E AssertionError: assert <class 'NoneType'> == int
E + where <class 'NoneType'> = type(None)
E + where None = <blessings.Terminal object at 0x7f26181da0a0>.height
blessings/tests.py:253: AssertionError
_______________________________ test_capability ________________________________
def test_capability():
"""Check that a capability lookup works.
Also test that Terminal grabs a reasonable default stream. This test
assumes it will be run from a tty.
"""
t = TestTerminal()
sc = unicode_cap('sc')
> assert t.save == sc
E AssertionError: assert '' == '\x1b7'
E - ESC7
blessings/tests.py:45: AssertionError
_____________________________ test_parametrization _____________________________
def test_parametrization():
"""Test parametrizing a capability."""
> assert TestTerminal().cup(3, 4), unicode_parm('cup', 3 == 4)
E AssertionError: ESC[1;1H
E assert ''
E + where '' = ''(3, 4)
E + where '' = <blessings.Terminal object at 0x7f26181a0580>.cup
E + where <blessings.Terminal object at 0x7f26181a0580> = TestTerminal()
blessings/tests.py:65: AssertionError
____________________________ test_height_and_width _____________________________
def test_height_and_width():
"""Assert that ``height_and_width()`` returns ints."""
t = TestTerminal() # kind shouldn't matter.
> assert isinstance(t.height, int)
E assert False
E + where False = isinstance(None, int)
E + where None = <blessings.Terminal object at 0x7f26181a72b0>.height
blessings/tests.py:71: AssertionError
________________________________ test_location _________________________________
def test_location():
"""Make sure ``location()`` does what it claims."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(3, 4):
t.stream.write(u'hi')
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('cup', 4, 3) +
u'hi' +
unicode_cap('rc'))
blessings/tests.py:88:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[5;4Hhi\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
___________________________ test_horizontal_location ___________________________
def test_horizontal_location():
"""Make sure we can move the cursor horizontally without changing rows."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(x=5):
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('hpa', 5) +
unicode_cap('rc'))
blessings/tests.py:99:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[6G\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
______________________________ test_null_location ______________________________
def test_null_location():
"""Make sure ``location()`` with no args just does position restoration."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location():
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_cap('rc'))
blessings/tests.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
______________________________ test_zero_location ______________________________
def test_zero_location():
"""Make sure ``location()`` pays attention to 0-valued args."""
t = TestTerminal(stream=StringIO(), force_styling=True)
with t.location(0, 0):
pass
> assert t.stream.getvalue() == unicode_cap('sc' +
unicode_parm('cup', 0, 0) +
unicode_cap('rc'))
blessings/tests.py:118:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cap = 'sc\x1b[1;1H\x1b8'
def unicode_cap(cap):
"""Return the result of ``tigetstr`` except as Unicode."""
> return tigetstr(cap).decode('latin1')
E AttributeError: 'NoneType' object has no attribute 'decode'
blessings/tests.py:28: AttributeError
_____________________________ test_mnemonic_colors _____________________________
def test_mnemonic_colors():
"""Make sure color shortcuts work."""
def color(num):
return unicode_parm('setaf', num)
def on_color(num):
return unicode_parm('setab', num)
# Avoid testing red, blue, yellow, and cyan, since they might someday
# change depending on terminal type.
t = TestTerminal()
> assert t.white == color(7)
E AssertionError: assert '' == '\x1b[37m'
E - ESC[37m
blessings/tests.py:146: AssertionError
______________________ test_number_of_colors_without_tty _______________________
def test_number_of_colors_without_tty():
"""``number_of_colors`` should return 0 when there's no tty."""
# Hypothesis: once setupterm() has run and decided the tty supports 256
# colors, it never changes its mind.
t = TestTerminal(stream=StringIO())
assert t.number_of_colors == 0
t = TestTerminal(stream=StringIO(), force_styling=True)
> assert t.number_of_colors == 0
E assert 256 == 0
E + where 256 = <blessings.Terminal object at 0x7f26181e9f70>.number_of_colors
blessings/tests.py:186: AssertionError
________________________ test_number_of_colors_with_tty ________________________
def test_number_of_colors_with_tty():
"""``number_of_colors`` should work."""
t = TestTerminal()
> assert t.number_of_colors == 256
E assert 0 == 256
E + where 0 = <blessings.Terminal object at 0x7f26183c4c40>.number_of_colors
blessings/tests.py:192: AssertionError
_____________________ test_init_descriptor_always_initted ______________________
def test_init_descriptor_always_initted():
"""We should be able to get a height and width even on no-tty Terminals."""
t = Terminal(stream=StringIO())
> assert type(t.height) == int
E AssertionError: assert <class 'NoneType'> == int
E + where <class 'NoneType'> = type(None)
E + where None = <blessings.Terminal object at 0x7f26181da2e0>.height
blessings/tests.py:253: AssertionError
=========================== short test summary info ============================
FAILED blessings/tests.py::test_capability - _curses.error: must call (at lea...
FAILED blessings/tests.py::test_parametrization - AssertionError: ESC[1;1H
FAILED blessings/tests.py::test_height_and_width - assert False
FAILED blessings/tests.py::test_location - AttributeError: 'NoneType' object ...
FAILED blessings/tests.py::test_horizontal_location - AttributeError: 'NoneTy...
FAILED blessings/tests.py::test_null_location - AttributeError: 'NoneType' ob...
FAILED blessings/tests.py::test_zero_location - AttributeError: 'NoneType' ob...
FAILED blessings/tests.py::test_mnemonic_colors - AssertionError: assert '' =...
FAILED blessings/tests.py::test_number_of_colors_without_tty - assert 256 == 0
FAILED blessings/tests.py::test_number_of_colors_with_tty - assert 0 == 256
FAILED blessings/tests.py::test_init_descriptor_always_initted - AssertionErr...
FAILED blessings/tests.py::test_capability - AssertionError: assert '' == '\x...
FAILED blessings/tests.py::test_parametrization - AssertionError: ESC[1;1H
FAILED blessings/tests.py::test_height_and_width - assert False
FAILED blessings/tests.py::test_location - AttributeError: 'NoneType' object ...
FAILED blessings/tests.py::test_horizontal_location - AttributeError: 'NoneTy...
FAILED blessings/tests.py::test_null_location - AttributeError: 'NoneType' ob...
FAILED blessings/tests.py::test_zero_location - AttributeError: 'NoneType' ob...
FAILED blessings/tests.py::test_mnemonic_colors - AssertionError: assert '' =...
FAILED blessings/tests.py::test_number_of_colors_without_tty - assert 256 == 0
FAILED blessings/tests.py::test_number_of_colors_with_tty - assert 0 == 256
FAILED blessings/tests.py::test_init_descriptor_always_initted - AssertionErr...
======================== 22 failed, 24 passed in 0.29s ========================= BTW looks like test suite emits some terminal sequences which are messing with output. |
This is because once a terminal is initialized with any kind of TERM, all future instances match this same terminal, and executed via tox, TERM is unset. More is written about it here, So, to be able to test multiple kinds of terminals with pytest, I created an This allows many multiple "kind" (TERM value) of terminals to be tested, and is used in every test case that calls |
Gentle ping .. any update? 🤔 |
These tests fail, what are you wanting to bump for? If you wanted help fixing them, I communicated the resolution, and implemented it in the "blessed" fork, which is API compatible with blessings, maintained, and uses pytest with the |
Help welcome, 5 tests still fail: