File: test_jupyter_widget.py

package info (click to toggle)
python-qtconsole 5.6.1-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,184 kB
  • sloc: python: 7,222; makefile: 180; sh: 36
file content (120 lines) | stat: -rw-r--r-- 5,207 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import unittest
import sys

import pytest
from qtpy import QT6
from qtpy import QtWidgets, QtGui

from qtconsole.jupyter_widget import JupyterWidget

from . import no_display


@pytest.mark.skipif(no_display, reason="Doesn't work without a display")
class TestJupyterWidget(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        """ Create the application for the test case.
        """
        cls._app = QtWidgets.QApplication.instance()
        if cls._app is None:
            cls._app = QtWidgets.QApplication([])
        cls._app.setQuitOnLastWindowClosed(False)

    @classmethod
    def tearDownClass(cls):
        """ Exit the application.
        """
        QtWidgets.QApplication.quit()

    def test_stylesheet_changed(self):
        """ Test changing stylesheets.
        """
        w = JupyterWidget(kind='rich')

        # By default, the background is light. White text is rendered as black
        self.assertEqual(w._ansi_processor.get_color(15).name(), '#000000')

        # Color code 40
        self.assertEqual(w._ansi_processor.get_color(40).name(), '#00d700')
        
        # Change to a dark colorscheme. White text is rendered as white
        w.syntax_style = 'monokai'
        self.assertEqual(w._ansi_processor.get_color(15).name(), '#ffffff')
        
        # Color code 40 with monokai
        self.assertEqual(w._ansi_processor.get_color(40).name(), '#00d700')

    @pytest.mark.skipif(not sys.platform.startswith('linux'),
                        reason="Works only on Linux")
    def test_other_output(self):
        """ Test displaying output from other clients.
        """
        w = JupyterWidget(kind='rich')
        w._append_plain_text('Header\n')
        w._show_interpreter_prompt(1)
        w.other_output_prefix = '[other] '
        w.syntax_style = 'default'

        msg = dict(
            execution_count=1,
            code='a = 1 + 1\nb = range(10)',
        )
        w._append_custom(w._insert_other_input, msg, before_prompt=True)

        control = w._control
        document = control.document()

        self.assertEqual(document.blockCount(), 6)
        self.assertEqual(document.toPlainText(), (
            'Header\n'
            '\n'
            '[other] In [1]: a = 1 + 1\n'
            '           ...: b = range(10)\n'
            '\n'
            'In [2]: '
        ))

        # Check proper syntax highlighting.
        # This changes with every Qt6 release, that's why we don't test it on it.
        if not QT6:
            html = (
                '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">\n'
                '<html><head><meta name="qrichtext" content="1" /><style type="text/css">\n'
                'p, li { white-space: pre-wrap; }\n'
                '</style></head><body style=" font-family:\'Monospace\'; font-size:9pt; font-weight:400; font-style:normal;">\n'
                '<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Header</p>\n'
                '<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>\n'
                '<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#000080;">[other] In [</span><span style=" font-weight:600; color:#000080;">1</span><span style=" color:#000080;">]:</span> a = 1 + 1</p>\n'
                '<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#000080;">\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0...:</span> b = range(10)</p>\n'
                '<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>\n'
                '<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#000080;">In [</span><span style=" font-weight:600; color:#000080;">2</span><span style=" color:#000080;">]:</span> </p></body></html>'
            )
        
            self.assertEqual(document.toHtml(), html)

    def test_copy_paste_prompt(self):
        """Test copy/paste removes partial and full prompts."""
        w = JupyterWidget(kind='rich')
        w._show_interpreter_prompt(1)
        control = w._control

        code = "    if True:\n        print('a')"
        w._set_input_buffer(code)
        assert code not in control.toPlainText()

        cursor = w._get_prompt_cursor()

        pos = cursor.position()
        cursor.setPosition(pos - 3)
        cursor.movePosition(QtGui.QTextCursor.End,
                            QtGui.QTextCursor.KeepAnchor)
        control.setTextCursor(cursor)
        control.hasFocus = lambda: True
        w.copy()
        clipboard = QtWidgets.QApplication.clipboard()
        assert clipboard.text() == code
        w.paste()
        expected = "In [1]: if True:\n   ...:     print('a')"
        assert expected in control.toPlainText()