Skip to content

#3374 If path name is very long then pytest will split name for several lines #3383

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

Closed
wants to merge 6 commits into from
Closed

#3374 If path name is very long then pytest will split name for several lines #3383

wants to merge 6 commits into from

Conversation

feuillemorte
Copy link
Contributor

Fixes #3374

Long names:

selection_023

Long name full line:
selection_025

Long name full line + 1 letter:
selection_026

Very beautiful when progress prints in every line but it is a problem with progress count: it counts only after run a test (after report write a dot), so, there is a problem:
selection_024

@feuillemorte feuillemorte added topic: reporting related to terminal output and user-facing messages and errors type: enhancement new feature or API change, should be merged into features branch labels Apr 10, 2018
@coveralls
Copy link

coveralls commented Apr 10, 2018

Coverage Status

Coverage increased (+0.03%) to 92.766% when pulling b9ebffb on feuillemorte:3374-long-filenames into 372bcdb on pytest-dev:features.

@nicoddemus
Copy link
Member

Thanks @feuillemorte for the PR!

Personally I prefer to just write the full path name and let the terminal wrap that around for us if needed, otherwise this makes it hard to copy/paste the test name which is useful on occasion:

tests/test_very_long_name_test_very_long_name_test_very_long_name_test_very_long_nam
e_test_very_long_name.py ..                                                   [ 50%]

If we write to the edge of the screen in a way that if we would mess with the alignment of the progress indicator, we should start a new line instead. Using the example from #3374:

tests\test_general\test_find_last_operator\test_correct_expressions.py . [ 77%]
.......                                                                  [ 93%]
tests\test_general\test_find_last_operator\test_incorrect_expressions.py 
.                                                                        [ 95%]
tests\test_general\test_find_last_operator\test_monomials.py ..          [100%]

What do others think?

cc @InDevRus

@feuillemorte
Copy link
Contributor Author

@nicoddemus
I fixed your comment and now it looks more convenient. Also I deleted test because I don't know how to set terminal width. If you can give me advice how to write a test, please, do it.

Look at the pictures how it works now:

Long names:
selection_035

Long name full line:
selection_036

Long name full line + 1 symbol:
selection_037

But I found a little problem here:
selection_038

I have 99% at 2 lines and 0% at the beginning. Is it a bug?

@feuillemorte
Copy link
Contributor Author

Fixed some bug:

before:
selection_039

after:
image
selection_040

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @feuillemorte and sorry for the delay.

Besides my comments, please add a test as well.

@@ -216,6 +217,11 @@ def write_fspath_result(self, nodeid, res):
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
width = self._tw.fullwidth - self._tw.chars_on_current_line
if 0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 10? I suggest using a variable with a descriptive name instead. The same can be done for the entire conditional, for example:

something_descriptive =  0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10

Also can you explain this logic here?

Copy link
Contributor Author

@feuillemorte feuillemorte Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 symbols because of this line:
.py [ 80%]
this is magic 10 symbols :)
Also all magic symbols was got by testing in terminal

logic:
if you have long name and remaining widht less then 10 symbols, then add new line.
OR
if you have long name (3 lines) and width of tail of this name more then screen width - 10 symbols, then also add new line

How I can write test on it? Does it have a value like
tempdir.runtests(--screen-width=120)
?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 symbols because of this line:
.py [ 80%]
this is magic 10 symbols :)

Ahh I see, thanks. In those cases it is usually better to put this in a descriptive constant:

_PROGRESS_LENGTH = len(' [100%]')
_MAX_LEN_LEFT = len('.py [ 80%]')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic:
if you have long name and remaining widht less then 10 symbols, then add new line.
OR
if you have long name (3 lines) and width of tail of this name more then screen width - 10 symbols, then also add new line

Could you please separate each condition in their own variable with descriptive name? A descriptive variable name often is enough to explain a complex situation and avoid having to write comments or explain it to people.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How I can write test on it? Does it have a value like
tempdir.runtests(--screen-width=120)
?

I don't think so, but I believe testdir uses a hard coded value internally. You can try to match against the entire line instead of using glob wildcards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe testdir uses a hard coded value internally.

I tried to run my test and it failed because this value was changed and my test with long name on 3 lines become to test with 1 line. So that's why I deleted it.

Also, could you please some test on your terminal after my fix and before merging? I'm some afraid of my magic constants :) It looks nice in my terminals (I tried 2 terminals), but who knows how it will not on my machine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @feuillemorte, did you push more commits? I don't see them here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicoddemus I fixed your comments, but I can't push because I can't to write a test. I try to get an object of terminal and get screen width. It says me 80 symbols, but actually it's wrong value inside runpytest() function (159 symbols):
(sorry, I can't paste image because some amazon ip's blocked in Russia, please, look url)

test_01_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_l="""
                import pytest
                from _pytest.terminal import TerminalReporter
                term = TerminalReporter(pytest.config)
                assert term._screen_width == 1
                
                @pytest.mark.parametrize('i', range(10))
                def test_bar(i): assert 1
            """,
test_01_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_long_name_very_l.py:4: in <module>
    assert term._screen_width == 1
E   assert 80 == 1

output:
https://pp.userapi.com/c824503/v824503903/11fc2b/8XBN-QcJDh0.jpg

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicoddemus I pushed some code but without tests

@@ -355,7 +361,10 @@ def pytest_runtest_logfinish(self, nodeid):
self._write_progress_information_filling_space()
else:
past_edge = self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
if past_edge:
width = self._tw.chars_on_current_line % self._screen_width + 9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again a magic constant, please use a named constant instead. 😁

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see 9 should be _MAX_LEN_LEFT - 1 if we add a constant for it, is that right?

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@feuillemorte thanks again for following up! This is shaping up nicely, I just think we should work a bit on improving the code.

Sorry if I seem picky, but the readability in this kind of code (which seems simple but is kind of tricky) is very important for future maintenance.

Thanks for your patience! 👍

@@ -216,6 +217,11 @@ def write_fspath_result(self, nodeid, res):
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
width = self._tw.fullwidth - self._tw.chars_on_current_line
if 0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 symbols because of this line:
.py [ 80%]
this is magic 10 symbols :)

Ahh I see, thanks. In those cases it is usually better to put this in a descriptive constant:

_PROGRESS_LENGTH = len(' [100%]')
_MAX_LEN_LEFT = len('.py [ 80%]')

@@ -216,6 +217,11 @@ def write_fspath_result(self, nodeid, res):
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
width = self._tw.fullwidth - self._tw.chars_on_current_line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

width is misleading, I suggest width_remaining

if 0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10:
self._tw.line()
elif width < 0:
self.is_fspath_extra_width = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest _is_fspath_past_edge (if I understand the code correctly)

@@ -216,6 +217,11 @@ def write_fspath_result(self, nodeid, res):
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
width = self._tw.fullwidth - self._tw.chars_on_current_line
if 0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic:
if you have long name and remaining widht less then 10 symbols, then add new line.
OR
if you have long name (3 lines) and width of tail of this name more then screen width - 10 symbols, then also add new line

Could you please separate each condition in their own variable with descriptive name? A descriptive variable name often is enough to explain a complex situation and avoid having to write comments or explain it to people.

@@ -355,7 +361,10 @@ def pytest_runtest_logfinish(self, nodeid):
self._write_progress_information_filling_space()
else:
past_edge = self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
if past_edge:
width = self._tw.chars_on_current_line % self._screen_width + 9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see 9 should be _MAX_LEN_LEFT - 1 if we add a constant for it, is that right?

@@ -216,6 +217,11 @@ def write_fspath_result(self, nodeid, res):
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
width = self._tw.fullwidth - self._tw.chars_on_current_line
if 0 < width < 10 or self._tw.chars_on_current_line % self._screen_width > self._screen_width - 10:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How I can write test on it? Does it have a value like
tempdir.runtests(--screen-width=120)
?

I don't think so, but I believe testdir uses a hard coded value internally. You can try to match against the entire line instead of using glob wildcards.

@nicoddemus
Copy link
Member

@feuillemorte thanks a lot for the follow up! 👍

I've tried your branch on Windows and the results are not very good unfortunately.

Here's two screenshots using the code from your branch, one for the native command prompt and another for Cmder (which is another command prompt and the one I use daily):

native cmd (feuillemorte:3374-long-filenames)

cmd1

Cmder (feuillemorte:3374-long-filenames)

cmder1

Now screenshots using the master branch:

native cmd (master)

cmd2

Cmder (master)

cmder2

I'm not sure this is something specific to Windows though. @RonnyPfannschmidt can you please try this in your system as well and see how it looks?

@nicoddemus
Copy link
Member

Hi @feuillemorte,

It has been a long time since it has last seen activity, plus we have made sweeping changes on master to drop Python 2.7 and 3.4 support, so this PR has some conflicts which require attention.

In order to clear up our queue and let us focus on the active PRs, I'm closing this PR for now.

Please don't consider this a rejection of your PR, we just want to get this out of sight until you have the time to tackle this again. If you get around to work on this in the future, please don't hesitate in re-opening this!

Thanks for your work, the team definitely appreciates it!

@nicoddemus nicoddemus closed this Jun 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: reporting related to terminal output and user-facing messages and errors type: enhancement new feature or API change, should be merged into features branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants