summaryrefslogtreecommitdiff
path: root/tests/test_history.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_history.py')
-rwxr-xr-xtests/test_history.py189
1 files changed, 136 insertions, 53 deletions
diff --git a/tests/test_history.py b/tests/test_history.py
index 6fa16ad8..cba6f3ce 100755
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -9,6 +9,7 @@ import tempfile
import pytest
import cmd2
+
# Python 3.5 had some regressions in the unitest.mock module, so use
# 3rd party mock if available
from cmd2.parsing import StatementParser
@@ -21,44 +22,57 @@ except ImportError:
from unittest import mock
-
#
# readline tests
#
def test_readline_remove_history_item(base_app):
from cmd2.rl_utils import readline
+
assert readline.get_current_history_length() == 0
readline.add_history('this is a test')
assert readline.get_current_history_length() == 1
readline.remove_history_item(0)
assert readline.get_current_history_length() == 0
+
#
# test History() class
#
@pytest.fixture
def hist():
- from cmd2.parsing import Statement
from cmd2.cmd2 import History, HistoryItem
- h = History([HistoryItem(Statement('', raw='first'), 1),
- HistoryItem(Statement('', raw='second'), 2),
- HistoryItem(Statement('', raw='third'), 3),
- HistoryItem(Statement('', raw='fourth'),4)])
+ from cmd2.parsing import Statement
+
+ h = History(
+ [
+ HistoryItem(Statement('', raw='first'), 1),
+ HistoryItem(Statement('', raw='second'), 2),
+ HistoryItem(Statement('', raw='third'), 3),
+ HistoryItem(Statement('', raw='fourth'), 4),
+ ]
+ )
return h
+
@pytest.fixture
def persisted_hist():
- from cmd2.parsing import Statement
from cmd2.cmd2 import History, HistoryItem
- h = History([HistoryItem(Statement('', raw='first'), 1),
- HistoryItem(Statement('', raw='second'), 2),
- HistoryItem(Statement('', raw='third'), 3),
- HistoryItem(Statement('', raw='fourth'),4)])
+ from cmd2.parsing import Statement
+
+ h = History(
+ [
+ HistoryItem(Statement('', raw='first'), 1),
+ HistoryItem(Statement('', raw='second'), 2),
+ HistoryItem(Statement('', raw='third'), 3),
+ HistoryItem(Statement('', raw='fourth'), 4),
+ ]
+ )
h.start_session()
h.append(Statement('', raw='fifth'))
h.append(Statement('', raw='sixth'))
return h
+
def test_history_class_span(hist):
for tryit in ['*', ':', '-', 'all', 'ALL']:
assert hist.span(tryit) == hist
@@ -135,6 +149,7 @@ def test_history_class_span(hist):
with pytest.raises(ValueError):
hist.span(tryit)
+
def test_persisted_history_span(persisted_hist):
for tryit in ['*', ':', '-', 'all', 'ALL']:
assert persisted_hist.span(tryit, include_persisted=True) == persisted_hist
@@ -191,6 +206,7 @@ def test_persisted_history_span(persisted_hist):
with pytest.raises(ValueError):
persisted_hist.span(tryit)
+
def test_history_class_get(hist):
assert hist.get('1').statement.raw == 'first'
assert hist.get(3).statement.raw == 'third'
@@ -217,6 +233,7 @@ def test_history_class_get(hist):
with pytest.raises(TypeError):
hist.get(None)
+
def test_history_str_search(hist):
items = hist.str_search('ir')
assert len(items) == 2
@@ -227,6 +244,7 @@ def test_history_str_search(hist):
assert len(items) == 1
assert items[0].statement.raw == 'fourth'
+
def test_history_regex_search(hist):
items = hist.regex_search('/i.*d/')
assert len(items) == 1
@@ -236,52 +254,59 @@ def test_history_regex_search(hist):
assert len(items) == 1
assert items[0].statement.raw == 'second'
+
def test_history_max_length_zero(hist):
hist.truncate(0)
assert len(hist) == 0
+
def test_history_max_length_negative(hist):
hist.truncate(-1)
assert len(hist) == 0
+
def test_history_max_length(hist):
hist.truncate(2)
assert len(hist) == 2
assert hist.get(1).statement.raw == 'third'
assert hist.get(2).statement.raw == 'fourth'
+
#
# test HistoryItem()
#
@pytest.fixture
def histitem():
- from cmd2.parsing import Statement
from cmd2.history import HistoryItem
- statement = Statement('history',
- raw='help history',
- command='help',
- arg_list=['history'],
- )
+ from cmd2.parsing import Statement
+
+ statement = Statement('history', raw='help history', command='help', arg_list=['history'],)
histitem = HistoryItem(statement, 1)
return histitem
+
@pytest.fixture
def parser():
from cmd2.parsing import StatementParser
+
parser = StatementParser(
terminators=[';', '&'],
multiline_commands=['multiline'],
- aliases={'helpalias': 'help',
- '42': 'theanswer',
- 'l': '!ls -al',
- 'anothermultiline': 'multiline',
- 'fake': 'run_pyscript'},
- shortcuts={'?': 'help', '!': 'shell'}
+ aliases={
+ 'helpalias': 'help',
+ '42': 'theanswer',
+ 'l': '!ls -al',
+ 'anothermultiline': 'multiline',
+ 'fake': 'run_pyscript',
+ },
+ shortcuts={'?': 'help', '!': 'shell'},
)
return parser
+
def test_multiline_histitem(parser):
from cmd2.history import History
+
line = 'multiline foo\nbar\n\n'
statement = parser.parse(line)
history = History()
@@ -292,8 +317,10 @@ def test_multiline_histitem(parser):
pr_lines = hist_item.pr().splitlines()
assert pr_lines[0].endswith('multiline foo bar')
+
def test_multiline_histitem_verbose(parser):
from cmd2.history import History
+
line = 'multiline foo\nbar\n\n'
statement = parser.parse(line)
history = History()
@@ -305,14 +332,12 @@ def test_multiline_histitem_verbose(parser):
assert pr_lines[0].endswith('multiline foo')
assert pr_lines[1] == 'bar'
+
def test_history_item_instantiate():
- from cmd2.parsing import Statement
from cmd2.history import HistoryItem
- statement = Statement('history',
- raw='help history',
- command='help',
- arg_list=['history'],
- )
+ from cmd2.parsing import Statement
+
+ statement = Statement('history', raw='help history', command='help', arg_list=['history'],)
with pytest.raises(TypeError):
_ = HistoryItem()
with pytest.raises(TypeError):
@@ -322,11 +347,13 @@ def test_history_item_instantiate():
with pytest.raises(TypeError):
_ = HistoryItem(statement=statement, idx='hi')
+
def test_history_item_properties(histitem):
assert histitem.raw == 'help history'
assert histitem.expanded == 'help history'
assert str(histitem) == 'help history'
+
#
# test history command
#
@@ -334,113 +361,144 @@ def test_base_history(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
out, err = run_cmd(base_app, 'history')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
2 shortcuts
-""")
+"""
+ )
assert out == expected
out, err = run_cmd(base_app, 'history he')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
-""")
+"""
+ )
assert out == expected
out, err = run_cmd(base_app, 'history sh')
- expected = normalize("""
+ expected = normalize(
+ """
2 shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_script_format(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
out, err = run_cmd(base_app, 'history -s')
- expected = normalize("""
+ expected = normalize(
+ """
help
shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_with_string_argument(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
run_cmd(base_app, 'help history')
out, err = run_cmd(base_app, 'history help')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
3 help history
-""")
+"""
+ )
assert out == expected
+
def test_history_expanded_with_string_argument(base_app):
run_cmd(base_app, 'alias create sc shortcuts')
run_cmd(base_app, 'help')
run_cmd(base_app, 'help history')
run_cmd(base_app, 'sc')
out, err = run_cmd(base_app, 'history -v shortcuts')
- expected = normalize("""
+ expected = normalize(
+ """
1 alias create sc shortcuts
4 sc
4x shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_expanded_with_regex_argument(base_app):
run_cmd(base_app, 'alias create sc shortcuts')
run_cmd(base_app, 'help')
run_cmd(base_app, 'help history')
run_cmd(base_app, 'sc')
out, err = run_cmd(base_app, 'history -v /sh.*cuts/')
- expected = normalize("""
+ expected = normalize(
+ """
1 alias create sc shortcuts
4 sc
4x shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_with_integer_argument(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
out, err = run_cmd(base_app, 'history 1')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
-""")
+"""
+ )
assert out == expected
+
def test_history_with_integer_span(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
run_cmd(base_app, 'help history')
out, err = run_cmd(base_app, 'history 1..2')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
2 shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_with_span_start(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
run_cmd(base_app, 'help history')
out, err = run_cmd(base_app, 'history 2:')
- expected = normalize("""
+ expected = normalize(
+ """
2 shortcuts
3 help history
-""")
+"""
+ )
assert out == expected
+
def test_history_with_span_end(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
run_cmd(base_app, 'help history')
out, err = run_cmd(base_app, 'history :2')
- expected = normalize("""
+ expected = normalize(
+ """
1 help
2 shortcuts
-""")
+"""
+ )
assert out == expected
+
def test_history_with_span_index_error(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'help history')
@@ -448,6 +506,7 @@ def test_history_with_span_index_error(base_app):
with pytest.raises(ValueError):
base_app.onecmd('history "hal :"')
+
def test_history_output_file():
app = cmd2.Cmd(multiline_commands=['alias'])
run_cmd(app, 'help')
@@ -463,6 +522,7 @@ def test_history_output_file():
content = normalize(f.read())
assert content == expected
+
def test_history_bad_output_file(base_app):
run_cmd(base_app, 'help')
run_cmd(base_app, 'shortcuts')
@@ -474,6 +534,7 @@ def test_history_bad_output_file(base_app):
assert not out
assert "Error saving" in err[0]
+
def test_history_edit(monkeypatch):
app = cmd2.Cmd(multiline_commands=['alias'])
@@ -499,6 +560,7 @@ def test_history_edit(monkeypatch):
edit_mock.assert_called_once()
run_script_mock.assert_called_once()
+
def test_history_run_all_commands(base_app):
# make sure we refuse to run all commands as a default
run_cmd(base_app, 'shortcuts')
@@ -509,11 +571,13 @@ def test_history_run_all_commands(base_app):
# then we should have a list of shortcuts in our output
assert out == []
+
def test_history_run_one_command(base_app):
out1, err1 = run_cmd(base_app, 'help')
out2, err2 = run_cmd(base_app, 'history -r 1')
assert out1 == out2
+
def test_history_clear(hist_file):
# Add commands to history
app = cmd2.Cmd(persistent_history_file=hist_file)
@@ -532,6 +596,7 @@ def test_history_clear(hist_file):
assert out == []
assert not os.path.exists(hist_file)
+
def test_history_verbose_with_other_options(base_app):
# make sure -v shows a usage error if any other options are present
options_to_test = ['-r', '-e', '-o file', '-t file', '-c', '-x']
@@ -541,6 +606,7 @@ def test_history_verbose_with_other_options(base_app):
assert out[0] == '-v can not be used with any other options'
assert out[1].startswith('Usage:')
+
def test_history_verbose(base_app):
# validate function of -v option
run_cmd(base_app, 'alias create s shortcuts')
@@ -549,6 +615,7 @@ def test_history_verbose(base_app):
assert len(out) == 3
# TODO test for basic formatting once we figure it out
+
def test_history_script_with_invalid_options(base_app):
# make sure -s shows a usage error if -c, -r, -e, -o, or -t are present
options_to_test = ['-r', '-e', '-o file', '-t file', '-c']
@@ -558,6 +625,7 @@ def test_history_script_with_invalid_options(base_app):
assert out[0] == '-s and -x can not be used with -c, -r, -e, -o, or -t'
assert out[1].startswith('Usage:')
+
def test_history_script(base_app):
cmds = ['alias create s shortcuts', 's']
for cmd in cmds:
@@ -565,6 +633,7 @@ def test_history_script(base_app):
out, err = run_cmd(base_app, 'history -s')
assert out == cmds
+
def test_history_expanded_with_invalid_options(base_app):
# make sure -x shows a usage error if -c, -r, -e, -o, or -t are present
options_to_test = ['-r', '-e', '-o file', '-t file', '-c']
@@ -574,6 +643,7 @@ def test_history_expanded_with_invalid_options(base_app):
assert out[0] == '-s and -x can not be used with -c, -r, -e, -o, or -t'
assert out[1].startswith('Usage:')
+
def test_history_expanded(base_app):
# validate function of -x option
cmds = ['alias create s shortcuts', 's']
@@ -583,6 +653,7 @@ def test_history_expanded(base_app):
expected = [' 1 alias create s shortcuts', ' 2 shortcuts']
assert out == expected
+
def test_history_script_expanded(base_app):
# validate function of -s -x options together
cmds = ['alias create s shortcuts', 's']
@@ -592,10 +663,12 @@ def test_history_script_expanded(base_app):
expected = ['alias create s shortcuts', 'shortcuts']
assert out == expected
+
def test_base_help_history(base_app):
out, err = run_cmd(base_app, 'help history')
assert out == normalize(HELP_HISTORY)
+
def test_exclude_from_history(base_app, monkeypatch):
# Run history command
run_cmd(base_app, 'history')
@@ -612,6 +685,7 @@ def test_exclude_from_history(base_app, monkeypatch):
expected = normalize(""" 1 help""")
assert out == expected
+
#
# test history initialization
#
@@ -626,6 +700,7 @@ def hist_file():
except FileNotFoundError:
pass
+
def test_history_file_is_directory(capsys):
with tempfile.TemporaryDirectory() as test_dir:
# Create a new cmd2 app
@@ -633,6 +708,7 @@ def test_history_file_is_directory(capsys):
_, err = capsys.readouterr()
assert 'is a directory' in err
+
def test_history_can_create_directory(mocker):
# Mock out atexit.register so the persistent file doesn't written when this function
# exists because we will be deleting the directory it needs to go to.
@@ -654,6 +730,7 @@ def test_history_can_create_directory(mocker):
# Cleanup
os.rmdir(hist_file_dir)
+
def test_history_cannot_create_directory(mocker, capsys):
mock_open = mocker.patch('os.makedirs')
mock_open.side_effect = OSError
@@ -663,6 +740,7 @@ def test_history_cannot_create_directory(mocker, capsys):
_, err = capsys.readouterr()
assert 'Error creating persistent history file directory' in err
+
def test_history_file_permission_error(mocker, capsys):
mock_open = mocker.patch('builtins.open')
mock_open.side_effect = PermissionError
@@ -672,6 +750,7 @@ def test_history_file_permission_error(mocker, capsys):
assert not out
assert 'Can not read' in err
+
def test_history_file_conversion_no_truncate_on_init(hist_file, capsys):
# make sure we don't truncate the plain text history file on init
# it shouldn't get converted to pickle format until we save history
@@ -688,14 +767,15 @@ def test_history_file_conversion_no_truncate_on_init(hist_file, capsys):
# history should be initialized, but the file on disk should
# still be plain text
with open(hist_file, 'r') as hfobj:
- histlist= hfobj.readlines()
+ histlist = hfobj.readlines()
assert len(histlist) == 3
# history.get() is overridden to be one based, not zero based
- assert histlist[0]== 'help\n'
+ assert histlist[0] == 'help\n'
assert histlist[1] == 'alias\n'
assert histlist[2] == 'alias create s shortcuts\n'
+
def test_history_populates_readline(hist_file):
# - create a cmd2 with persistent history
app = cmd2.Cmd(persistent_history_file=hist_file)
@@ -718,11 +798,13 @@ def test_history_populates_readline(hist_file):
# so we check to make sure that cmd2 populated the readline history
# using the same rules
from cmd2.rl_utils import readline
+
assert readline.get_current_history_length() == 3
assert readline.get_history_item(1) == 'help'
assert readline.get_history_item(2) == 'shortcuts'
assert readline.get_history_item(3) == 'alias'
+
#
# test cmd2's ability to write out history on exit
# we are testing the _persist_history_on_exit() method, and
@@ -737,6 +819,7 @@ def test_persist_history_ensure_no_error_if_no_histfile(base_app, capsys):
assert not out
assert not err
+
def test_persist_history_permission_error(hist_file, mocker, capsys):
app = cmd2.Cmd(persistent_history_file=hist_file)
run_cmd(app, 'help')