@@ -695,165 +695,183 @@ def test_static_subcommands(static_subcommands_app):
695
695
696
696
697
697
@cmd2 .with_default_category ('With Completer' )
698
- class WithCompleterCommandSet (cmd2 .CommandSet ):
698
+ class SupportFuncProvider (cmd2 .CommandSet ):
699
+ """CommandSet which provides a support function (complete_states) to other CommandSets"""
700
+
699
701
states = ['alabama' , 'alaska' , 'arizona' , 'arkansas' , 'california' , 'colorado' , 'connecticut' , 'delaware' ]
700
702
701
703
def __init__ (self , dummy ):
702
704
"""dummy variable prevents this from being autoloaded in other tests"""
703
- super (WithCompleterCommandSet , self ).__init__ ()
705
+ super (SupportFuncProvider , self ).__init__ ()
704
706
705
707
def complete_states (self , text : str , line : str , begidx : int , endidx : int ) -> List [str ]:
706
708
assert self is complete_states_expected_self
707
709
return self ._cmd .basic_complete (text , line , begidx , endidx , self .states )
708
710
709
711
710
- class SubclassCommandSetCase1 (WithCompleterCommandSet ):
712
+ class SupportFuncUserSubclass1 (SupportFuncProvider ):
713
+ """A sub-class of SupportFuncProvider which uses its support function"""
714
+
711
715
parser = cmd2 .Cmd2ArgumentParser ()
712
- parser .add_argument ('state' , type = str , completer = WithCompleterCommandSet .complete_states )
716
+ parser .add_argument ('state' , type = str , completer = SupportFuncProvider .complete_states )
713
717
714
718
@cmd2 .with_argparser (parser )
715
- def do_case1 (self , ns : argparse .Namespace ):
719
+ def do_user_sub1 (self , ns : argparse .Namespace ):
716
720
self ._cmd .poutput ('something {}' .format (ns .state ))
717
721
718
722
719
- class SubclassCommandSetErrorCase2 (WithCompleterCommandSet ):
723
+ class SupportFuncUserSubclass2 (SupportFuncProvider ):
724
+ """A second sub-class of SupportFuncProvider which uses its support function"""
725
+
720
726
parser = cmd2 .Cmd2ArgumentParser ()
721
- parser .add_argument ('state' , type = str , completer = WithCompleterCommandSet .complete_states )
727
+ parser .add_argument ('state' , type = str , completer = SupportFuncProvider .complete_states )
722
728
723
729
@cmd2 .with_argparser (parser )
724
- def do_error2 (self , ns : argparse .Namespace ):
730
+ def do_user_sub2 (self , ns : argparse .Namespace ):
725
731
self ._cmd .poutput ('something {}' .format (ns .state ))
726
732
727
733
728
- class SubclassCommandSetCase2 (cmd2 .CommandSet ):
734
+ class SupportFuncUserUnrelated (cmd2 .CommandSet ):
735
+ """A CommandSet that isn't related to SupportFuncProvider which uses its support function"""
736
+
729
737
def __init__ (self , dummy ):
730
738
"""dummy variable prevents this from being autoloaded in other tests"""
731
- super (SubclassCommandSetCase2 , self ).__init__ ()
739
+ super (SupportFuncUserUnrelated , self ).__init__ ()
732
740
733
741
parser = cmd2 .Cmd2ArgumentParser ()
734
- parser .add_argument ('state' , type = str , completer = WithCompleterCommandSet .complete_states )
742
+ parser .add_argument ('state' , type = str , completer = SupportFuncProvider .complete_states )
735
743
736
744
@cmd2 .with_argparser (parser )
737
- def do_case2 (self , ns : argparse .Namespace ):
745
+ def do_user_unrelated (self , ns : argparse .Namespace ):
738
746
self ._cmd .poutput ('something {}' .format (ns .state ))
739
747
740
748
741
749
def test_cross_commandset_completer (command_sets_manual ):
742
750
global complete_states_expected_self
743
751
# This tests the different ways to locate the matching CommandSet when completing an argparse argument.
744
- # Exercises the `_complete_arg` function of `ArgparseCompleter` in `argparse_completer.py`
752
+ # Exercises the 3 cases in cmd2.Cmd._resolve_func_self().
753
+
754
+ # Create all the CommandSets for these tests
755
+ func_provider = SupportFuncProvider (1 )
756
+ user_sub1 = SupportFuncUserSubclass1 (2 )
757
+ user_sub2 = SupportFuncUserSubclass2 (3 )
758
+ user_unrelated = SupportFuncUserUnrelated (4 )
745
759
746
760
####################################################################################################################
747
761
# This exercises Case 1
748
762
# If the CommandSet holding a command is a sub-class of the class that defines the completer function, then use that
749
763
# CommandSet instance as self when calling the completer
750
- case1_set = SubclassCommandSetCase1 (1 )
751
764
752
- command_sets_manual .register_command_set (case1_set )
765
+ # Create instances of two different sub-class types to ensure no one removes the case 1 check in Cmd._resolve_func_self().
766
+ # If that check is removed, testing with only 1 sub-class type will still pass. Testing it with two sub-class types
767
+ # will fail and show that the case 1 check cannot be removed.
768
+ command_sets_manual .register_command_set (user_sub1 )
769
+ command_sets_manual .register_command_set (user_sub2 )
753
770
754
771
text = ''
755
- line = 'case1 {}' .format (text )
772
+ line = 'user_sub1 {}' .format (text )
756
773
endidx = len (line )
757
774
begidx = endidx
758
- complete_states_expected_self = case1_set
775
+ complete_states_expected_self = user_sub1
759
776
first_match = complete_tester (text , line , begidx , endidx , command_sets_manual )
760
777
complete_states_expected_self = None
761
778
762
779
assert first_match == 'alabama'
763
- assert command_sets_manual .completion_matches == WithCompleterCommandSet .states
780
+ assert command_sets_manual .completion_matches == SupportFuncProvider .states
764
781
765
- assert getattr (command_sets_manual .cmd_func ('case1' ).__func__ , cmd2 .constants .CMD_ATTR_HELP_CATEGORY ) == 'With Completer'
782
+ assert (
783
+ getattr (command_sets_manual .cmd_func ('user_sub1' ).__func__ , cmd2 .constants .CMD_ATTR_HELP_CATEGORY ) == 'With Completer'
784
+ )
766
785
767
- command_sets_manual .unregister_command_set (case1_set )
786
+ command_sets_manual .unregister_command_set (user_sub2 )
787
+ command_sets_manual .unregister_command_set (user_sub1 )
768
788
769
789
####################################################################################################################
770
790
# This exercises Case 2
771
791
# If the CommandSet holding a command is unrelated to the CommandSet holding the completer function, then search
772
792
# all installed CommandSet instances for one that is an exact type match
773
793
774
- # First verify that, without the correct command set
775
- base_set = WithCompleterCommandSet (1 )
776
- case2_set = SubclassCommandSetCase2 (2 )
777
- command_sets_manual .register_command_set (base_set )
778
- command_sets_manual .register_command_set (case2_set )
794
+ command_sets_manual .register_command_set (func_provider )
795
+ command_sets_manual .register_command_set (user_unrelated )
779
796
780
797
text = ''
781
- line = 'case2 {}' .format (text )
798
+ line = 'user_unrelated {}' .format (text )
782
799
endidx = len (line )
783
800
begidx = endidx
784
- complete_states_expected_self = base_set
801
+ complete_states_expected_self = func_provider
785
802
first_match = complete_tester (text , line , begidx , endidx , command_sets_manual )
786
803
complete_states_expected_self = None
787
804
788
805
assert first_match == 'alabama'
789
- assert command_sets_manual .completion_matches == WithCompleterCommandSet .states
806
+ assert command_sets_manual .completion_matches == SupportFuncProvider .states
790
807
791
- command_sets_manual .unregister_command_set (case2_set )
792
- command_sets_manual .unregister_command_set (base_set )
808
+ command_sets_manual .unregister_command_set (user_unrelated )
809
+ command_sets_manual .unregister_command_set (func_provider )
793
810
794
811
####################################################################################################################
795
812
# This exercises Case 3
796
813
# If the CommandSet holding a command is unrelated to the CommandSet holding the completer function,
797
814
# and no exact type match can be found, but sub-class matches can be found and there is only a single
798
- # subclass match, then use the lone subclass match as the parent CommandSet.
815
+ # sub-class match, then use the lone sub-class match as the parent CommandSet.
799
816
800
- command_sets_manual .register_command_set (case1_set )
801
- command_sets_manual .register_command_set (case2_set )
817
+ command_sets_manual .register_command_set (user_sub1 )
818
+ command_sets_manual .register_command_set (user_unrelated )
802
819
803
820
text = ''
804
- line = 'case2 {}' .format (text )
821
+ line = 'user_unrelated {}' .format (text )
805
822
endidx = len (line )
806
823
begidx = endidx
807
- complete_states_expected_self = case1_set
824
+ complete_states_expected_self = user_sub1
808
825
first_match = complete_tester (text , line , begidx , endidx , command_sets_manual )
809
826
complete_states_expected_self = None
810
827
811
828
assert first_match == 'alabama'
812
- assert command_sets_manual .completion_matches == WithCompleterCommandSet .states
829
+ assert command_sets_manual .completion_matches == SupportFuncProvider .states
813
830
814
- command_sets_manual .unregister_command_set (case2_set )
815
- command_sets_manual .unregister_command_set (case1_set )
831
+ command_sets_manual .unregister_command_set (user_unrelated )
832
+ command_sets_manual .unregister_command_set (user_sub1 )
816
833
817
834
####################################################################################################################
818
835
# Error Case 1
819
836
# If the CommandSet holding a command is unrelated to the CommandSet holding the completer function, then search
820
837
# all installed CommandSet instances for one that is an exact type match, none are found
821
838
# search for sub-class matches, also none are found.
822
839
823
- command_sets_manual .register_command_set (case2_set )
840
+ command_sets_manual .register_command_set (user_unrelated )
824
841
825
842
text = ''
826
- line = 'case2 {}' .format (text )
843
+ line = 'user_unrelated {}' .format (text )
827
844
endidx = len (line )
828
845
begidx = endidx
829
846
first_match = complete_tester (text , line , begidx , endidx , command_sets_manual )
830
847
831
848
assert first_match is None
832
849
assert command_sets_manual .completion_matches == []
833
850
834
- command_sets_manual .unregister_command_set (case2_set )
851
+ command_sets_manual .unregister_command_set (user_unrelated )
835
852
836
853
####################################################################################################################
837
854
# Error Case 2
838
855
# If the CommandSet holding a command is unrelated to the CommandSet holding the completer function, then search
839
856
# all installed CommandSet instances for one that is an exact type match, none are found
840
- # search for sub-class matches, more than 1 is found
857
+ # search for sub-class matches, more than 1 is found.
841
858
842
- error_case2_set = SubclassCommandSetErrorCase2 (4 )
843
- command_sets_manual .register_command_set (case1_set )
844
- command_sets_manual .register_command_set (case2_set )
845
- command_sets_manual .register_command_set (error_case2_set )
859
+ command_sets_manual .register_command_set (user_sub1 )
860
+ command_sets_manual .register_command_set (user_sub2 )
861
+ command_sets_manual .register_command_set (user_unrelated )
846
862
847
863
text = ''
848
- line = 'case2 {}' .format (text )
864
+ line = 'user_unrelated {}' .format (text )
849
865
endidx = len (line )
850
866
begidx = endidx
851
867
first_match = complete_tester (text , line , begidx , endidx , command_sets_manual )
852
868
853
869
assert first_match is None
854
870
assert command_sets_manual .completion_matches == []
855
871
856
- command_sets_manual .unregister_command_set (case2_set )
872
+ command_sets_manual .unregister_command_set (user_unrelated )
873
+ command_sets_manual .unregister_command_set (user_sub2 )
874
+ command_sets_manual .unregister_command_set (user_sub1 )
857
875
858
876
859
877
class CommandSetWithPathComplete (cmd2 .CommandSet ):
0 commit comments