From 3243e9b6098291362ec7e5dc57eb9e4629f20815 Mon Sep 17 00:00:00 2001 From: Kevin Van Brunt Date: Thu, 18 Nov 2021 22:45:06 -0500 Subject: [PATCH] Added unit tests for right-aligned numbers in completion hint tables --- CHANGELOG.md | 4 +- tests/test_argparse_completer.py | 71 ++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fc003e4..e32dd4af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.3.1 (TBD, 2021) +## 2.3.1 (November 18, 2021) * Bug Fixes * Fixed issue introduced in 2.3.0 with `AlternatingTable`, `BorderedTable`, and `SimpleTable` that caused header alignment settings to be overridden by data alignment settings. @@ -6,7 +6,7 @@ * `CompletionItems` now saves the original object from which it creates a string. * Using `CompletionItems` as argparse choices is fully supported. `cmd2` patched `argparse` to compare input to the original value instead of the `CompletionItems` instance. - * `ArgparseCompleter` now does the following if a list of `CompletionItems` was created with numerical types + * `ArgparseCompleter` now does the following if a list of `CompletionItems` was created with numerical types: * Sorts completion hints numerically * Right-aligns the left-most column in completion hint table diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py index 3c9da6bf..0586b476 100644 --- a/tests/test_argparse_completer.py +++ b/tests/test_argparse_completer.py @@ -23,6 +23,7 @@ ) from cmd2.utils import ( StdSim, + align_right, ) from .conftest import ( @@ -718,6 +719,53 @@ def test_autocomp_blank_token(ac_app): assert sorted(completions) == sorted(ArgparseCompleterTester.completions_for_pos_2) +def test_completion_items(ac_app): + # First test CompletionItems created from strings + text = '' + line = 'choices --completion_items {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + first_match = complete_tester(text, line, begidx, endidx, ac_app) + assert first_match is not None + assert len(ac_app.completion_matches) == len(ac_app.completion_item_choices) + assert len(ac_app.display_matches) == len(ac_app.completion_item_choices) + + # Look for both the value and description in the hint table + line_found = False + for line in ac_app.formatted_completions.splitlines(): + # Since the CompletionItems were created from strings, the left-most column is left-aligned. + # Therefore choice_1 will begin the line. + if line.startswith('choice_1') and 'A description' in line: + line_found = True + break + + assert line_found + + # Now test CompletionItems created from numbers + text = '' + line = 'choices --num_completion_items {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + first_match = complete_tester(text, line, begidx, endidx, ac_app) + assert first_match is not None + assert len(ac_app.completion_matches) == len(ac_app.num_completion_items) + assert len(ac_app.display_matches) == len(ac_app.num_completion_items) + + # Look for both the value and description in the hint table + line_found = False + aligned_val = align_right('1.5', width=cmd2.ansi.style_aware_wcswidth('num_completion_items')) + for line in ac_app.formatted_completions.splitlines(): + # Since the CompletionItems were created from numbers, the left-most column is right-aligned. + # Therefore 1.5 will be right-aligned in a field as wide as the arg ("num_completion_items"). + if line.startswith(aligned_val) and 'One.Five' in line: + line_found = True + break + + assert line_found + + @pytest.mark.parametrize( 'num_aliases, show_description', [ @@ -729,7 +777,7 @@ def test_autocomp_blank_token(ac_app): (100, False), ], ) -def test_completion_items(ac_app, num_aliases, show_description): +def test_max_completion_items(ac_app, num_aliases, show_description): # Create aliases for i in range(0, num_aliases): run_cmd(ac_app, 'alias create fake_alias{} help'.format(i)) @@ -758,27 +806,6 @@ def test_completion_items(ac_app, num_aliases, show_description): assert description_displayed -def test_completion_item_choices(ac_app): - text = '' - line = 'choices --completion_items {}'.format(text) - endidx = len(line) - begidx = endidx - len(text) - - first_match = complete_tester(text, line, begidx, endidx, ac_app) - assert first_match is not None - assert len(ac_app.completion_matches) == len(ac_app.completion_item_choices) - assert len(ac_app.display_matches) == len(ac_app.completion_item_choices) - - # The table will show both the choice and description - description_displayed = False - for line in ac_app.formatted_completions.splitlines(): - if 'choice_1' in line and 'A description' in line: - description_displayed = True - break - - assert description_displayed - - @pytest.mark.parametrize( 'args, completions', [