@@ -813,3 +813,139 @@ def test_help_overridden_method(help_app):
813813 out = run_cmd (help_app , 'help pause' )
814814 expected = normalize ('This overrides the pause command and does nothing.' )
815815 assert out == expected
816+
817+
818+ class SelectApp (cmd2 .Cmd ):
819+ def do_eat (self , arg ):
820+ """Eat something, with a selection of sauces to choose from."""
821+ # Pass in a single string of space-separated selections
822+ sauce = self .select ('sweet salty' , 'Sauce? ' )
823+ result = '{food} with {sauce} sauce, yum!'
824+ result = result .format (food = arg , sauce = sauce )
825+ self .stdout .write (result + '\n ' )
826+
827+ def do_study (self , arg ):
828+ """Learn something, with a selection of subjects to choose from."""
829+ # Pass in a list of strings for selections
830+ subject = self .select (['math' , 'science' ], 'Subject? ' )
831+ result = 'Good luck learning {}!\n ' .format (subject )
832+ self .stdout .write (result )
833+
834+ def do_procrastinate (self , arg ):
835+ """Waste time in your manner of choice."""
836+ # Pass in a list of tuples for selections
837+ leisure_activity = self .select ([('Netflix and chill' , 'Netflix' ), ('Porn' , 'WebSurfing' )],
838+ 'How would you like to procrastinate? ' )
839+ result = 'Have fun procrasinating with {}!\n ' .format (leisure_activity )
840+ self .stdout .write (result )
841+
842+ def do_play (self , arg ):
843+ """Play your favorite musical instrument."""
844+ # Pass in an uneven list of tuples for selections
845+ instrument = self .select ([('Guitar' , 'Electric Guitar' ), ('Drums' ,)], 'Instrument? ' )
846+ result = 'Charm us with the {}...\n ' .format (instrument )
847+ self .stdout .write (result )
848+
849+ @pytest .fixture
850+ def select_app ():
851+ app = SelectApp ()
852+ app .stdout = StdOut ()
853+ return app
854+
855+ def test_select_options (select_app ):
856+ # Mock out the input call so we don't actually wait for a user's response on stdin
857+ m = mock .MagicMock (name = 'input' , return_value = '2' )
858+ sm .input = m
859+
860+ food = 'bacon'
861+ out = run_cmd (select_app , "eat {}" .format (food ))
862+ expected = normalize ("""
863+ 1. sweet
864+ 2. salty
865+ {} with salty sauce, yum!
866+ """ .format (food ))
867+
868+ # Make sure our mock was called with the expected arguments
869+ m .assert_called_once_with ('Sauce? ' )
870+
871+ # And verify the expected output to stdout
872+ assert out == expected
873+
874+ def test_select_invalid_option (select_app ):
875+ # Mock out the input call so we don't actually wait for a user's response on stdin
876+ m = mock .MagicMock (name = 'input' )
877+ # If side_effect is an iterable then each call to the mock will return the next value from the iterable.
878+ m .side_effect = ['3' , '1' ] # First pass and invalid selection, then pass a valid one
879+ sm .input = m
880+
881+ food = 'fish'
882+ out = run_cmd (select_app , "eat {}" .format (food ))
883+ expected = normalize ("""
884+ 1. sweet
885+ 2. salty
886+ 3 isn't a valid choice. Pick a number between 1 and 2:
887+ {} with sweet sauce, yum!
888+ """ .format (food ))
889+
890+ # Make sure our mock was called exactly twice with the expected arguments
891+ arg = 'Sauce? '
892+ calls = [mock .call (arg ), mock .call (arg )]
893+ m .assert_has_calls (calls )
894+
895+ # And verify the expected output to stdout
896+ assert out == expected
897+
898+ def test_select_list_of_strings (select_app ):
899+ # Mock out the input call so we don't actually wait for a user's response on stdin
900+ m = mock .MagicMock (name = 'input' , return_value = '2' )
901+ sm .input = m
902+
903+ out = run_cmd (select_app , "study" )
904+ expected = normalize ("""
905+ 1. math
906+ 2. science
907+ Good luck learning {}!
908+ """ .format ('science' ))
909+
910+ # Make sure our mock was called with the expected arguments
911+ m .assert_called_once_with ('Subject? ' )
912+
913+ # And verify the expected output to stdout
914+ assert out == expected
915+
916+ def test_select_list_of_tuples (select_app ):
917+ # Mock out the input call so we don't actually wait for a user's response on stdin
918+ m = mock .MagicMock (name = 'input' , return_value = '2' )
919+ sm .input = m
920+
921+ out = run_cmd (select_app , "procrastinate" )
922+ expected = normalize ("""
923+ 1. Netflix
924+ 2. WebSurfing
925+ Have fun procrasinating with {}!
926+ """ .format ('Porn' ))
927+
928+ # Make sure our mock was called with the expected arguments
929+ m .assert_called_once_with ('How would you like to procrastinate? ' )
930+
931+ # And verify the expected output to stdout
932+ assert out == expected
933+
934+
935+ def test_select_uneven_list_of_tuples (select_app ):
936+ # Mock out the input call so we don't actually wait for a user's response on stdin
937+ m = mock .MagicMock (name = 'input' , return_value = '2' )
938+ sm .input = m
939+
940+ out = run_cmd (select_app , "play" )
941+ expected = normalize ("""
942+ 1. Electric Guitar
943+ 2. Drums
944+ Charm us with the {}...
945+ """ .format ('Drums' ))
946+
947+ # Make sure our mock was called with the expected arguments
948+ m .assert_called_once_with ('Instrument? ' )
949+
950+ # And verify the expected output to stdout
951+ assert out == expected
0 commit comments