2016-11-27 22:57:24 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""Tests the xonsh history."""
|
|
|
|
# pylint: disable=protected-access
|
|
|
|
import os
|
|
|
|
import shlex
|
|
|
|
|
|
|
|
from xonsh.history.sqlite import SqliteHistory
|
|
|
|
from xonsh.history.main import history_main
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.yield_fixture
|
|
|
|
def hist():
|
2018-08-30 09:18:49 -05:00
|
|
|
h = SqliteHistory(
|
|
|
|
filename="xonsh-HISTORY-TEST.sqlite", sessionid="SESSIONID", gc=False
|
|
|
|
)
|
2016-11-27 22:57:24 +08:00
|
|
|
yield h
|
|
|
|
os.remove(h.filename)
|
|
|
|
|
|
|
|
|
|
|
|
def test_hist_append(hist, xonsh_builtins):
|
|
|
|
"""Verify appending to the history works."""
|
2018-09-13 14:03:35 -04:00
|
|
|
xonsh_builtins.__xonsh__.env["HISTCONTROL"] = set()
|
2018-08-30 09:18:49 -05:00
|
|
|
hf = hist.append({"inp": "still alive", "rtn": 1})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert hf is None
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
|
|
|
assert len(items) == 1
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "still alive" == items[0]["inp"]
|
|
|
|
assert 1 == items[0]["rtn"]
|
|
|
|
hist.append({"inp": "still alive", "rtn": 0})
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
|
|
|
assert len(items) == 2
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "still alive" == items[1]["inp"]
|
|
|
|
assert 0 == items[1]["rtn"]
|
2016-12-01 22:14:22 +08:00
|
|
|
assert list(hist.all_items()) == items
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
|
2016-11-30 22:49:13 +08:00
|
|
|
def test_hist_attrs(hist, xonsh_builtins):
|
2018-09-13 14:03:35 -04:00
|
|
|
xonsh_builtins.__xonsh__.env["HISTCONTROL"] = set()
|
2018-08-30 09:18:49 -05:00
|
|
|
hf = hist.append({"inp": "ls foo", "rtn": 1})
|
2016-11-30 22:49:13 +08:00
|
|
|
assert hf is None
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "ls foo" == hist.inps[0]
|
|
|
|
assert "ls foo" == hist.inps[-1]
|
2016-11-30 22:49:13 +08:00
|
|
|
assert 1 == hist.rtns[0]
|
|
|
|
assert 1 == hist.rtns[-1]
|
|
|
|
assert None is hist.outs[-1]
|
|
|
|
assert [1] == hist.rtns[:]
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls bar", "rtn": 0})
|
|
|
|
assert "ls bar" == hist.inps[1]
|
|
|
|
assert "ls bar" == hist.inps[-1]
|
2016-11-30 22:49:13 +08:00
|
|
|
assert 0 == hist.rtns[1]
|
|
|
|
assert 0 == hist.rtns[-1]
|
|
|
|
assert None is hist.outs[-1]
|
|
|
|
assert [1, 0] == hist.rtns[:]
|
|
|
|
assert len(hist.tss) == 2
|
|
|
|
assert len(hist.tss[0]) == 2
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
CMDS = ["ls", "cat hello kitty", "abc", "def", "touch me", "grep from me"]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, commands, offset",
|
|
|
|
[
|
|
|
|
("", CMDS, (0, 1)),
|
|
|
|
("-r", list(reversed(CMDS)), (len(CMDS) - 1, -1)),
|
|
|
|
("0", CMDS[0:1], (0, 1)),
|
|
|
|
("1", CMDS[1:2], (1, 1)),
|
|
|
|
("-2", CMDS[-2:-1], (len(CMDS) - 2, 1)),
|
|
|
|
("1:3", CMDS[1:3], (1, 1)),
|
|
|
|
("1::2", CMDS[1::2], (1, 2)),
|
|
|
|
("-4:-2", CMDS[-4:-2], (len(CMDS) - 4, 1)),
|
|
|
|
],
|
|
|
|
)
|
2016-11-27 22:57:24 +08:00
|
|
|
def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys):
|
|
|
|
"""Verify that CLI history commands work."""
|
|
|
|
base_idx, step = offset
|
2018-09-13 14:03:35 -04:00
|
|
|
xonsh_builtins.__xonsh__.history = hist
|
|
|
|
xonsh_builtins.__xonsh__.env["HISTCONTROL"] = set()
|
2016-11-27 22:57:24 +08:00
|
|
|
for ts, cmd in enumerate(CMDS): # populate the shell history
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": cmd, "rtn": 0, "ts": (ts + 1, ts + 1.5)})
|
2016-11-27 22:57:24 +08:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = (
|
|
|
|
"{}: {}".format(base_idx + idx * step, cmd)
|
|
|
|
for idx, cmd in enumerate(list(commands))
|
|
|
|
)
|
|
|
|
exp = "\n".join(exp)
|
2016-11-27 22:57:24 +08:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
history_main(["show", "-n"] + shlex.split(inp))
|
2016-11-27 22:57:24 +08:00
|
|
|
out, err = capsys.readouterr()
|
|
|
|
assert out.rstrip() == exp
|
|
|
|
|
|
|
|
|
|
|
|
def test_histcontrol(hist, xonsh_builtins):
|
|
|
|
"""Test HISTCONTROL=ignoredups,ignoreerr"""
|
|
|
|
|
2018-09-13 14:03:35 -04:00
|
|
|
xonsh_builtins.__xonsh__.env["HISTCONTROL"] = "ignoredups,ignoreerr"
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 0
|
|
|
|
|
2016-12-01 22:14:22 +08:00
|
|
|
# An error, items() remains empty
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls foo", "rtn": 2})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 0
|
2016-12-04 23:24:56 +08:00
|
|
|
assert len(hist.inps) == 1
|
|
|
|
assert len(hist.rtns) == 1
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 2 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Success
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls foobazz", "rtn": 0})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 1
|
2016-12-04 23:24:56 +08:00
|
|
|
assert len(hist.inps) == 2
|
|
|
|
assert len(hist.rtns) == 2
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "ls foobazz" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 0 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Error
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls foo", "rtn": 2})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 1
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "ls foobazz" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 2 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# File now exists, success
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls foo", "rtn": 0})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 2
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "ls foo" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 0 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Success
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls", "rtn": 0})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 3
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "ls" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 0 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Dup
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls", "rtn": 0})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 3
|
|
|
|
|
|
|
|
# Success
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "/bin/ls", "rtn": 0})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 4
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "/bin/ls" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 0 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Error
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls bazz", "rtn": 1})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 4
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "/bin/ls" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
|
|
|
assert "ls bazz" == hist.inps[-1]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert 1 == hist.rtns[-1]
|
2016-11-27 22:57:24 +08:00
|
|
|
|
|
|
|
# Error
|
2018-08-30 09:18:49 -05:00
|
|
|
hist.append({"inp": "ls bazz", "rtn": -1})
|
2016-11-27 22:57:24 +08:00
|
|
|
assert len(hist) == 4
|
2016-12-01 22:14:22 +08:00
|
|
|
items = list(hist.items())
|
2018-08-30 09:18:49 -05:00
|
|
|
assert "/bin/ls" == items[-1]["inp"]
|
|
|
|
assert 0 == items[-1]["rtn"]
|
2016-12-04 22:54:45 +08:00
|
|
|
assert -1 == hist.rtns[-1]
|
2017-02-05 22:55:04 +08:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"index, exp",
|
|
|
|
[
|
|
|
|
(-1, ("grep from me", "out", 0, (5, 6))),
|
|
|
|
(1, ("cat hello kitty", "out", 0, (1, 2))),
|
|
|
|
(
|
|
|
|
slice(1, 3),
|
|
|
|
[("cat hello kitty", "out", 0, (1, 2)), ("abc", "out", 0, (2, 3))],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2017-02-05 22:55:04 +08:00
|
|
|
def test_history_getitem(index, exp, hist, xonsh_builtins):
|
2018-09-13 14:03:35 -04:00
|
|
|
xonsh_builtins.__xonsh__.env["HISTCONTROL"] = set()
|
|
|
|
xonsh_builtins.__xonsh__.env["XONSH_STORE_STDOUT"] = True
|
2018-08-30 09:18:49 -05:00
|
|
|
attrs = ("inp", "out", "rtn", "ts")
|
2017-02-05 22:55:04 +08:00
|
|
|
|
|
|
|
for ts, cmd in enumerate(CMDS): # populate the shell history
|
2018-08-30 09:18:49 -05:00
|
|
|
entry = {k: v for k, v in zip(attrs, [cmd, "out", 0, (ts, ts + 1)])}
|
2017-02-05 22:55:04 +08:00
|
|
|
hist.append(entry)
|
|
|
|
|
|
|
|
entry = hist[index]
|
|
|
|
if isinstance(entry, list):
|
|
|
|
assert [(e.cmd, e.out, e.rtn, e.ts) for e in entry] == exp
|
|
|
|
else:
|
|
|
|
assert (entry.cmd, entry.out, entry.rtn, entry.ts) == exp
|