Example #1
0
    def test_search_message(
        self,
        initial_narrow: List[Any],
        final_narrow: List[Any],
        controller: Controller,
        mocker: MockerFixture,
        msg_ids: Set[int],
        index_search_messages: Index,
    ) -> None:
        get_message = mocker.patch(MODEL + ".get_messages")
        create_msg = mocker.patch(MODULE + ".create_msg_box_list")
        mocker.patch(MODEL + ".get_message_ids_in_current_narrow", return_value=msg_ids)
        controller.model.index = index_search_messages  # Any initial search index
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.narrow = initial_narrow

        def set_msg_ids(*args: Any, **kwargs: Any) -> None:
            controller.model.index["search"].update(msg_ids)

        get_message.side_effect = set_msg_ids
        assert controller.model.index["search"] == {500}

        controller.search_messages("FOO")

        assert controller.model.narrow == final_narrow
        get_message.assert_called_once_with(
            num_after=0, num_before=30, anchor=10000000000
        )
        create_msg.assert_called_once_with(controller.model, msg_ids)
        assert controller.model.index == dict(
            index_search_messages, **{"search": msg_ids}
        )
Example #2
0
    def test_narrow_to_user(
        self,
        mocker: MockerFixture,
        controller: Controller,
        index_user: Index,
        user_email: str = "*****@*****.**",
        user_id: int = 5179,
    ) -> None:
        controller.model.narrow = []
        controller.model.index = index_user
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.user_id = 5140
        controller.model.user_email = "some@email"
        controller.model.user_dict = {user_email: {"user_id": user_id}}

        emails = [user_email]

        controller.narrow_to_user(recipient_emails=emails)

        assert controller.model.narrow == [["pm_with", user_email]]
        controller.view.message_view.log.clear.assert_called_once_with()
        recipients = frozenset([controller.model.user_id, user_id])
        assert controller.model.recipients == recipients
        widget = controller.view.message_view.log.extend.call_args_list[0][0][0][0]
        id_list = index_user["private_msg_ids_by_user_ids"][recipients]
        assert {widget.original_widget.message["id"]} == id_list
Example #3
0
    def test_narrow_to_all_messages(
        self,
        mocker: MockerFixture,
        controller: Controller,
        index_all_messages: Index,
        anchor: Optional[int],
        expected_final_focus_msg_id: int,
    ) -> None:
        controller.model.narrow = [["stream", "PTEST"]]
        controller.model.index = index_all_messages
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.user_email = "some@email"
        controller.model.user_id = 1
        controller.model.stream_dict = {
            205: {
                "color": "#ffffff",
            }
        }
        controller.model.muted_streams = set()
        mocker.patch(MODEL + ".is_muted_topic", return_value=False)

        controller.narrow_to_all_messages(contextual_message_id=anchor)

        assert controller.model.narrow == []
        controller.view.message_view.log.clear.assert_called_once_with()

        widgets, focus = controller.view.message_view.log.extend.call_args_list[0][0]
        id_list = index_all_messages["all_msg_ids"]
        msg_ids = {widget.original_widget.message["id"] for widget in widgets}
        final_focus_msg_id = widgets[focus].original_widget.message["id"]
        assert msg_ids == id_list
        assert final_focus_msg_id == expected_final_focus_msg_id
Example #4
0
    def test_narrow_to_stream(
        self,
        mocker: MockerFixture,
        controller: Controller,
        index_stream: Index,
        stream_id: int = 205,
        stream_name: str = "PTEST",
    ) -> None:
        controller.model.narrow = []
        controller.model.index = index_stream
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.stream_dict = {
            stream_id: {
                "color": "#ffffff",
                "name": stream_name,
            }
        }
        controller.model.muted_streams = set()
        mocker.patch(MODEL + ".is_muted_topic", return_value=False)

        controller.narrow_to_stream(stream_name=stream_name)

        assert controller.model.stream_id == stream_id
        assert controller.model.narrow == [["stream", stream_name]]
        controller.view.message_view.log.clear.assert_called_once_with()

        widget = controller.view.message_view.log.extend.call_args_list[0][0][0][0]
        id_list = index_stream["stream_msg_ids_by_stream_id"][stream_id]
        assert {widget.original_widget.message["id"]} == id_list
Example #5
0
    def test_show_typing_notification(
        self,
        mocker: MockerFixture,
        controller: Controller,
        active_conversation_info: Dict[str, str],
    ) -> None:
        set_footer_text = mocker.patch(VIEW + ".set_footer_text")
        sleep = mocker.patch(MODULE + ".time.sleep")
        controller.active_conversation_info = active_conversation_info

        def mock_typing() -> None:
            controller.active_conversation_info = {}

        Timer(0.1, mock_typing).start()
        Thread(controller.show_typing_notification()).start()

        if active_conversation_info:
            set_footer_text.assert_has_calls(
                [
                    mocker.call([("footer_contrast", " hamlet "), " is typing"]),
                    mocker.call([("footer_contrast", " hamlet "), " is typing."]),
                    mocker.call([("footer_contrast", " hamlet "), " is typing.."]),
                    mocker.call([("footer_contrast", " hamlet "), " is typing..."]),
                ]
            )
            set_footer_text.assert_called_with()
        else:
            set_footer_text.assert_called_once_with()
        assert controller.is_typing_notification_in_progress is False
        assert controller.active_conversation_info == {}
Example #6
0
    def test_editor_mode_exits_after_entering(
        self, mocker: MockerFixture, controller: Controller
    ) -> None:
        controller.enter_editor_mode_with(mocker.Mock())
        controller.exit_editor_mode()

        assert not controller.is_in_editor_mode()
Example #7
0
    def test_editor_mode_error_on_multiple_enter(
        self, mocker: MockerFixture, controller: Controller
    ) -> None:
        controller.enter_editor_mode_with(mocker.Mock())

        with pytest.raises(AssertionError):
            controller.enter_editor_mode_with(mocker.Mock())
Example #8
0
    def test_narrow_to_all_mentions(
        self, mocker: MockerFixture, controller: Controller, index_all_mentions: Index
    ) -> None:
        controller.model.narrow = []
        controller.model.index = index_all_mentions
        controller.model.muted_streams = set()  # FIXME Expand upon this
        # FIXME: Expand upon is_muted_topic().
        mocker.patch(MODEL + ".is_muted_topic", return_value=False)
        controller.model.user_email = "some@email"
        controller.model.user_id = 1
        controller.model.stream_dict = {
            205: {
                "color": "#ffffff",
            }
        }
        controller.view.message_view = mocker.patch("urwid.ListBox")

        controller.narrow_to_all_mentions()  # FIXME: Add id narrowing test

        assert controller.model.narrow == [["is", "mentioned"]]
        controller.view.message_view.log.clear.assert_called_once_with()

        id_list = index_all_mentions["mentioned_msg_ids"]
        widgets = controller.view.message_view.log.extend.call_args_list[0][0][0]
        msg_ids = {widget.original_widget.message["id"] for widget in widgets}
        assert msg_ids == id_list
Example #9
0
    def test_main(self, mocker: MockerFixture, controller: Controller) -> None:
        controller.view.palette = {"default": "theme_properties"}
        mock_tsk = mocker.patch(MODULE + ".Screen.tty_signal_keys")
        controller.loop.screen.tty_signal_keys = mocker.Mock(return_value={})

        controller.main()

        assert controller.loop.run.call_count == 1
Example #10
0
    def test_editor_mode_entered_from_initial(
        self, mocker: MockerFixture, controller: Controller
    ) -> None:
        editor = mocker.Mock()

        controller.enter_editor_mode_with(editor)

        assert controller.is_in_editor_mode()
        assert controller.current_editor() == editor
Example #11
0
    def test_open_in_browser_fail__no_browser_controller(
        self, mocker: MockerFixture, controller: Controller
    ) -> None:
        os.environ["DISPLAY"] = ":0"
        error = "No runnable browser found"
        mocked_report_error = mocker.patch(MODULE + ".Controller.report_error")
        mocker.patch(MODULE + ".webbrowser.get").side_effect = webbrowser.Error(error)

        controller.open_in_browser("https://chat.zulip.org/#narrow/stream/test")

        mocked_report_error.assert_called_once_with(f"ERROR: {error}")
Example #12
0
    def test_open_in_browser_success(
        self, mocker: MockerFixture, controller: Controller, url: str
    ) -> None:
        # Set DISPLAY environ to be able to run test in CI
        os.environ["DISPLAY"] = ":0"
        mocked_report_success = mocker.patch(MODULE + ".Controller.report_success")
        mock_get = mocker.patch(MODULE + ".webbrowser.get")
        mock_open = mock_get.return_value.open

        controller.open_in_browser(url)

        mock_open.assert_called_once_with(url)
        mocked_report_success.assert_called_once_with(
            f"The link was successfully opened using {mock_get.return_value.name}"
        )
Example #13
0
    def test_copy_to_clipboard_exception(
        self, mocker: MockerFixture, controller: Controller, text_category: str = "Test"
    ) -> None:
        popup = mocker.patch(MODULE + ".Controller.show_pop_up")
        mocker.patch(
            MODULE + ".pyperclip.copy", side_effect=pyperclip.PyperclipException()
        )
        mocker.patch(
            MODULE + ".Controller.maximum_popup_dimensions", return_value=(64, 64)
        )

        controller.copy_to_clipboard("copy text", text_category)

        popup.assert_called_once()
        assert popup.call_args_list[0][0][1] == "area:error"
Example #14
0
 def test_register(self, mocker):
     self.config_file = 'path/to/zuliprc'
     self.theme = 'default'
     controller = Controller(self.config_file, self.theme)
     event_types = ['message', 'update_message', 'reaction']
     controller.client.register.assert_called_once_with(
         event_types=event_types)
Example #15
0
    def controller(self, mocker: MockerFixture) -> Controller:
        # Patch these unconditionally to avoid calling in __init__
        self.poll_for_events = mocker.patch(MODEL + ".poll_for_events")
        mocker.patch(MODULE + ".Controller.show_loading")
        self.main_loop = mocker.patch(
            MODULE + ".urwid.MainLoop", return_value=mocker.Mock()
        )

        self.config_file = "path/to/zuliprc"
        self.theme_name = "zt_dark"
        self.theme = generate_theme("zt_dark", 256)
        self.in_explore_mode = False
        self.autohide = True  # FIXME Add tests for no-autohide
        self.notify_enabled = False
        self.maximum_footlinks = 3
        result = Controller(
            config_file=self.config_file,
            maximum_footlinks=self.maximum_footlinks,
            theme_name=self.theme_name,
            theme=self.theme,
            color_depth=256,
            in_explore_mode=self.in_explore_mode,
            debug_path=None,
            **dict(
                autohide=self.autohide,
                notify=self.notify_enabled,
            ),
        )
        result.view.message_view = mocker.Mock()  # set in View.__init__
        result.model.server_url = SERVER_URL
        return result
Example #16
0
    def controller(self, mocker) -> None:
        # Patch these unconditionally to avoid calling in __init__
        self.poll_for_events = mocker.patch(CORE + ".Model.poll_for_events")
        mocker.patch(CORE + ".Controller.show_loading")
        self.main_loop = mocker.patch(CORE + ".urwid.MainLoop",
                                      return_value=mocker.Mock())

        self.config_file = "path/to/zuliprc"
        self.theme_name = "zt_dark"
        self.theme = "default"
        self.in_explore_mode = False
        self.autohide = True  # FIXME Add tests for no-autohide
        self.notify_enabled = False
        self.maximum_footlinks = 3
        result = Controller(
            self.config_file,
            self.maximum_footlinks,
            self.theme_name,
            self.theme,
            256,
            self.in_explore_mode,
            self.autohide,
            self.notify_enabled,
        )
        result.view.message_view = mocker.Mock()  # set in View.__init__
        result.model.server_url = SERVER_URL
        return result
Example #17
0
 def controller(self, mocker) -> None:
     self.config_file = 'path/to/zuliprc'
     self.theme = 'default'
     self.autohide = True  # FIXME Add tests for no-autohide
     self.notify_enabled = False
     return Controller(self.config_file, self.theme, 256, self.autohide,
                       self.notify_enabled)
Example #18
0
def main():
    """
    Launch Zulip Terminal.
    """
    args = parse_args()
    if args.debug:
        save_stdout()
    if args.profile:
        import cProfile
        prof = cProfile.Profile()
        prof.enable()

    try:
        Controller(args.config_file, args.theme).main()
    except Exception:
        # A unexpected exception occurred, open the debugger in debug mode
        if args.debug:
            import pudb
            pudb.post_mortem()
    finally:
        if args.debug:
            restore_stdout()

        if args.profile:
            prof.disable()
            prof.dump_stats("/tmp/profile.data")
            print("Profile data saved to /tmp/profile.data")
            print("You can visualize it using e.g."
                  "`snakeviz /tmp/profile.data`")

        print("\nThanks for using the Zulip-Terminal interface.\n")
        sys.exit(1)
Example #19
0
    def test_narrow_to_topic(
        self,
        mocker: MockerFixture,
        controller: Controller,
        index_multiple_topic_msg: Index,
        initial_narrow: List[Any],
        initial_stream_id: Optional[int],
        anchor: Optional[int],
        expected_final_focus: int,
        stream_name: str = "PTEST",
        topic_name: str = "Test",
        stream_id: int = 205,
    ) -> None:
        expected_narrow = [
            ["stream", stream_name],
            ["topic", topic_name],
        ]
        controller.model.narrow = initial_narrow
        controller.model.index = index_multiple_topic_msg
        controller.model.stream_id = initial_stream_id
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.stream_dict = {
            stream_id: {
                "color": "#ffffff",
                "name": stream_name,
            }
        }
        controller.model.muted_streams = set()
        mocker.patch(MODEL + ".is_muted_topic", return_value=False)

        controller.narrow_to_topic(
            stream_name=stream_name,
            topic_name=topic_name,
            contextual_message_id=anchor,
        )

        assert controller.model.stream_id == stream_id
        assert controller.model.narrow == expected_narrow
        controller.view.message_view.log.clear.assert_called_once_with()

        widgets, focus = controller.view.message_view.log.extend.call_args_list[0][0]
        id_list = index_multiple_topic_msg["topic_msg_ids"][stream_id][topic_name]
        msg_ids = {widget.original_widget.message["id"] for widget in widgets}
        final_focus_msg_id = widgets[focus].original_widget.message["id"]
        assert msg_ids == id_list
        assert final_focus_msg_id == expected_final_focus
Example #20
0
    def test_narrow_to_all_pm(
        self, mocker: MockerFixture, controller: Controller, index_user: Index
    ) -> None:
        controller.model.narrow = []
        controller.model.index = index_user
        controller.view.message_view = mocker.patch("urwid.ListBox")
        controller.model.user_id = 1
        controller.model.user_email = "some@email"

        controller.narrow_to_all_pm()  # FIXME: Add id narrowing test

        assert controller.model.narrow == [["is", "private"]]
        controller.view.message_view.log.clear.assert_called_once_with()

        widgets = controller.view.message_view.log.extend.call_args_list[0][0][0]
        id_list = index_user["private_msg_ids"]
        msg_ids = {widget.original_widget.message["id"] for widget in widgets}
        assert msg_ids == id_list
Example #21
0
    def test_maximum_popup_dimensions(
        self,
        mocker: MockerFixture,
        controller: Controller,
        screen_size: Tuple[int, int],
        expected_popup_size: Tuple[int, int],
    ) -> None:
        controller.loop.screen.get_cols_rows = mocker.Mock(return_value=screen_size)

        popup_size = controller.maximum_popup_dimensions()

        assert popup_size == expected_popup_size
Example #22
0
 def test_register_initial_desired_events(self, mocker):
     self.config_file = 'path/to/zuliprc'
     self.theme = 'default'
     controller = Controller(self.config_file, self.theme)
     event_types = [
         'message',
         'update_message',
         'reaction',
         'typing',
     ]
     controller.client.register.assert_called_once_with(
         event_types=event_types, apply_markdown=True)
Example #23
0
    def test_stream_muting_confirmation_popup(
        self,
        mocker: MockerFixture,
        controller: Controller,
        muted_streams: Set[int],
        action: str,
        stream_id: int = 205,
        stream_name: str = "PTEST",
    ) -> None:
        pop_up = mocker.patch(MODULE + ".PopUpConfirmationView")
        text = mocker.patch(MODULE + ".urwid.Text")
        partial = mocker.patch(MODULE + ".partial")
        controller.model.muted_streams = muted_streams
        controller.loop = mocker.Mock()

        controller.stream_muting_confirmation_popup(stream_id, stream_name)

        text.assert_called_with(
            ("bold", f"Confirm {action} of stream '{stream_name}' ?"),
            "center",
        )
        pop_up.assert_called_once_with(controller, text(), partial())
Example #24
0
    def controller(self, mocker) -> None:
        # Patch these unconditionally to avoid calling in __init__
        self.poll_for_events = mocker.patch(CORE + '.Model.poll_for_events')
        mocker.patch(CORE + '.Controller.show_loading')

        self.config_file = 'path/to/zuliprc'
        self.theme = 'default'
        self.autohide = True  # FIXME Add tests for no-autohide
        self.notify_enabled = False
        self.footlinks_enabled = True
        result = Controller(self.config_file, self.theme, 256, self.autohide,
                            self.notify_enabled, self.footlinks_enabled)
        result.view.message_view = mocker.Mock()  # set in View.__init__
        return result
Example #25
0
    def test_copy_to_clipboard_no_exception(
        self,
        text_to_copy: str,
        pasted_text: str,
        expected_result: str,
        mocker: MockerFixture,
        controller: Controller,
        text_category: str = "Test",
    ) -> None:
        mocker.patch(MODULE + ".pyperclip.copy", return_value=None)
        mocker.patch(MODULE + ".pyperclip.paste", return_value=pasted_text)
        mock_success = mocker.patch(MODULE + ".Controller.report_success")
        mock_warning = mocker.patch(MODULE + ".Controller.report_warning")

        controller.copy_to_clipboard(text_to_copy, text_category)

        if expected_result == "success":
            mock_success.assert_called_once_with(f"{text_category} copied successfully")
            mock_warning.assert_not_called()
        else:
            mock_success.assert_not_called()
            mock_warning.assert_called_once_with(
                f"{text_category} copied, but the clipboard text does not match"
            )
Example #26
0
def main() -> None:
    """
    Launch Zulip Terminal.
    """

    args = parse_args()
    if args.config_file:
        zuliprc_path = args.config_file
    else:
        zuliprc_path = '~/zuliprc'

    zterm = parse_zuliprc(zuliprc_path)

    if args.profile:
        import cProfile
        prof = cProfile.Profile()
        prof.enable()

    try:
        Controller(zuliprc_path, zterm['theme']).main()
    except Exception as e:
        if args.debug:
            # A unexpected exception occurred, open the debugger in debug mode
            import pudb
            pudb.post_mortem()

        sys.stdout.flush()
        traceback.print_exc(file=sys.stderr)
        print("Zulip Terminal has crashed!", file=sys.stderr)
        print("You can ask for help at:", file=sys.stderr)
        print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal",
              file=sys.stderr)
        print("\nThanks for using the Zulip-Terminal interface.\n")
        sys.stderr.flush()

    finally:
        if args.profile:
            prof.disable()
            prof.dump_stats("/tmp/profile.data")
            print("Profile data saved to /tmp/profile.data")
            print("You can visualize it using e.g."
                  "`snakeviz /tmp/profile.data`")

        sys.exit(1)
Example #27
0
def main(options: Optional[List[str]] = None) -> None:
    """
    Launch Zulip Terminal.
    """

    argv = options if options is not None else sys.argv[1:]
    args = parse_args(argv)

    if args.profile:
        import cProfile
        prof = cProfile.Profile()
        prof.enable()

    if args.config_file:
        zuliprc_path = args.config_file
    else:
        zuliprc_path = '~/zuliprc'

    try:
        zterm = parse_zuliprc(zuliprc_path)

        if args.theme:
            theme_to_use = (args.theme, 'on command line')
        else:
            theme_to_use = zterm['theme']
        valid_themes = THEMES.keys()
        if theme_to_use[0] not in valid_themes:
            print("Invalid theme '{}' was specified {}.".format(*theme_to_use))
            print("The following themes are available:")
            for theme in valid_themes:
                print("  ", theme)
            print("Specify theme in zuliprc file or override "
                  "using -t/--theme options on command line.")
            sys.exit(1)

        valid_autohide_settings = {'autohide', 'no_autohide'}
        if zterm['autohide'][0] not in valid_autohide_settings:
            print("Invalid autohide setting '{}' was specified {}.".format(
                *zterm['autohide']))
            print("The following options are available:")
            for option in valid_autohide_settings:
                print("  ", option)
            print("Specify the autohide option in zuliprc file.")
            sys.exit(1)
        autohide_setting = (zterm['autohide'][0] == 'autohide')

        print("Loading with:")
        print("   theme '{}' specified {}.".format(*theme_to_use))
        print("   autohide setting '{}' specified {}.".format(
            *zterm['autohide']))
        Controller(zuliprc_path, THEMES[theme_to_use[0]],
                   autohide_setting).main()
    except ServerConnectionFailure as e:
        print("\n\033[91mError connecting to Zulip server: {}.".format(e))
        sys.exit(1)
    except Exception as e:
        if args.debug:
            # A unexpected exception occurred, open the debugger in debug mode
            import pudb
            pudb.post_mortem()

        sys.stdout.flush()
        traceback.print_exc(file=sys.stderr)
        print("Zulip Terminal has crashed!", file=sys.stderr)
        print("You can ask for help at:", file=sys.stderr)
        print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal",
              file=sys.stderr)
        print("\nThanks for using the Zulip-Terminal interface.\n")
        sys.stderr.flush()

    finally:
        if args.profile:
            prof.disable()
            prof.dump_stats("/tmp/profile.data")
            print("Profile data saved to /tmp/profile.data")
            print("You can visualize it using e.g."
                  "`snakeviz /tmp/profile.data`")

        sys.exit(1)
Example #28
0
def main(options: Optional[List[str]] = None) -> None:
    """
    Launch Zulip Terminal.
    """

    argv = options if options is not None else sys.argv[1:]
    args = parse_args(argv)

    set_encoding('utf-8')

    if args.profile:
        import cProfile
        prof = cProfile.Profile()
        prof.enable()

    if args.version:
        print('Zulip Terminal ' + ZT_VERSION)
        sys.exit(0)

    if args.config_file:
        zuliprc_path = args.config_file
    else:
        zuliprc_path = '~/zuliprc'

    try:
        zterm = parse_zuliprc(zuliprc_path)

        if args.theme:
            theme_to_use = (args.theme, 'on command line')
        else:
            theme_to_use = zterm['theme']
        available_themes = all_themes()
        if theme_to_use[0] not in available_themes:
            print("Invalid theme '{}' was specified {}.".format(*theme_to_use))
            print("The following themes are available:")
            for theme in available_themes:
                print("  ", theme)
            print("Specify theme in zuliprc file or override "
                  "using -t/--theme options on command line.")
            sys.exit(1)

        valid_autohide_settings = {'autohide', 'no_autohide'}
        if zterm['autohide'][0] not in valid_autohide_settings:
            print("Invalid autohide setting '{}' was specified {}.".format(
                *zterm['autohide']))
            print("The following options are available:")
            for option in valid_autohide_settings:
                print("  ", option)
            print("Specify the autohide option in zuliprc file.")
            sys.exit(1)
        autohide_setting = (zterm['autohide'][0] == 'autohide')

        print("Loading with:")
        print("   theme '{}' specified {}.".format(*theme_to_use))
        complete, incomplete = complete_and_incomplete_themes()
        if theme_to_use[0] in incomplete:
            print(
                in_color(
                    'yellow', "   WARNING: Incomplete theme; "
                    "results may vary!\n"
                    "      (you could try: {})".format(", ".join(complete))))
        print("   autohide setting '{}' specified {}.".format(
            *zterm['autohide']))
        Controller(zuliprc_path, THEMES[theme_to_use[0]],
                   autohide_setting).main()
    except ServerConnectionFailure as e:
        print(
            in_color('red',
                     "\nError connecting to Zulip server: {}.".format(e)))
        # Acts as separator between logs
        logging.info("\n\n" + str(e) + "\n\n")
        logging.exception(e)
        sys.exit(1)
    except Exception as e:
        logging.info("\n\n" + str(e) + "\n\n")
        logging.exception(e)
        if args.debug:
            sys.stdout.flush()
            traceback.print_exc(file=sys.stderr)
            run_debugger = input("Run Debugger? (y/n): ")
            if run_debugger in ["y", "Y", "yes"]:
                # Open PUDB Debuuger
                import pudb
                pudb.post_mortem()

        if hasattr(e, 'extra_info'):
            print(
                "\n" + in_color("red", e.extra_info),  # type: ignore
                file=sys.stderr)

        print(in_color(
            "red", "\nZulip Terminal has crashed!"
            "\nPlease refer to " + LOG_FILENAME + " for full log of"
            " the error."),
              file=sys.stderr)
        print("You can ask for help at:", file=sys.stderr)
        print("https://chat.zulip.org/#narrow/stream/206-zulip-terminal",
              file=sys.stderr)
        print("\nThanks for using the Zulip-Terminal interface.\n")
        sys.stderr.flush()

    finally:
        if args.profile:
            prof.disable()
            prof.dump_stats("/tmp/profile.data")
            print("Profile data saved to /tmp/profile.data")
            print("You can visualize it using e.g."
                  "`snakeviz /tmp/profile.data`")

        sys.exit(1)
Example #29
0
 def test_current_editor_error_if_no_editor(self, controller: Controller) -> None:
     with pytest.raises(AssertionError):
         controller.current_editor()
Example #30
0
 def test_initial_editor_mode(self, controller: Controller) -> None:
     assert not controller.is_in_editor_mode()