|
6 | 6 | import py |
7 | 7 | import pytest |
8 | 8 | from _pytest.assertion import util |
| 9 | +from _pytest.assertion import truncate |
9 | 10 |
|
10 | 11 | PY3 = sys.version_info >= (3, 0) |
11 | 12 |
|
@@ -572,6 +573,111 @@ def test_fmt_multi_newline_before_where(self): |
572 | 573 | assert util.format_explanation(expl) == res |
573 | 574 |
|
574 | 575 |
|
| 576 | +class TestTruncateExplanation: |
| 577 | + |
| 578 | + """ Confirm assertion output is truncated as expected """ |
| 579 | + |
| 580 | + # The number of lines in the truncation explanation message. Used |
| 581 | + # to calculate that results have the expected length. |
| 582 | + LINES_IN_TRUNCATION_MSG = 2 |
| 583 | + |
| 584 | + def test_doesnt_truncate_when_input_is_empty_list(self): |
| 585 | + expl = [] |
| 586 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=100) |
| 587 | + assert result == expl |
| 588 | + |
| 589 | + def test_doesnt_truncate_at_when_input_is_5_lines_and_LT_max_chars(self): |
| 590 | + expl = ['a' * 100 for x in range(5)] |
| 591 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=8*80) |
| 592 | + assert result == expl |
| 593 | + |
| 594 | + def test_truncates_at_8_lines_when_given_list_of_empty_strings(self): |
| 595 | + expl = ['' for x in range(50)] |
| 596 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=100) |
| 597 | + assert result != expl |
| 598 | + assert len(result) == 8 + self.LINES_IN_TRUNCATION_MSG |
| 599 | + assert "Full output truncated" in result[-1] |
| 600 | + assert "43 lines hidden" in result[-1] |
| 601 | + last_line_before_trunc_msg = result[- self.LINES_IN_TRUNCATION_MSG -1] |
| 602 | + assert last_line_before_trunc_msg.endswith("...") |
| 603 | + |
| 604 | + def test_truncates_at_8_lines_when_first_8_lines_are_LT_max_chars(self): |
| 605 | + expl = ['a' for x in range(100)] |
| 606 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=8*80) |
| 607 | + assert result != expl |
| 608 | + assert len(result) == 8 + self.LINES_IN_TRUNCATION_MSG |
| 609 | + assert "Full output truncated" in result[-1] |
| 610 | + assert "93 lines hidden" in result[-1] |
| 611 | + last_line_before_trunc_msg = result[- self.LINES_IN_TRUNCATION_MSG -1] |
| 612 | + assert last_line_before_trunc_msg.endswith("...") |
| 613 | + |
| 614 | + def test_truncates_at_8_lines_when_first_8_lines_are_EQ_max_chars(self): |
| 615 | + expl = ['a' * 80 for x in range(16)] |
| 616 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=8*80) |
| 617 | + assert result != expl |
| 618 | + assert len(result) == 8 + self.LINES_IN_TRUNCATION_MSG |
| 619 | + assert "Full output truncated" in result[-1] |
| 620 | + assert "9 lines hidden" in result[-1] |
| 621 | + last_line_before_trunc_msg = result[- self.LINES_IN_TRUNCATION_MSG -1] |
| 622 | + assert last_line_before_trunc_msg.endswith("...") |
| 623 | + |
| 624 | + def test_truncates_at_4_lines_when_first_4_lines_are_GT_max_chars(self): |
| 625 | + expl = ['a' * 250 for x in range(10)] |
| 626 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=999) |
| 627 | + assert result != expl |
| 628 | + assert len(result) == 4 + self.LINES_IN_TRUNCATION_MSG |
| 629 | + assert "Full output truncated" in result[-1] |
| 630 | + assert "7 lines hidden" in result[-1] |
| 631 | + last_line_before_trunc_msg = result[- self.LINES_IN_TRUNCATION_MSG -1] |
| 632 | + assert last_line_before_trunc_msg.endswith("...") |
| 633 | + |
| 634 | + def test_truncates_at_1_line_when_first_line_is_GT_max_chars(self): |
| 635 | + expl = ['a' * 250 for x in range(1000)] |
| 636 | + result = truncate._truncate_explanation(expl, max_lines=8, max_chars=100) |
| 637 | + assert result != expl |
| 638 | + assert len(result) == 1 + self.LINES_IN_TRUNCATION_MSG |
| 639 | + assert "Full output truncated" in result[-1] |
| 640 | + assert "1000 lines hidden" in result[-1] |
| 641 | + last_line_before_trunc_msg = result[- self.LINES_IN_TRUNCATION_MSG -1] |
| 642 | + assert last_line_before_trunc_msg.endswith("...") |
| 643 | + |
| 644 | + def test_full_output_truncated(self, monkeypatch, testdir): |
| 645 | + """ Test against full runpytest() output. """ |
| 646 | + |
| 647 | + line_count = 7 |
| 648 | + line_len = 100 |
| 649 | + expected_truncated_lines = 2 |
| 650 | + testdir.makepyfile(r""" |
| 651 | + def test_many_lines(): |
| 652 | + a = list([str(i)[0] * %d for i in range(%d)]) |
| 653 | + b = a[::2] |
| 654 | + a = '\n'.join(map(str, a)) |
| 655 | + b = '\n'.join(map(str, b)) |
| 656 | + assert a == b |
| 657 | + """ % (line_len, line_count)) |
| 658 | + monkeypatch.delenv('CI', raising=False) |
| 659 | + |
| 660 | + result = testdir.runpytest() |
| 661 | + # without -vv, truncate the message showing a few diff lines only |
| 662 | + result.stdout.fnmatch_lines([ |
| 663 | + "*- 1*", |
| 664 | + "*- 3*", |
| 665 | + "*- 5*", |
| 666 | + "*truncated (%d lines hidden)*use*-vv*" % expected_truncated_lines, |
| 667 | + ]) |
| 668 | + |
| 669 | + result = testdir.runpytest('-vv') |
| 670 | + result.stdout.fnmatch_lines([ |
| 671 | + "*- %d*" % 5, |
| 672 | + ]) |
| 673 | + |
| 674 | + monkeypatch.setenv('CI', '1') |
| 675 | + result = testdir.runpytest() |
| 676 | + result.stdout.fnmatch_lines([ |
| 677 | + "*- %d*" % 5, |
| 678 | + ]) |
| 679 | + |
| 680 | + |
575 | 681 | def test_python25_compile_issue257(testdir): |
576 | 682 | testdir.makepyfile(""" |
577 | 683 | def test_rewritten(): |
@@ -631,40 +737,6 @@ def test_hello(): |
631 | 737 | ]) |
632 | 738 |
|
633 | 739 |
|
634 | | -def test_assert_compare_truncate_longmessage(monkeypatch, testdir): |
635 | | - testdir.makepyfile(r""" |
636 | | - def test_long(): |
637 | | - a = list(range(200)) |
638 | | - b = a[::2] |
639 | | - a = '\n'.join(map(str, a)) |
640 | | - b = '\n'.join(map(str, b)) |
641 | | - assert a == b |
642 | | - """) |
643 | | - monkeypatch.delenv('CI', raising=False) |
644 | | - |
645 | | - result = testdir.runpytest() |
646 | | - # without -vv, truncate the message showing a few diff lines only |
647 | | - result.stdout.fnmatch_lines([ |
648 | | - "*- 1", |
649 | | - "*- 3", |
650 | | - "*- 5", |
651 | | - "*- 7", |
652 | | - "*truncated (193 more lines)*use*-vv*", |
653 | | - ]) |
654 | | - |
655 | | - |
656 | | - result = testdir.runpytest('-vv') |
657 | | - result.stdout.fnmatch_lines([ |
658 | | - "*- 197", |
659 | | - ]) |
660 | | - |
661 | | - monkeypatch.setenv('CI', '1') |
662 | | - result = testdir.runpytest() |
663 | | - result.stdout.fnmatch_lines([ |
664 | | - "*- 197", |
665 | | - ]) |
666 | | - |
667 | | - |
668 | 740 | def test_assertrepr_loaded_per_dir(testdir): |
669 | 741 | testdir.makepyfile(test_base=['def test_base(): assert 1 == 2']) |
670 | 742 | a = testdir.mkdir('a') |
@@ -883,4 +955,3 @@ def f(): |
883 | 955 | result = testdir.runpytest() |
884 | 956 | result.stdout.fnmatch_lines(["*1 error*"]) |
885 | 957 | assert "AttributeError: 'Module' object has no attribute '_obj'" not in result.stdout.str() |
886 | | - |
|
0 commit comments