summaryrefslogtreecommitdiff
path: root/tests/test_replwrap.py
blob: 5e50ea28b3369b7fd3317149196b3a6c1c1063e2 (plain)
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
121
122
123
import platform
import unittest
import re
import os
import sys

import pexpect
from pexpect import replwrap

skip_pypy = "This test fails on PyPy because of REPL differences"


class REPLWrapTestCase(unittest.TestCase):
    def setUp(self):
        super(REPLWrapTestCase, self).setUp()
        self.save_ps1 = os.getenv('PS1', r'\$')
        self.save_ps2 = os.getenv('PS2', '>')
        os.putenv('PS1', r'\$')
        os.putenv('PS2', '>')

    def tearDown(self):
        super(REPLWrapTestCase, self).tearDown()
        os.putenv('PS1', self.save_ps1)
        os.putenv('PS2', self.save_ps2)

    def test_bash(self):
        bash = replwrap.bash()
        res = bash.run_command("alias")
        assert 'alias' in res, res

        try:
            bash.run_command('')
        except ValueError:
            pass
        else:
            assert False, "Didn't raise ValueError for empty input"

    def test_pager_as_cat(self):
        " PAGER is set to cat, to prevent timeout in ``man sleep``. "
        bash = replwrap.bash()
        res = bash.run_command('man sleep', timeout=5)
        assert 'SLEEP' in res, res

    def test_bash_env(self):
        """env, which displays PS1=..., should not mess up finding the prompt.
        """
        bash = replwrap.bash()
        res = bash.run_command("export PS1")
        res = bash.run_command("env")
        self.assertIn('PS1', res)
        res = bash.run_command("echo $HOME")
        assert res.startswith('/'), res

    def test_long_running_multiline(self):
        " ensure the default timeout is used for multi-line commands. "
        bash = replwrap.bash()
        res = bash.run_command("echo begin\r\nsleep 2\r\necho done")
        self.assertEqual(res.strip().splitlines(), ['begin', 'done'])

    def test_long_running_continuation(self):
        " also ensure timeout when used within continuation prompts. "
        bash = replwrap.bash()
        # The two extra '\\' in the following expression force a continuation
        # prompt:
        # $ echo begin\
        #     + ;
        # $ sleep 2
        # $ echo done
        res = bash.run_command("echo begin\\\n;sleep 2\r\necho done")
        self.assertEqual(res.strip().splitlines(), ['begin', 'done'])

    def test_multiline(self):
        bash = replwrap.bash()
        res = bash.run_command("echo '1 2\n3 4'")
        self.assertEqual(res.strip().splitlines(), ['1 2', '3 4'])

        # Should raise ValueError if input is incomplete
        try:
            bash.run_command("echo '5 6")
        except ValueError:
            pass
        else:
            assert False, "Didn't raise ValueError for incomplete input"

        # Check that the REPL was reset (SIGINT) after the incomplete input
        res = bash.run_command("echo '1 2\n3 4'")
        self.assertEqual(res.strip().splitlines(), ['1 2', '3 4'])

    def test_existing_spawn(self):
        child = pexpect.spawn("bash", timeout=5, encoding='utf-8')
        repl = replwrap.REPLWrapper(child, re.compile('[$#]'),
                                    "PS1='{0}' PS2='{1}' "
                                    "PROMPT_COMMAND=''")

        res = repl.run_command("echo $HOME")
        assert res.startswith('/'), res

    def test_python(self):
        if platform.python_implementation() == 'PyPy':
            raise unittest.SkipTest(skip_pypy)

        p = replwrap.python()
        res = p.run_command('4+7')
        assert res.strip() == '11'

        res = p.run_command('for a in range(3): print(a)\n')
        assert res.strip().splitlines() == ['0', '1', '2']

    def test_no_change_prompt(self):
        if platform.python_implementation() == 'PyPy':
            raise unittest.SkipTest(skip_pypy)

        child = pexpect.spawn(sys.executable, echo=False, timeout=5, encoding='utf-8')
        # prompt_change=None should mean no prompt change
        py = replwrap.REPLWrapper(child, u">>> ", prompt_change=None,
                                  continuation_prompt=u"... ")
        assert py.prompt == ">>> "

        res = py.run_command("for a in range(3): print(a)\n")
        assert res.strip().splitlines() == ['0', '1', '2']

if __name__ == '__main__':
    unittest.main()