Esempio n. 1
0
 def test_result_value_multi(self):
     prompt = FuzzyPrompt(message="Select one of them",
                          choices=[1, 2, 3],
                          multiselect=True)
     self.assertEqual(prompt.result_value, [])
     prompt.content_control.choices[0]["enabled"] = True
     prompt.content_control.choices[2]["enabled"] = True
     self.assertEqual(prompt.result_value, [1, 3])
Esempio n. 2
0
    def test_extra_lines_with_long_instruction(self, mocked_term,
                                               mocked_term2):
        mocked_term.return_value = (24, 80)
        mocked_term2.return_value = (24, 80)
        message = 15 * "i"
        qmark = "[?]"
        instruction = 3 * "i"
        long_instruction = 24 * "i"
        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            long_instruction=long_instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
        )
        self.assertEqual(prompt.extra_long_instruction_line_count, 0)

        long_instruction = 25 * "i"
        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            long_instruction=long_instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
        )
        self.assertEqual(prompt.extra_long_instruction_line_count, 1)
Esempio n. 3
0
    def test_height_offset(self, mocked_term) -> None:
        mocked_term.return_value = (24, 80)
        message = 15 * "i"
        qmark = "[?]"
        instruction = 4 * "i"
        prompt = FuzzyPrompt(message=message,
                             qmark=qmark,
                             instruction=instruction,
                             choices=[1, 2, 3])
        self.assertEqual(prompt.height_offset, 4)
        prompt._wrap_lines = False
        self.assertEqual(prompt.height_offset, 3)

        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            choices=[1, 2, 3],
            border=True,
        )
        self.assertEqual(prompt.height_offset, 6)

        instruction = 3 * "i"  # width total should be 24 and no extra lines needed
        prompt = FuzzyPrompt(message=message,
                             qmark=qmark,
                             instruction=instruction,
                             choices=[1, 2, 3])
        self.assertEqual(prompt.height_offset, 3)
Esempio n. 4
0
    def test_result_value_simple(self):
        prompt = FuzzyPrompt(message="Select one of them", choices=[1, 2, 3])

        self.assertEqual(prompt.result_value, 1)
        prompt.content_control.selected_choice_index = 1
        self.assertEqual(prompt.result_value, 2)

        prompt.content_control.selected_choice_index = 4
        self.assertEqual(prompt.result_value, "")
Esempio n. 5
0
    def test_get_error_message(self):
        class SelectionValidator(Validator):
            def validate(self, document) -> None:
                if document.text == 1:
                    raise ValidationError(
                        message="hello",
                        cursor_position=document.cursor_position)

        prompt = FuzzyPrompt(
            message="",
            choices=[1, 2, 3],
            validate=SelectionValidator(),
            invalid_message="minimum 2 selections",
        )
        self.assertEqual(prompt._invalid_message, "minimum 2 selections")
        self.assertFalse(prompt._invalid)
        prompt._handle_enter(None)
        self.assertEqual(prompt._invalid_message, "hello")
        self.assertTrue(prompt._invalid)
        self.assertEqual(prompt._get_error_message(),
                         [("class:validation-toolbar", "hello")])
Esempio n. 6
0
 def test_prompt_handle_toggle_all_filter(self) -> None:
     prompt = FuzzyPrompt(message="",
                          choices=["haha", "asdfa", "112321fd"],
                          multiselect=True)
     prompt.content_control._current_text = lambda: "haha"
     prompt.content_control._filtered_choices = asyncio.run(
         prompt.content_control._filter_choices(0.0))
     self.assertEqual(
         prompt.content_control._filtered_choices,
         [{
             "enabled": False,
             "index": 0,
             "indices": [0, 1, 2, 3],
             "name": "haha",
             "value": "haha",
         }],
     )
     prompt._handle_toggle_all(None)
     self.assertEqual(prompt.content_control.choices[0]["enabled"], True)
     self.assertEqual(prompt.content_control.choices[1]["enabled"], False)
     self.assertEqual(prompt.content_control.choices[2]["enabled"], False)
Esempio n. 7
0
    def test_prompt_message(self):
        prompt = FuzzyPrompt(message="Select one of them",
                             choices=lambda _: [1, 2, 3])

        self.assertEqual(
            prompt._get_prompt_message(),
            [
                ("class:questionmark", "?"),
                ("class:question", " Select one of them"),
                ("class:instruction", " "),
            ],
        )
        prompt.status["answered"] = True
        prompt.status["result"] = ["hello"]
        prompt.status["skipped"] = False

        self.assertEqual(
            prompt._get_prompt_message(),
            [
                ("class:answermark", "?"),
                ("class:answered_question", " Select one of them"),
                ("class:answer", " ['hello']"),
            ],
        )

        prompt = FuzzyPrompt(
            message=lambda result: "no" if not result else "hello",
            choices=[1, 2, 3],
            session_result={"1": True},
        )
        self.assertEqual(
            prompt._get_prompt_message(),
            [
                ("class:questionmark", "?"),
                ("class:question", " hello"),
                ("class:instruction", " "),
            ],
        )
Esempio n. 8
0
 def test_prompt_handle_toggle_all_no_multiselect(self):
     prompt = FuzzyPrompt(message="", choices=[1], multiselect=False)
     self.assertEqual(
         prompt.content_control.choices,
         [{
             "enabled": False,
             "index": 0,
             "indices": [],
             "name": "1",
             "value": 1,
         }],
     )
     prompt._handle_toggle_all(None)
     self.assertEqual(
         prompt.content_control.choices,
         [{
             "enabled": False,
             "index": 0,
             "indices": [],
             "name": "1",
             "value": 1,
         }],
     )
Esempio n. 9
0
 def test_prompt_after_input(self):
     prompt = FuzzyPrompt(
         message="Select one of them",
         choices=["haah", "haha", "what", "waht", "weaht"],
     )
     self.assertEqual(prompt._generate_after_input(),
                      [("", "  "), ("class:fuzzy_info", "5/5")])
     prompt = FuzzyPrompt(
         message="Select one of them",
         choices=["haah", "haha", "what", "waht", "weaht"],
         info=False,
     )
     self.assertEqual(prompt._generate_after_input(), [])
Esempio n. 10
0
 def test_prompt_before_input(self):
     prompt = FuzzyPrompt(
         message="Select one of them",
         choices=["haah", "haha", "what", "waht", "weaht"],
     )
     self.assertEqual(prompt._generate_before_input(),
                      [("class:fuzzy_prompt", "❯ ")])
     prompt = FuzzyPrompt(
         message="Select one of them",
         choices=["haah", "haha", "what", "waht", "weaht"],
         prompt=">",
     )
     self.assertEqual(prompt._generate_before_input(),
                      [("class:fuzzy_prompt", "> ")])
Esempio n. 11
0
    def test_prompt_validator(self, _):
        prompt = FuzzyPrompt(
            message="Select one",
            choices=["haha", "asa", "132132"],
            validate=lambda x: len(x) > 1,
            invalid_message="what",
            multiselect=True,
        )
        self.assertEqual(prompt._invalid, False)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
            self.assertEqual(prompt._invalid_message, "what")
            self.assertEqual(prompt._invalid, True)

        prompt._on_text_changed("")
        self.assertEqual(prompt._invalid, False)
Esempio n. 12
0
    def test_handle_up_no_cycle(self):
        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            cycle=False,
        )
        self.assertEqual(prompt.content_control.selected_choice_index, 0)
        prompt._handle_up(None)
        self.assertEqual(prompt.content_control.selected_choice_index, 0)
        prompt._handle_up(None)
        prompt._handle_up(None)
        self.assertEqual(prompt.content_control.selected_choice_index, 0)
        prompt._handle_down(None)
        prompt._handle_down(None)
        self.assertEqual(prompt.content_control.selected_choice_index, 2)
        prompt._handle_up(None)
        prompt._handle_up(None)
        prompt._handle_up(None)
        prompt._handle_up(None)
        self.assertEqual(prompt.content_control.selected_choice_index, 0)

        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            cycle=False,
        )
Esempio n. 13
0
 def test_prompt_handle_toggle_all(self):
     prompt = FuzzyPrompt(message="",
                          choices=["haha", "asdfa", "112321fd"],
                          multiselect=True)
     self.assertEqual(
         prompt.content_control.choices,
         [
             {
                 "enabled": False,
                 "index": 0,
                 "indices": [],
                 "name": "haha",
                 "value": "haha",
             },
             {
                 "enabled": False,
                 "index": 1,
                 "indices": [],
                 "name": "asdfa",
                 "value": "asdfa",
             },
             {
                 "enabled": False,
                 "index": 2,
                 "indices": [],
                 "name": "112321fd",
                 "value": "112321fd",
             },
         ],
     )
     prompt._handle_toggle_all(None)
     self.assertEqual(
         prompt.content_control.choices,
         [
             {
                 "enabled": True,
                 "index": 0,
                 "indices": [],
                 "name": "haha",
                 "value": "haha",
             },
             {
                 "enabled": True,
                 "index": 1,
                 "indices": [],
                 "name": "asdfa",
                 "value": "asdfa",
             },
             {
                 "enabled": True,
                 "index": 2,
                 "indices": [],
                 "name": "112321fd",
                 "value": "112321fd",
             },
         ],
     )
     prompt._handle_toggle_all(None, True)
     self.assertEqual(
         prompt.content_control.choices,
         [
             {
                 "enabled": True,
                 "index": 0,
                 "indices": [],
                 "name": "haha",
                 "value": "haha",
             },
             {
                 "enabled": True,
                 "index": 1,
                 "indices": [],
                 "name": "asdfa",
                 "value": "asdfa",
             },
             {
                 "enabled": True,
                 "index": 2,
                 "indices": [],
                 "name": "112321fd",
                 "value": "112321fd",
             },
         ],
     )
     prompt._handle_toggle_all(None)
     self.assertEqual(
         prompt.content_control.choices,
         [
             {
                 "enabled": False,
                 "index": 0,
                 "indices": [],
                 "name": "haha",
                 "value": "haha",
             },
             {
                 "enabled": False,
                 "index": 1,
                 "indices": [],
                 "name": "asdfa",
                 "value": "asdfa",
             },
             {
                 "enabled": False,
                 "index": 2,
                 "indices": [],
                 "name": "112321fd",
                 "value": "112321fd",
             },
         ],
     )
Esempio n. 14
0
    def test_prompt_bindings(self):
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            self.prompt._handle_enter(event)
        self.assertEqual(self.prompt.status["answered"], True)
        self.assertEqual(self.prompt.status["result"], "haah")
        self.assertEqual(self.prompt.status["skipped"], False)

        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            multiselect=True,
        )
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], ["haah"])
        self.assertEqual(prompt.status["skipped"], False)
        prompt.status["answered"] = False
        prompt.status["result"] = None
        prompt._handle_toggle_choice(None)
        prompt._handle_down(None)
        prompt._handle_toggle_choice(None)
        prompt._handle_down(None)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], ["haah", "haha"])
        self.assertEqual(prompt.status["skipped"], False)

        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            multiselect=True,
        )
        prompt.content_control._filtered_choices = []
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], [])
Esempio n. 15
0
    def test_constructor(self, mocked_term, mocked_height, mocked_control):
        mocked_term.return_value = (24, 80)
        mocked_height.return_value = (80, 80)
        message = 15 * "i"
        qmark = "[?]"
        instruction = 2 * "i"
        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
        )

        self.assertEqual(prompt._instruction, instruction)
        self.assertEqual(prompt._multiselect, False)
        self.assertEqual(prompt._prompt, INQUIRERPY_POINTER_SEQUENCE)
        self.assertFalse(prompt._border)
        self.assertEqual(prompt._info, True)
        self.assertIsInstance(prompt._buffer, Buffer)
        self.assertIsInstance(prompt._layout, Layout)
        self.assertIsInstance(prompt._application, Application)
        mocked_control.assert_called_with(
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=ANY,
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )

        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            border=True,
        )
        mocked_control.assert_called_with(
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=ANY,
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )
Esempio n. 16
0
class TestFuzzy(unittest.TestCase):
    content_control = InquirerPyFuzzyControl(
        choices=["haah", "haha", "what", "waht", "weaht"],
        pointer=INQUIRERPY_POINTER_SEQUENCE,
        marker=INQUIRERPY_POINTER_SEQUENCE,
        current_text=lambda: "yes",
        max_lines=80,
        session_result=None,
        multiselect=False,
        marker_pl=" ",
        match_exact=False,
    )

    @patch("InquirerPy.utils.shutil.get_terminal_size")
    def setUp(self, mocked_term):
        mocked_term.return_value = (24, 80)
        self.prompt = FuzzyPrompt(
            message="Select one of them",
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
        )

    def test_content_control_init(self):
        self.assertEqual(self.content_control._pointer,
                         INQUIRERPY_POINTER_SEQUENCE)
        self.assertEqual(self.content_control._marker,
                         INQUIRERPY_POINTER_SEQUENCE)
        self.assertEqual(self.content_control._current_text(), "yes")
        self.assertEqual(
            self.content_control.choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "haah",
                    "value": "haah",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "waht",
                    "value": "waht",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "weaht",
                    "value": "weaht",
                },
            ],
        )
        self.assertEqual(
            self.content_control._filtered_choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "haah",
                    "value": "haah",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "waht",
                    "value": "waht",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "weaht",
                    "value": "weaht",
                },
            ],
        )
        self.assertEqual(self.content_control.selected_choice_index, 0)
        self.assertEqual(
            self.content_control.selection,
            {
                "index": 0,
                "name": "haah",
                "enabled": False,
                "value": "haah",
                "indices": [],
            },
        )
        self.assertEqual(self.content_control.choice_count, 5)

    def test_content_control_text(self):
        self.content_control.choices[0]["enabled"] = True
        self.assertEqual(
            self.content_control._get_formatted_choices(),
            [
                ("class:pointer", "❯"),
                ("class:marker", "❯"),
                ("[SetCursorPosition]", ""),
                ("class:pointer", "haah"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("", "haha"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("", "what"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("", "waht"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("", "weaht"),
            ],
        )
        self.content_control.choices[0]["enabled"] = False

    def test_prompt_filter1(self):
        content_control = InquirerPyFuzzyControl(
            choices=["meat", "what", "whaaah", "weather", "haha"],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=lambda: "wh",
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )
        self.assertEqual(
            content_control._filtered_choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "meat",
                    "value": "meat",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "whaaah",
                    "value": "whaaah",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "weather",
                    "value": "weather",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
            ],
        )
        result = asyncio.run(content_control._filter_choices(0.0))
        self.assertEqual(
            result,
            [
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [0, 1],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [0, 1],
                    "name": "whaaah",
                    "value": "whaaah",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [0, 4],
                    "name": "weather",
                    "value": "weather",
                },
            ],
        )
        content_control._filtered_choices = result
        self.assertEqual(
            content_control._get_formatted_choices(),
            [
                ("class:pointer", "❯"),
                ("class:marker", " "),
                ("[SetCursorPosition]", ""),
                ("class:fuzzy_match", "w"),
                ("class:fuzzy_match", "h"),
                ("class:pointer", "a"),
                ("class:pointer", "t"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("class:fuzzy_match", "w"),
                ("class:fuzzy_match", "h"),
                ("", "a"),
                ("", "a"),
                ("", "a"),
                ("", "h"),
                ("", "\n"),
                ("class:pointer", " "),
                ("class:marker", " "),
                ("class:fuzzy_match", "w"),
                ("", "e"),
                ("", "a"),
                ("", "t"),
                ("class:fuzzy_match", "h"),
                ("", "e"),
                ("", "r"),
            ],
        )
        self.assertEqual(content_control.choice_count, 3)
        self.assertEqual(content_control.selected_choice_index, 0)

    def test_prompt_filter2(self):
        content_control = InquirerPyFuzzyControl(
            choices=["meat", "what", "whaaah", "weather", "haha"],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=lambda: "",
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )
        content_control.choices[0]["indices"] = [1, 2, 3]
        asyncio.run(content_control._filter_choices(0.0))
        self.assertEqual(
            content_control._filtered_choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "meat",
                    "value": "meat",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "whaaah",
                    "value": "whaaah",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "weather",
                    "value": "weather",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
            ],
        )

    @patch("InquirerPy.prompts.fuzzy.InquirerPyFuzzyControl")
    @patch("InquirerPy.prompts.fuzzy.calculate_height")
    @patch("InquirerPy.utils.shutil.get_terminal_size")
    def test_constructor(self, mocked_term, mocked_height, mocked_control):
        mocked_term.return_value = (24, 80)
        mocked_height.return_value = (80, 80)
        message = 15 * "i"
        qmark = "[?]"
        instruction = 2 * "i"
        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
        )

        self.assertEqual(prompt._instruction, instruction)
        self.assertEqual(prompt._multiselect, False)
        self.assertEqual(prompt._prompt, INQUIRERPY_POINTER_SEQUENCE)
        self.assertFalse(prompt._border)
        self.assertEqual(prompt._info, True)
        self.assertIsInstance(prompt._buffer, Buffer)
        self.assertIsInstance(prompt._layout, Layout)
        self.assertIsInstance(prompt._application, Application)
        mocked_control.assert_called_with(
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=ANY,
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )

        prompt = FuzzyPrompt(
            message=message,
            qmark=qmark,
            instruction=instruction,
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            border=True,
        )
        mocked_control.assert_called_with(
            choices=[
                "haah",
                "haha",
                "what",
                "waht",
                {
                    "name": "weaht",
                    "value": "weaht",
                    "enabled": True
                },
            ],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=ANY,
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=False,
        )

    def test_prompt_after_input(self):
        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
        )
        self.assertEqual(prompt._generate_after_input(),
                         [("", "  "), ("class:fuzzy_info", "5/5")])
        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            info=False,
        )
        self.assertEqual(prompt._generate_after_input(), [])

    def test_prompt_after_input2(self):
        prompt = FuzzyPrompt(message="",
                             choices=["1", "2", "3"],
                             match_exact=True,
                             exact_symbol=" *")
        self.assertEqual(
            prompt._generate_after_input(),
            [("", "  "), ("class:fuzzy_info", "3/3"),
             ("class:fuzzy_info", " *")],
        )

    def test_prompt_before_input(self):
        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
        )
        self.assertEqual(prompt._generate_before_input(),
                         [("class:fuzzy_prompt", "❯ ")])
        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            prompt=">",
        )
        self.assertEqual(prompt._generate_before_input(),
                         [("class:fuzzy_prompt", "> ")])

    @patch("asyncio.create_task")
    def test_prompt_on_text_changed(self, mocked):
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)
        self.prompt.content_control.selected_choice_index = 4
        self.prompt._buffer.text = "ha"
        mocked.assert_called()

    def test_prompt_filter_callback(self):
        class Hello(NamedTuple):
            cancelled: Callable
            result: Callable

        hello = Hello(cancelled=lambda: True, result=lambda: [])
        self.prompt._filter_callback(hello)
        self.assertEqual(
            self.prompt.content_control._filtered_choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "haah",
                    "value": "haah",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "waht",
                    "value": "waht",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "weaht",
                    "value": "weaht",
                },
            ],
        )
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)
        self.prompt.content_control.selected_choice_index = 4
        hello = Hello(cancelled=lambda: False, result=lambda: [])
        self.prompt._filter_callback(hello)
        self.prompt.content_control._get_formatted_choices()
        self.assertEqual(self.prompt.content_control._filtered_choices, [])
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)

        self.prompt.content_control.selected_choice_index = -1
        hello = Hello(
            cancelled=lambda: False,
            result=lambda: [{
                "enabled": False,
                "index": i,
                "indices": [],
                "name": "weaht",
                "value": "weaht",
            } for i in range(3)],
        )
        self.prompt._filter_callback(hello)
        self.prompt.content_control._get_formatted_choices()
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)
        self.assertEqual(self.prompt.content_control._first_line, 0)
        self.assertEqual(self.prompt.content_control._last_line, 3)

        self.prompt.content_control.selected_choice_index = 5
        hello = Hello(
            cancelled=lambda: False,
            result=lambda: [{
                "enabled": False,
                "index": i,
                "indices": [],
                "name": "weaht",
                "value": "weaht",
            } for i in range(3)],
        )
        self.prompt._filter_callback(hello)
        self.prompt.content_control._get_formatted_choices()
        self.assertEqual(self.prompt.content_control.selected_choice_index, 2)
        self.assertEqual(self.prompt.content_control._first_line, 0)
        self.assertEqual(self.prompt.content_control._last_line, 3)

    def test_prompt_bindings(self):
        self.assertEqual(self.prompt.content_control.selected_choice_index, 0)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            self.prompt._handle_enter(event)
        self.assertEqual(self.prompt.status["answered"], True)
        self.assertEqual(self.prompt.status["result"], "haah")
        self.assertEqual(self.prompt.status["skipped"], False)

        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            multiselect=True,
        )
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], ["haah"])
        self.assertEqual(prompt.status["skipped"], False)
        prompt.status["answered"] = False
        prompt.status["result"] = None
        prompt._handle_toggle_choice(None)
        prompt._handle_down(None)
        prompt._handle_toggle_choice(None)
        prompt._handle_down(None)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], ["haah", "haha"])
        self.assertEqual(prompt.status["skipped"], False)

        prompt = FuzzyPrompt(
            message="Select one of them",
            choices=["haah", "haha", "what", "waht", "weaht"],
            multiselect=True,
        )
        prompt.content_control._filtered_choices = []
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
        self.assertEqual(prompt.status["answered"], True)
        self.assertEqual(prompt.status["result"], [])

    @patch("asyncio.create_task")
    def test_prompt_validator(self, _):
        prompt = FuzzyPrompt(
            message="Select one",
            choices=["haha", "asa", "132132"],
            validate=lambda x: len(x) > 1,
            invalid_message="what",
            multiselect=True,
        )
        self.assertEqual(prompt._invalid, False)
        with patch("prompt_toolkit.utils.Event") as mock:
            event = mock.return_value
            prompt._handle_enter(event)
            self.assertEqual(prompt._invalid_message, "what")
            self.assertEqual(prompt._invalid, True)

        prompt._on_text_changed("")
        self.assertEqual(prompt._invalid, False)

    def test_prompt_handle_toggle_no_multiselect(self):
        prompt = FuzzyPrompt(message="", choices=[1], multiselect=False)
        self.assertEqual(
            prompt.content_control.choices,
            [{
                "enabled": False,
                "index": 0,
                "indices": [],
                "name": "1",
                "value": 1,
            }],
        )
        prompt._handle_toggle_choice(None)
        self.assertEqual(
            prompt.content_control.choices,
            [{
                "enabled": False,
                "index": 0,
                "indices": [],
                "name": "1",
                "value": 1,
            }],
        )

    def test_prompt_handle_toggle_all_no_multiselect(self):
        prompt = FuzzyPrompt(message="", choices=[1], multiselect=False)
        self.assertEqual(
            prompt.content_control.choices,
            [{
                "enabled": False,
                "index": 0,
                "indices": [],
                "name": "1",
                "value": 1,
            }],
        )
        prompt._handle_toggle_all(None)
        self.assertEqual(
            prompt.content_control.choices,
            [{
                "enabled": False,
                "index": 0,
                "indices": [],
                "name": "1",
                "value": 1,
            }],
        )

    def test_prompt_handle_toggle_all_filter(self) -> None:
        prompt = FuzzyPrompt(message="",
                             choices=["haha", "asdfa", "112321fd"],
                             multiselect=True)
        prompt.content_control._current_text = lambda: "haha"
        prompt.content_control._filtered_choices = asyncio.run(
            prompt.content_control._filter_choices(0.0))
        self.assertEqual(
            prompt.content_control._filtered_choices,
            [{
                "enabled": False,
                "index": 0,
                "indices": [0, 1, 2, 3],
                "name": "haha",
                "value": "haha",
            }],
        )
        prompt._handle_toggle_all(None)
        self.assertEqual(prompt.content_control.choices[0]["enabled"], True)
        self.assertEqual(prompt.content_control.choices[1]["enabled"], False)
        self.assertEqual(prompt.content_control.choices[2]["enabled"], False)

    def test_prompt_handle_toggle_all(self):
        prompt = FuzzyPrompt(message="",
                             choices=["haha", "asdfa", "112321fd"],
                             multiselect=True)
        self.assertEqual(
            prompt.content_control.choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "asdfa",
                    "value": "asdfa",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "112321fd",
                    "value": "112321fd",
                },
            ],
        )
        prompt._handle_toggle_all(None)
        self.assertEqual(
            prompt.content_control.choices,
            [
                {
                    "enabled": True,
                    "index": 0,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": True,
                    "index": 1,
                    "indices": [],
                    "name": "asdfa",
                    "value": "asdfa",
                },
                {
                    "enabled": True,
                    "index": 2,
                    "indices": [],
                    "name": "112321fd",
                    "value": "112321fd",
                },
            ],
        )
        prompt._handle_toggle_all(None, True)
        self.assertEqual(
            prompt.content_control.choices,
            [
                {
                    "enabled": True,
                    "index": 0,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": True,
                    "index": 1,
                    "indices": [],
                    "name": "asdfa",
                    "value": "asdfa",
                },
                {
                    "enabled": True,
                    "index": 2,
                    "indices": [],
                    "name": "112321fd",
                    "value": "112321fd",
                },
            ],
        )
        prompt._handle_toggle_all(None)
        self.assertEqual(
            prompt.content_control.choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "asdfa",
                    "value": "asdfa",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "112321fd",
                    "value": "112321fd",
                },
            ],
        )

    def test_wait_time(self):
        self.prompt.content_control.choices = []
        self.assertEqual(self.prompt._calculate_wait_time(), 0.0)
        self.prompt.content_control.choices = [{} for _ in range(9)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.0)
        self.prompt.content_control.choices = [{} for _ in range(50)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.05)
        self.prompt.content_control.choices = [{} for _ in range(100)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.1)
        self.prompt.content_control.choices = [{} for _ in range(1000)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.2)
        self.prompt.content_control.choices = [{} for _ in range(10000)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.3)
        self.prompt.content_control.choices = [{} for _ in range(100000)]
        self.assertEqual(self.prompt._calculate_wait_time(), 0.6)
        self.prompt.content_control.choices = [{} for _ in range(1000000)]
        self.assertEqual(self.prompt._calculate_wait_time(), 1.2)

    def test_prompt_validator_index(self):
        class Hello(NamedTuple):
            cancelled: Callable
            result: Callable

        class App(NamedTuple):
            exit: Callable

        class Event(NamedTuple):
            app: NamedTuple

        hello = Hello(cancelled=lambda: False, result=lambda: [])
        self.prompt._filter_callback(hello)

        event = Event(App(exit=lambda result: True))
        self.prompt._handle_enter(event)

    @patch.object(FuzzyPrompt, "_on_text_changed")
    def test_on_rendered(self, _):
        prompt = FuzzyPrompt(message="", choices=[1, 2, 3], default="yes")
        self.assertEqual(prompt._buffer.text, "")
        self.assertEqual(prompt._buffer.cursor_position, 0)
        prompt._on_rendered(None)
        self.assertEqual(prompt._buffer.text, "yes")
        self.assertEqual(prompt._buffer.cursor_position, 3)

    @patch.object(FuzzyPrompt, "_on_rendered")
    @patch.object(BaseComplexPrompt, "register_kb")
    def test_constructor_keybindings(self, mocked_kb, mocked_rendered):
        prompt = FuzzyPrompt(message="", choices=[1, 2, 3])
        prompt._after_render(None)
        try:
            mocked_kb.assert_has_calls([call("space", filter=ANY)])
            mocked_kb.assert_has_calls([call("j", filter=ANY)])
            mocked_kb.assert_has_calls([call("k", filter=ANY)])
        except AssertionError:
            pass
        else:
            self.fail("space/j/k kb was registered")

    def test_control_line_render(self) -> None:
        control = InquirerPyFuzzyControl(
            choices=[i for i in range(6)],
            pointer="",
            marker="",
            current_text=lambda: "",
            max_lines=4,
            session_result=None,
            multiselect=True,
            marker_pl=" ",
            match_exact=False,
        )
        # range 0-4
        self.assertEqual(control._last_line, 4)
        self.assertEqual(control._first_line, 0)
        control._get_formatted_choices()
        self.assertEqual(control._last_line, 4)
        self.assertEqual(control._first_line, 0)

        # range 1-5
        control.selected_choice_index = 4
        control._get_formatted_choices()
        self.assertEqual(control._last_line, 5)
        self.assertEqual(control._first_line, 1)

        control.selected_choice_index = 6
        control._get_formatted_choices()
        self.assertEqual(control._last_line, 6)
        self.assertEqual(control._first_line, 2)

        control.selected_choice_index = 7
        control._get_formatted_choices()
        self.assertEqual(control._last_line, 6)
        self.assertEqual(control._first_line, 2)

    def test_control_exact_match(self) -> None:
        content_control = InquirerPyFuzzyControl(
            choices=["meat", "what", "whaaah", "weather", "haha"],
            pointer=INQUIRERPY_POINTER_SEQUENCE,
            marker=INQUIRERPY_POINTER_SEQUENCE,
            current_text=lambda: "aa",
            max_lines=80,
            session_result=None,
            multiselect=False,
            marker_pl=" ",
            match_exact=True,
        )
        self.assertEqual(
            content_control._filtered_choices,
            [
                {
                    "enabled": False,
                    "index": 0,
                    "indices": [],
                    "name": "meat",
                    "value": "meat",
                },
                {
                    "enabled": False,
                    "index": 1,
                    "indices": [],
                    "name": "what",
                    "value": "what",
                },
                {
                    "enabled": False,
                    "index": 2,
                    "indices": [],
                    "name": "whaaah",
                    "value": "whaaah",
                },
                {
                    "enabled": False,
                    "index": 3,
                    "indices": [],
                    "name": "weather",
                    "value": "weather",
                },
                {
                    "enabled": False,
                    "index": 4,
                    "indices": [],
                    "name": "haha",
                    "value": "haha",
                },
            ],
        )
        result = asyncio.run(content_control._filter_choices(0.0))
        self.assertEqual(
            result,
            [{
                "enabled": False,
                "index": 2,
                "indices": [2, 3],
                "name": "whaaah",
                "value": "whaaah",
            }],
        )

    def test_toggle_exact(self):
        self.assertEqual(self.prompt.content_control._scorer, fzy_scorer)
        self.prompt._toggle_exact(None)
        self.assertEqual(self.prompt.content_control._scorer, substr_scorer)
        self.prompt._toggle_exact(None)
        self.assertEqual(self.prompt.content_control._scorer, fzy_scorer)
        self.prompt._toggle_exact(None, True)
        self.assertEqual(self.prompt.content_control._scorer, substr_scorer)
        self.prompt._toggle_exact(None, False)
        self.assertEqual(self.prompt.content_control._scorer, fzy_scorer)