Skip to content

Commit e3930e1

Browse files
committed
Figured out how to test piped input without hacking stdin
1 parent ae42c7c commit e3930e1

File tree

1 file changed

+41
-82
lines changed

1 file changed

+41
-82
lines changed

tests/test_cmd2.py

Lines changed: 41 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,6 @@ def test_eos(base_app):
13691369
# And make sure it reduced the length of the script dir list
13701370
assert len(base_app._script_dir) == 0
13711371

1372-
13731372
def test_echo(capsys):
13741373
app = cmd2.Cmd()
13751374
# Turn echo on and pre-stage some commands in the queue, simulating like we are in the middle of a script
@@ -1390,112 +1389,72 @@ def test_echo(capsys):
13901389
assert app._current_script_dir is None
13911390
assert out.startswith('{}{}\n'.format(app.prompt, command) + 'history [arg]: lists past commands issued')
13921391

1393-
def test_piped_input_echo_false_rawinput_false(capsys):
1394-
command = 'set'
1395-
1396-
# mock up the input
1397-
fakein = io.StringIO(command)
1392+
# the next helper function and two tests check for piped
1393+
# input when use_rawinput is True.
1394+
#
1395+
# the only way to make this testable is to mock the builtin input()
1396+
# function
1397+
def piped_input_rawinput_true(capsys, echo, command):
1398+
m = mock.Mock(name='input', side_effect=[command, 'quit'])
1399+
sm.input = m
13981400

1399-
# run the cmdloop, which should pull input from stdin
1400-
app = cmd2.Cmd(stdin=fakein)
1401-
app.use_rawinput = False
1402-
app.echo = False
1401+
# run the cmdloop, which should pull input from our mocked input_list
1402+
app = cmd2.Cmd()
1403+
app.use_rawinput = True
1404+
app.echo = echo
14031405
app.abbrev = False
14041406
app._cmdloop()
14051407
out, err = capsys.readouterr()
1408+
return (app, out)
1409+
1410+
def test_piped_input_rawinput_true_echo_true(capsys):
1411+
command = 'set'
1412+
app, out = piped_input_rawinput_true(capsys, True, command)
1413+
out = out.splitlines()
1414+
assert out[0] == '{}{}'.format(app.prompt, command)
1415+
assert out[1] == 'abbrev: False'
14061416

1417+
def test_piped_input_rawinput_true_echo_false(capsys):
1418+
command = 'set'
1419+
app, out = piped_input_rawinput_true(capsys, False, command)
14071420
firstline = out.splitlines()[0]
14081421
assert firstline == 'abbrev: False'
14091422
assert not '{}{}'.format(app.prompt, command) in out
14101423

1424+
# the next helper function and two tests check for piped
1425+
# input when use_rawinput is False
14111426
#
1412-
# WARNING:
1413-
#
1414-
# this test passes, and validates the proper behavior of
1415-
# cmd2.pseudo_raw_input() when use_rawinput = True
1416-
#
1417-
# However, there is only one way to patch/mock/hack input()
1418-
# or raw_input() for testing: that is to change the
1419-
# sys.stdin file descriptor. This results in unpredictable
1420-
# failures when 'pytest -n8' parallelizes tests.
1421-
#
1422-
# @pytest.mark.parametrize('rawinput', [True, False])
1423-
# def test_piped_input_echo_false_stdin_hack(capsys, rawinput):
1424-
# command = 'set'
1425-
#
1426-
# # hack up stdin
1427-
# fakein = io.StringIO(command)
1428-
# realin = sys.stdin
1429-
# sys.stdin = fakein
1430-
#
1431-
# # run the cmdloop, which should pull input from stdin
1432-
# app = cmd2.Cmd(stdin=fakein)
1433-
# app.use_rawinput = rawinput
1434-
# app.echo = False
1435-
# app.abbrev = False
1436-
# app._cmdloop()
1437-
# out, err = capsys.readouterr()
1438-
#
1439-
# # put stdin back
1440-
# sys.stdin = realin
1441-
#
1442-
# firstline = out.splitlines()[0]
1443-
# assert firstline == 'abbrev: False'
1444-
# assert not '{}{}'.format(app.prompt, command) in out
1445-
1446-
def test_piped_input_echo_true_rawinput_false(capsys):
1447-
command = 'set'
1448-
1427+
# the only way to make this testable is to pass a file handle
1428+
# as stdin
1429+
def piped_input_rawinput_false(capsys, echo, command):
14491430
# mock up the input
14501431
fakein = io.StringIO(command)
14511432

14521433
# run the cmdloop, which should pull input from stdin
14531434
app = cmd2.Cmd(stdin=fakein)
14541435
app.use_rawinput = False
1455-
app.echo = True
1436+
app.echo = echo
14561437
app.abbrev = False
14571438
app._cmdloop()
14581439
out, err = capsys.readouterr()
1440+
return (app, out)
14591441

1442+
def test_piped_input_rawinput_false_echo_true(capsys):
1443+
command = 'set'
1444+
app, out = piped_input_rawinput_false(capsys, True, command)
14601445
out = out.splitlines()
14611446
assert out[0] == '{}{}'.format(app.prompt, command)
14621447
assert out[1] == 'abbrev: False'
14631448

1464-
#
1465-
# WARNING:
1466-
#
1467-
# this test passes, and validates the proper behavior of
1468-
# cmd2.pseudo_raw_input() when use_rawinput = True
1469-
#
1470-
# However, there is only one way to patch/mock/hack input()
1471-
# or raw_input() for testing: that is to change the
1472-
# sys.stdin file descriptor. This results in unpredictable
1473-
# failures when 'pytest -n8' parallelizes tests.
1474-
#
1475-
# @pytest.mark.parametrize('rawinput', [True, False])
1476-
# def test_piped_input_echo_true_stdin_hack(capsys, rawinput):
1477-
# command = 'set'
1478-
#
1479-
# # hack up stdin
1480-
# fakein = io.StringIO(command)
1481-
# realin = sys.stdin
1482-
# sys.stdin = fakein
1483-
#
1484-
# # run the cmdloop, which should pull input from stdin
1485-
# app = cmd2.Cmd()
1486-
# app.use_rawinput = rawinput
1487-
# app.echo = True
1488-
# app.abbrev = False
1489-
# app._cmdloop()
1490-
# out, err = capsys.readouterr()
1491-
#
1492-
# # put stdin back
1493-
# sys.stdin = realin
1494-
#
1495-
# out = out.splitlines()
1496-
# assert out[0] == '{}{}'.format(app.prompt, command)
1497-
# assert out[1] == 'abbrev: False'
1449+
def test_piped_input_rawinput_false_echo_false(capsys):
1450+
command = 'set'
1451+
app, out = piped_input_rawinput_false(capsys, False, command)
1452+
firstline = out.splitlines()[0]
1453+
assert firstline == 'abbrev: False'
1454+
assert not '{}{}'.format(app.prompt, command) in out
14981455

1456+
#
1457+
# other input tests
14991458
def test_raw_input(base_app):
15001459
base_app.use_raw_input = True
15011460
fake_input = 'quit'

0 commit comments

Comments
 (0)