1"""Test embedding of IPython"""
2
3#-----------------------------------------------------------------------------
4#  Copyright (C) 2013 The IPython Development Team
5#
6#  Distributed under the terms of the BSD License.  The full license is in
7#  the file COPYING, distributed as part of this software.
8#-----------------------------------------------------------------------------
9
10#-----------------------------------------------------------------------------
11# Imports
12#-----------------------------------------------------------------------------
13
14import os
15import subprocess
16import sys
17import nose.tools as nt
18from IPython.utils.tempdir import NamedFileInTemporaryDirectory
19from IPython.testing.decorators import skip_win32
20
21#-----------------------------------------------------------------------------
22# Tests
23#-----------------------------------------------------------------------------
24
25
26_sample_embed = b"""
27from __future__ import print_function
28import IPython
29
30a = 3
31b = 14
32print(a, '.', b)
33
34IPython.embed()
35
36print('bye!')
37"""
38
39_exit = b"exit\r"
40
41def test_ipython_embed():
42    """test that `IPython.embed()` works"""
43    with NamedFileInTemporaryDirectory('file_with_embed.py') as f:
44        f.write(_sample_embed)
45        f.flush()
46        f.close() # otherwise msft won't be able to read the file
47
48        # run `python file_with_embed.py`
49        cmd = [sys.executable, f.name]
50        env = os.environ.copy()
51        env['IPY_TEST_SIMPLE_PROMPT'] = '1'
52
53        p = subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE,
54                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55        out, err = p.communicate(_exit)
56        std = out.decode('UTF-8')
57
58        nt.assert_equal(p.returncode, 0)
59        nt.assert_in('3 . 14', std)
60        if os.name != 'nt':
61            # TODO: Fix up our different stdout references, see issue gh-14
62            nt.assert_in('IPython', std)
63        nt.assert_in('bye!', std)
64
65@skip_win32
66def test_nest_embed():
67    """test that `IPython.embed()` is nestable"""
68    import pexpect
69    ipy_prompt = r']:' #ansi color codes give problems matching beyond this
70    env = os.environ.copy()
71    env['IPY_TEST_SIMPLE_PROMPT'] = '1'
72
73
74    child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor'],
75                          env=env)
76    child.expect(ipy_prompt)
77    child.sendline("from __future__ import print_function")
78    child.expect(ipy_prompt)
79    child.sendline("import IPython")
80    child.expect(ipy_prompt)
81    child.sendline("ip0 = get_ipython()")
82    #enter first nested embed
83    child.sendline("IPython.embed()")
84    #skip the banner until we get to a prompt
85    try:
86        prompted = -1
87        while prompted != 0:
88            prompted = child.expect([ipy_prompt, '\r\n'])
89    except pexpect.TIMEOUT as e:
90        print(e)
91        #child.interact()
92    child.sendline("embed1 = get_ipython()"); child.expect(ipy_prompt)
93    child.sendline("print('true' if embed1 is not ip0 else 'false')")
94    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
95    child.expect(ipy_prompt)
96    child.sendline("print('true' if IPython.get_ipython() is embed1 else 'false')")
97    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
98    child.expect(ipy_prompt)
99    #enter second nested embed
100    child.sendline("IPython.embed()")
101    #skip the banner until we get to a prompt
102    try:
103        prompted = -1
104        while prompted != 0:
105            prompted = child.expect([ipy_prompt, '\r\n'])
106    except pexpect.TIMEOUT as e:
107        print(e)
108        #child.interact()
109    child.sendline("embed2 = get_ipython()"); child.expect(ipy_prompt)
110    child.sendline("print('true' if embed2 is not embed1 else 'false')")
111    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
112    child.expect(ipy_prompt)
113    child.sendline("print('true' if embed2 is IPython.get_ipython() else 'false')")
114    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
115    child.expect(ipy_prompt)
116    child.sendline('exit')
117    #back at first embed
118    child.expect(ipy_prompt)
119    child.sendline("print('true' if get_ipython() is embed1 else 'false')")
120    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
121    child.expect(ipy_prompt)
122    child.sendline("print('true' if IPython.get_ipython() is embed1 else 'false')")
123    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
124    child.expect(ipy_prompt)
125    child.sendline('exit')
126    #back at launching scope
127    child.expect(ipy_prompt)
128    child.sendline("print('true' if get_ipython() is ip0 else 'false')")
129    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
130    child.expect(ipy_prompt)
131    child.sendline("print('true' if IPython.get_ipython() is ip0 else 'false')")
132    assert(child.expect(['true\r\n', 'false\r\n']) == 0)
133    child.expect(ipy_prompt)
134    child.sendline('exit')
135    child.close()
136