import pytest import sys import os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from slic.utils.ask_yes_no import * from unittest.mock import patch @pytest.mark.parametrize( "default, user_input, expected_output, expected_prompt", [ # Basic cases (None, 'y', True, "Question? [y/n] "), (None, 'yes', True, "Question? [y/n] "), (None, 'n', False, "Question? [y/n] "), (None, 'no', False, "Question? [y/n] "), # Invalid entrances first (None, ['maybe', 'y'], True, "Question? [y/n] "), (None, ['', 'no'], False, "Question? [y/n] "), (None, ['invalid', '', 'invalid', 'yes'], True, "Question? [y/n] "), # Try different defaults values than None ('y', 'y', True, "Question? [Y/n] "), ('y', 'n', False, "Question? [Y/n] "), ('y', '', True, "Question? [Y/n] "), ('n', 'y', True, "Question? [y/N] "), ('n', 'n', False, "Question? [y/N] "), ('n', '', False, "Question? [y/N] "), ] ) def test_ask_yes_no(default, user_input, expected_output, expected_prompt): patch_target = 'slic.utils.ask_yes_no.read_input' if isinstance(user_input, list): input_patch = patch(patch_target, side_effect=user_input) else: input_patch = patch(patch_target, return_value=user_input) with input_patch as mock_input: result = ask_yes_no("Question", default=default) assert result == expected_output first_prompt = mock_input.call_args_list[0][0][0] assert first_prompt == expected_prompt # If ctrl_c occurs @pytest.mark.parametrize( "default, user_input, expected_output, ctrl_c", [ # Basic cases where it takes directly ctrl_c value (None, KeyboardInterrupt, False, "n"), (None, KeyboardInterrupt, True, "y"), ('y', KeyboardInterrupt, False, "n"), ('y', KeyboardInterrupt, True, "y"), ('n', KeyboardInterrupt, False, "n"), # Complex case where at the end it takes ctrl_c value after some loop (None, ['invalid', '', 'invalid', KeyboardInterrupt], False, "n"), (None, ['invalid', '', 'invalid', KeyboardInterrupt], True, "y"), # Cases where at the end even with some KeyboardInterrupt it don't takes the ctrl_c value (None, ['foo', '', KeyboardInterrupt, '', 'invalid', KeyboardInterrupt,'no'], False, None), ('n', [KeyboardInterrupt, KeyboardInterrupt, KeyboardInterrupt, ''], False, None), ('n', [KeyboardInterrupt, KeyboardInterrupt, KeyboardInterrupt, ''], False, "Invalid") ] ) def test_ask_yes_no_ctrl_c(default, user_input, expected_output, ctrl_c): patch_target = 'slic.utils.ask_yes_no.read_input' if isinstance(user_input, list): input_patch = patch(patch_target, side_effect=user_input) else: input_patch = patch(patch_target, side_effect=[user_input]) with input_patch: result = ask_yes_no("Question", default=default, ctrl_c=ctrl_c) assert result == expected_output # If ctrl_d occurs @pytest.mark.parametrize( "default, user_input, expected_output, ctrl_d", [ # Basic cases, where it takes directly ctrl_c value (None, EOFError, False, "n"), (None, EOFError, True, "y"), ('y', EOFError, True, "y"), ('n', EOFError, True, "y"), ('n', EOFError, False, "n"), (None, ['foo', EOFError], True, "y"), (None, ['foo', EOFError], False, "n"), # Ctrl_d = None cases ('y', EOFError, True, None), ('n', EOFError, False, None), (None, ['invalid', 'ok', '', EOFError, 'ok', 'y'], True, None), ('n', ['no', EOFError], False, None), (None, [EOFError, EOFError, EOFError, 'y'], True, None), # Long sequences (None, ['invalid', '', 'nope', EOFError], False, "n"), (None, ['nope', 'nope', EOFError], True, "y"), ] ) def test_ask_yes_no_ctrl_d(default, user_input, expected_output, ctrl_d): patch_target = 'slic.utils.ask_yes_no.read_input' if isinstance(user_input, list): input_patch = patch(patch_target, side_effect=user_input) else: input_patch = patch(patch_target, side_effect=[user_input]) with input_patch: result = ask_yes_no("Question", default=default, ctrl_d=ctrl_d) assert result == expected_output # Mixte of errors @pytest.mark.parametrize( "default, ctrl_c, ctrl_d, user_input, expected_output", [ (None, "invalid", None, ['what', '', 'nope', KeyboardInterrupt, 'ok', EOFError, 'no'], False), (None, None, "notananswer", ['maybe', KeyboardInterrupt, 'nop', 'yep', EOFError, 'yes'], True), (None, "n", "nop", ['ok', EOFError, EOFError, 'maybe', EOFError, 'nah', KeyboardInterrupt], False), ] ) def test_ask_yes_no_mixed_sequences(default, ctrl_c, ctrl_d, user_input, expected_output): patch_target = 'slic.utils.ask_yes_no.read_input' with patch(patch_target, side_effect=user_input): result = ask_yes_no("Question", default=default, ctrl_c=ctrl_c, ctrl_d=ctrl_d) assert result == expected_output