From eebfee8344d135713db94f59fccd86d51354bdc3 Mon Sep 17 00:00:00 2001 From: LoricAndre Date: Wed, 20 Nov 2024 17:42:47 +0100 Subject: [PATCH] chore: remove some platform-specific quirkinesses from e2e --- test/test_skim.py | 378 ++++++++++++++++++++++++++++++---------------- 1 file changed, 246 insertions(+), 132 deletions(-) diff --git a/test/test_skim.py b/test/test_skim.py index f85515c88..879fb352a 100644 --- a/test/test_skim.py +++ b/test/test_skim.py @@ -20,9 +20,11 @@ os.chdir(BASE) SK = f"SKIM_DEFAULT_OPTIONS= SKIM_DEFAULT_COMMAND= {BASE}/target/release/sk" + def now_mills(): return int(round(time.time() * 1000)) + def wait(func, timeout_handler=None): since = now_mills() while now_mills() - since < DEFAULT_TIMEOUT: @@ -34,46 +36,63 @@ def wait(func, timeout_handler=None): timeout_handler() raise BaseException('Timeout on wait') + class Shell(object): """The shell configurations for tmux tests""" + def __init__(self): super(Shell, self).__init__() + def unsets(): return 'unset SKIM_DEFAULT_COMMAND SKIM_DEFAULT_OPTIONS;' + def bash(): return 'PS1= PROMPT_COMMAND= bash --rcfile None' + def zsh(): return 'PS1= PROMPT_COMMAND= HISTSIZE=100 zsh -f' + class Key(object): """Represent a key to send to tmux""" + def __init__(self, key): super(Key, self).__init__() self.key = key + def __repr__(self): return self.key + class Ctrl(Key): """Represent a control key""" + def __init__(self, key): super(Ctrl, self).__init__(key) + def __repr__(self): return f'C-{self.key.upper()}' + class Alt(Key): """Represent an alt key""" + def __init__(self, key): super(Alt, self).__init__(key) + def __repr__(self): return f'M-{self.key}' + class TmuxOutput(list): """A list that contains the output of tmux""" # match the status line # normal: `| 10/219 [2] 8/0.` # inline: `> query < 10/219 [2] 8/0.` # preview: `> query < 10/219 [2] 8/0.│...` - RE = re.compile(r'(?:^|[^<-]*). ([0-9]+)/([0-9]+)(?:/[A-Z]*)?(?: \[([0-9]+)\])? *([0-9]+)/(-?[0-9]+)(\.)?(?: │)? *$') + RE = re.compile( + r'(?:^|[^<-]*). ([0-9]+)/([0-9]+)(?:/[A-Z]*)?(?: \[([0-9]+)\])? *([0-9]+)/(-?[0-9]+)(\.)?(?: │)? *$') + def __init__(self, iteratable=[]): super(TmuxOutput, self).__init__(iteratable) self._counts = None @@ -88,7 +107,7 @@ def counts(self): mat = TmuxOutput.RE.match(line) if mat is not None: ret = mat.groups() - break; + break self._counts = ret return ret @@ -123,21 +142,23 @@ def ready_with_matches(self, matches): def any_include(self, val): if hasattr(re, '_pattern_type') and isinstance(val, re._pattern_type): - method = lambda l: val.match(l) + def method(l): return val.match(l) if hasattr(re, 'Pattern') and isinstance(val, re.Pattern): - method = lambda l: val.match(l) + def method(l): return val.match(l) else: - method = lambda l: l.find(val) >= 0 + def method(l): return l.find(val) >= 0 for line in self: if method(line): return True return False + class Tmux(object): TEMPNAME = '/tmp/skim-test.txt' """Object to manipulate tmux and get result""" - def __init__(self, shell = 'bash'): + + def __init__(self, shell='bash'): super(Tmux, self).__init__() if shell == 'bash': @@ -147,9 +168,12 @@ def __init__(self, shell = 'bash'): else: raise BaseException('unknown shell') - self.win = self._go("new-window", "-d", "-P", "-F", "#I", f"{shell_cmd}")[0] - self._go("set-window-option", "-t", f"{self.win}", "pane-base-index", "0") - self.lines = int(subprocess.check_output('tput lines', shell=True).decode('utf8').strip()) + self.win = self._go("new-window", "-d", "-P", + "-F", "#I", f"{shell_cmd}")[0] + self._go("set-window-option", "-t", + f"{self.win}", "pane-base-index", "0") + self.lines = int(subprocess.check_output( + 'tput lines', shell=True).decode('utf8').strip()) def _go(self, *args, **kwargs): """Run tmux command and return result in list of strings (lines) @@ -181,11 +205,13 @@ def paste(self, content): "pasteb", "-t", f"{self.win}", ";", "send-keys", "-t", f"{self.win}", "Enter"]) - def capture(self, pane = 0): + def capture(self, pane=0): def save_capture(): try: - self._go('capture-pane', '-t', f'{self.win}.{pane}', stderr=subprocess.DEVNULL) - self._go("save-buffer", f"{Tmux.TEMPNAME}", stderr=subprocess.DEVNULL) + self._go('capture-pane', '-t', + f'{self.win}.{pane}', stderr=subprocess.DEVNULL) + self._go("save-buffer", + f"{Tmux.TEMPNAME}", stderr=subprocess.DEVNULL) return True except subprocess.CalledProcessError as ex: return False @@ -198,13 +224,14 @@ def save_capture(): content = fp.read() return TmuxOutput(content.rstrip().split(INPUT_RECORD_SEPARATOR)) - def until(self, predicate, refresh = False, pane = 0, debug_info = None): + def until(self, predicate, refresh=False, pane=0, debug_info=None): def wait_callback(): lines = self.capture() pred = predicate(lines) if pred: self.send_keys(Ctrl('l') if refresh else None) return pred + def timeout_handler(): lines = self.capture() print(lines) @@ -220,8 +247,10 @@ def prepare(self): raise e self.send_keys(Ctrl('u')) + class TestBase(unittest.TestCase): TEMPNAME = '/tmp/output' + def __init__(self, *args, **kwargs): super(TestBase, self).__init__(*args, **kwargs) self._temp_suffix = 0 @@ -262,7 +291,8 @@ def command_until(self, until_predicate, sk_options, stdin="echo -e 'a1\\na2\\na command_keys = stdin + " | " + self.sk(*sk_options) self.tmux.send_keys(command_keys) self.tmux.send_keys(Key("Enter")) - self.tmux.until(until_predicate, debug_info="SK args: {}".format(sk_options)) + self.tmux.until(until_predicate, + debug_info="SK args: {}".format(sk_options)) self.tmux.send_keys(Key('Enter')) @@ -276,7 +306,8 @@ def tearDown(self): def test_vanilla(self): self.tmux.send_keys(Key(f'seq 1 100000 | {self.sk()}'), Key('Enter')) - self.tmux.until(lambda lines: re.match(r'^>', lines[-1]) and re.match(r'^ 100000', lines[-2])) + self.tmux.until(lambda lines: re.match( + r'^>', lines[-1]) and re.match(r'^ 100000', lines[-2])) lines = self.tmux.capture() self.assertEqual(' 2', lines[-4]) self.assertEqual('> 1', lines[-3]) @@ -323,7 +354,8 @@ def test_vanilla(self): self.assertEqual('1390', self.readonce().strip()) def test_default_command(self): - self.tmux.send_keys(self.sk().replace('SKIM_DEFAULT_COMMAND=', "SKIM_DEFAULT_COMMAND='echo hello'")) + self.tmux.send_keys(self.sk().replace( + 'SKIM_DEFAULT_COMMAND=', "SKIM_DEFAULT_COMMAND='echo hello'")) self.tmux.send_keys(Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) self.tmux.send_keys(Key('Enter')) @@ -337,7 +369,7 @@ def test_key_bindings(self): self.tmux.send_keys(Ctrl('a'), Key('(')) self.tmux.until(lambda lines: lines[-1] == '> (foo bar foo-bar') - ## Meta-F + # Meta-F self.tmux.send_keys(Alt('f'), Key(')')) self.tmux.until(lambda lines: lines[-1] == '> (foo) bar foo-bar') @@ -359,49 +391,57 @@ def test_key_bindings(self): # META-B self.tmux.send_keys(Alt('b'), Key('Space'), Key('Space')) - self.tmux.until(lambda lines: lines[-1] == '> ( foovfoovr) bar foo-bar') + self.tmux.until( + lambda lines: lines[-1] == '> ( foovfoovr) bar foo-bar') # CTRL-F / Right - self.tmux.send_keys( Ctrl('f'), Key('Right'), '/') - self.tmux.until(lambda lines: lines[-1] == '> ( fo/ovfoovr) bar foo-bar') + self.tmux.send_keys(Ctrl('f'), Key('Right'), '/') + self.tmux.until( + lambda lines: lines[-1] == '> ( fo/ovfoovr) bar foo-bar') # CTRL-H / BS - self.tmux.send_keys( Ctrl('h'), Key('BSpace')) - self.tmux.until(lambda lines: lines[-1] == '> ( fovfoovr) bar foo-bar') + self.tmux.send_keys(Ctrl('h'), Key('BSpace')) + self.tmux.until( + lambda lines: lines[-1] == '> ( fovfoovr) bar foo-bar') # CTRL-E self.tmux.send_keys(Ctrl('e'), 'baz') - self.tmux.until(lambda lines: lines[-1] == '> ( fovfoovr) bar foo-barbaz') + self.tmux.until( + lambda lines: lines[-1] == '> ( fovfoovr) bar foo-barbaz') # CTRL-U - self.tmux.send_keys( Ctrl('u')) + self.tmux.send_keys(Ctrl('u')) self.tmux.until(lambda lines: lines[-1] == '>') # CTRL-Y - self.tmux.send_keys( Ctrl('y')) - self.tmux.until(lambda lines: lines[-1] == '> ( fovfoovr) bar foo-barbaz') + self.tmux.send_keys(Ctrl('y')) + self.tmux.until( + lambda lines: lines[-1] == '> ( fovfoovr) bar foo-barbaz') # CTRL-W - self.tmux.send_keys( Ctrl('w'), 'bar-foo') - self.tmux.until(lambda lines: lines[-1] == '> ( fovfoovr) bar bar-foo') + self.tmux.send_keys(Ctrl('w'), 'bar-foo') + self.tmux.until( + lambda lines: lines[-1] == '> ( fovfoovr) bar bar-foo') # # META-D self.tmux.send_keys(Alt('b'), Alt('b'), Alt('d'), Ctrl('a'), Ctrl('y')) - self.tmux.until(lambda lines: lines[-1] == '> bar( fovfoovr) bar -foo') + self.tmux.until( + lambda lines: lines[-1] == '> bar( fovfoovr) bar -foo') # CTRL-M self.tmux.send_keys(Ctrl('m')) self.tmux.until(lambda lines: not lines[-1].startswith('>')) def test_key_bindings_interactive(self): - self.tmux.send_keys(f"{SK} -i --cmd-query 'foo bar foo-bar'", Key('Enter')) + self.tmux.send_keys( + f"{SK} -i --cmd-query 'foo bar foo-bar'", Key('Enter')) self.tmux.until(lambda lines: lines[-1].startswith('c>')) # Ctrl-A self.tmux.send_keys(Ctrl('a'), Key('(')) self.tmux.until(lambda lines: lines[-1] == 'c> (foo bar foo-bar') - ## Meta-F + # Meta-F self.tmux.send_keys(Alt('f'), Key(')')) self.tmux.until(lambda lines: lines[-1] == 'c> (foo) bar foo-bar') @@ -419,46 +459,55 @@ def test_key_bindings_interactive(self): # # # CTRL-Y self.tmux.send_keys(Ctrl('y'), Ctrl('y')) - self.tmux.until(lambda lines: lines[-1] == 'c> (foovfoovr) bar foo-bar') + self.tmux.until( + lambda lines: lines[-1] == 'c> (foovfoovr) bar foo-bar') # META-B self.tmux.send_keys(Alt('b'), Key('Space'), Key('Space')) - self.tmux.until(lambda lines: lines[-1] == 'c> ( foovfoovr) bar foo-bar') + self.tmux.until( + lambda lines: lines[-1] == 'c> ( foovfoovr) bar foo-bar') # CTRL-F / Right - self.tmux.send_keys( Ctrl('f'), Key('Right'), '/') - self.tmux.until(lambda lines: lines[-1] == 'c> ( fo/ovfoovr) bar foo-bar') + self.tmux.send_keys(Ctrl('f'), Key('Right'), '/') + self.tmux.until( + lambda lines: lines[-1] == 'c> ( fo/ovfoovr) bar foo-bar') # CTRL-H / BS - self.tmux.send_keys( Ctrl('h'), Key('BSpace')) - self.tmux.until(lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-bar') + self.tmux.send_keys(Ctrl('h'), Key('BSpace')) + self.tmux.until( + lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-bar') # CTRL-E self.tmux.send_keys(Ctrl('e'), 'baz') - self.tmux.until(lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-barbaz') + self.tmux.until( + lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-barbaz') # CTRL-U - self.tmux.send_keys( Ctrl('u')) + self.tmux.send_keys(Ctrl('u')) self.tmux.until(lambda lines: lines[-1] == 'c>') # CTRL-Y - self.tmux.send_keys( Ctrl('y')) - self.tmux.until(lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-barbaz') + self.tmux.send_keys(Ctrl('y')) + self.tmux.until( + lambda lines: lines[-1] == 'c> ( fovfoovr) bar foo-barbaz') # CTRL-W - self.tmux.send_keys( Ctrl('w'), 'bar-foo') - self.tmux.until(lambda lines: lines[-1] == 'c> ( fovfoovr) bar bar-foo') + self.tmux.send_keys(Ctrl('w'), 'bar-foo') + self.tmux.until( + lambda lines: lines[-1] == 'c> ( fovfoovr) bar bar-foo') # # META-D self.tmux.send_keys(Alt('b'), Alt('b'), Alt('d'), Ctrl('a'), Ctrl('y')) - self.tmux.until(lambda lines: lines[-1] == 'c> bar( fovfoovr) bar -foo') + self.tmux.until( + lambda lines: lines[-1] == 'c> bar( fovfoovr) bar -foo') # CTRL-M self.tmux.send_keys(Ctrl('m')) self.tmux.until(lambda lines: not lines[-1].startswith('c>')) def test_read0(self): - nfiles = subprocess.check_output("find .", shell=True).decode("utf-8").strip().split("\n") + nfiles = subprocess.check_output( + "find .", shell=True).decode("utf-8").strip().split("\n") num_of_files = len(nfiles) self.tmux.send_keys(f"find . | {self.sk()}", Key('Enter')) @@ -467,53 +516,59 @@ def test_read0(self): orig = self.readonce().strip() - self.tmux.send_keys(f"find . -print0 | {self.sk('--read0')}", Key('Enter')) + self.tmux.send_keys( + f"find . -print0 | {self.sk('--read0')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(num_of_files)) self.tmux.send_keys(Key('Enter')) self.assertEqual(orig, self.readonce().strip()) def test_print0(self): - self.tmux.send_keys(f"echo -e 'a\\nb' | {self.sk('-m', '--print0')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\\nb' | {self.sk('-m', '--print0')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(2)) self.tmux.send_keys(Key('BTab'), Key('BTab'), Key('Enter')) lines = self.readonce().strip() self.assertEqual(lines, 'a\0b\0') - self.tmux.send_keys(f"echo -e 'a\\naa\\nb' | {self.sk('-f a', '--print0')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\\naa\\nb' | {self.sk('-f a', '--print0')}", Key('Enter')) lines = self.readonce().strip() self.assertEqual(lines, 'a\0aa\0') def test_with_nth_preview(self): - sk_command = self.sk("--delimiter ','", '--with-nth 2..', '--preview', "'echo X{1}Y'") - self.tmux.send_keys("echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) + sk_command = self.sk( + "--delimiter ','", '--with-nth 2..', '--preview', "'echo X{1}Y'") + self.tmux.send_keys( + "echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) self.tmux.until(lambda lines: lines.any_include("Xfield1Y")) self.tmux.send_keys(Key('Enter')) def test_with_nth(self): # fields, expected tests = [ - ('1', 'field1,'), - ('2', 'field2,'), - ('3', 'field3,'), - ('4', 'field4'), - ('5', ''), - ('-1', 'field4'), - ('-2', 'field3,'), - ('-3', 'field2,'), - ('-4', 'field1,'), - ('-5', ''), - ('2..', 'field2,field3,field4'), - ('..3', 'field1,field2,field3,'), - ('2..3', 'field2,field3,'), - ('3..2', ''), - ] + ('1', 'field1,'), + ('2', 'field2,'), + ('3', 'field3,'), + ('4', 'field4'), + ('5', ''), + ('-1', 'field4'), + ('-2', 'field3,'), + ('-3', 'field2,'), + ('-4', 'field1,'), + ('-5', ''), + ('2..', 'field2,field3,field4'), + ('..3', 'field1,field2,field3,'), + ('2..3', 'field2,field3,'), + ('3..2', ''), + ] for field, expected in tests: sk_command = self.sk("--delimiter ','", f'--with-nth={field}') - self.tmux.send_keys("echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) + self.tmux.send_keys( + "echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) lines = self.tmux.capture() self.tmux.send_keys(Key('Enter')) @@ -522,27 +577,29 @@ def test_with_nth(self): def test_nth(self): # fields, query, match_count(0/1) tests = [ - ('1', 'field1', 1), - ('1', 'field2', 0), - ('-1', 'field4', 1), - ('-1', 'field3', 0), - ('-5', 'f', 0), - ('2..', 'field2', 1), - ('2..', 'field4', 1), - ('..3', 'field1', 1), - ('..3', 'field3,', 1), - ('2..3', '2,3', 1), - ('3..2', 'f', 0), - ] + ('1', 'field1', 1), + ('1', 'field2', 0), + ('-1', 'field4', 1), + ('-1', 'field3', 0), + ('-5', 'f', 0), + ('2..', 'field2', 1), + ('2..', 'field4', 1), + ('..3', 'field1', 1), + ('..3', 'field3,', 1), + ('2..3', '2,3', 1), + ('3..2', 'f', 0), + ] for field, query, count in tests: sk_command = self.sk(f"--delimiter ',' --nth={field} -q {query}") - self.tmux.send_keys("echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) + self.tmux.send_keys( + "echo -e 'field1,field2,field3,field4' |" + sk_command, Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key('Enter')) def test_print_query(self): - self.tmux.send_keys(f"seq 1 1000 | {self.sk('-q 10', '--print-query')}", Key('Enter')) + self.tmux.send_keys( + f"seq 1 1000 | {self.sk('-q 10', '--print-query')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1000)) self.tmux.send_keys(Key('Enter')) @@ -550,7 +607,8 @@ def test_print_query(self): self.assertEqual(lines, '10\n10') def test_print_cmd(self): - self.tmux.send_keys(f"seq 1 1000 | {self.sk('--cmd-query 10', '--print-cmd')}", Key('Enter')) + self.tmux.send_keys( + f"seq 1 1000 | {self.sk('--cmd-query 10', '--print-cmd')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1000)) self.tmux.send_keys(Key('Enter')) @@ -558,7 +616,8 @@ def test_print_cmd(self): self.assertEqual(lines, '10\n1') def test_print_cmd_and_query(self): - self.tmux.send_keys(f"seq 1 1000 | {self.sk('-q 10', '--cmd-query cmd', '--print-cmd', '--print-query')}", Key('Enter')) + self.tmux.send_keys( + f"seq 1 1000 | {self.sk('-q 10', '--cmd-query cmd', '--print-cmd', '--print-query')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1000)) self.tmux.send_keys(Key('Enter')) @@ -592,7 +651,8 @@ def test_hscroll(self): self.tmux.send_keys(Key('Enter')) def test_no_hscroll(self): - self.tmux.send_keys(f"cat < a b')) self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f"echo -e 'a\\tb' | {self.sk('--tabstop 1')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\\tb' | {self.sk('--tabstop 1')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.until(lambda lines: lines[-3].startswith('> a b')) self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f"echo -e 'aa\\tb' | {self.sk('--tabstop 2')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aa\\tb' | {self.sk('--tabstop 2')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.until(lambda lines: lines[-3].startswith('> aa b')) self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f"echo -e 'aa\\tb' | {self.sk('--tabstop 3')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aa\\tb' | {self.sk('--tabstop 3')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.until(lambda lines: lines[-3].startswith('> aa b')) self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f"echo -e 'a\\tb' | {self.sk('--tabstop 4')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\\tb' | {self.sk('--tabstop 4')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.until(lambda lines: lines[-3].startswith('> a b')) self.tmux.send_keys(Key('Enter')) def test_inline_info(self): INLINE_INFO_SEP = " <" - ## the dot accounts for spinner + # the dot accounts for spinner RE = re.compile(r'[^0-9]*([0-9]+)/([0-9]+)(?: \[([0-9]+)\])?') - self.tmux.send_keys(f"echo -e 'a1\\na2\\na3\\na4' | {self.sk('--inline-info')}", Key('Enter')) - self.tmux.until(lambda lines: lines.match_count() == lines.item_count()) + self.tmux.send_keys( + f"echo -e 'a1\\na2\\na3\\na4' | {self.sk('--inline-info')}", Key('Enter')) + self.tmux.until(lambda lines: lines.match_count() + == lines.item_count()) self.tmux.send_keys("a") self.tmux.until(lambda lines: lines[-1].find(INLINE_INFO_SEP) != -1) lines = self.tmux.capture() @@ -644,7 +710,8 @@ def test_inline_info(self): self.assertEqual((bef, ret[0], ret[1], ret[2]), ("> a ", 4, 4, 0)) # test that inline info is does not overwrite query - self.tmux.send_keys(f"echo -e 'a1\\nabcd2\\nabcd3\\nabcd4' | {self.sk('--inline-info')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a1\\nabcd2\\nabcd3\\nabcd4' | {self.sk('--inline-info')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(4)) self.tmux.send_keys("bc", Ctrl("a"), "a") self.tmux.until(lambda lines: lines[-1].find(INLINE_INFO_SEP) != -1 and @@ -753,16 +820,20 @@ def test_multiple_option_values_should_be_accepted(self): self.command_until(sk_options=[opt], until_predicate=find_prompt) options = [ - ('--prompt a --prompt b -p c', lambda lines: lines[-1].startswith("c")), - ('-i --cmd-prompt a --cmd-prompt b', lambda lines: lines[-1].startswith("b")), - ('-i --cmd-query asdf --cmd-query xyz', lambda lines: lines[-1].startswith("c> xyz")), + ('--prompt a --prompt b -p c', + lambda lines: lines[-1].startswith("c")), + ('-i --cmd-prompt a --cmd-prompt b', + lambda lines: lines[-1].startswith("b")), + ('-i --cmd-query asdf --cmd-query xyz', + lambda lines: lines[-1].startswith("c> xyz")), ('--interactive -i', lambda lines: find_prompt(lines, interactive=True)), ('--reverse --reverse', lambda lines: find_prompt(lines, reverse=True)) ] for opt, pred in options: self.command_until(sk_options=[opt], until_predicate=pred) - self.command_until(stdin="echo -e a\\0b", sk_options=['--read0 --read0'], until_predicate=find_prompt) + self.command_until( + stdin="echo -e a\\0b", sk_options=['--read0 --read0'], until_predicate=find_prompt) def test_single_quote_of_preview_command(self): # echo "'\"ABC\"'" | sk --preview="echo X{}X" => X'"ABC"'X @@ -781,7 +852,8 @@ def test_single_quote_of_preview_command(self): def test_ansi_and_read0(self): """should keep the NULL character, see #142""" - self.tmux.send_keys(f"echo -e 'a\\0b' | {self.sk('--ansi')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\\0b' | {self.sk('--ansi')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key('Enter')) output = ":".join("{:02x}".format(ord(c)) for c in self.readonce()) @@ -817,7 +889,8 @@ def test_ignore_case_fuzzy(self): """should behave correctly on case, #219""" # ignore case - self.tmux.send_keys(f"echo -e 'aBcXyZ' | {self.sk('--case ignore')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aBcXyZ' | {self.sk('--case ignore')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key('abc')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) @@ -830,7 +903,8 @@ def test_ignore_case_exact(self): """should behave correctly on case, #219""" # ignore case - self.tmux.send_keys(f"echo -e 'aBcXyZ' | {self.sk('--case ignore')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aBcXyZ' | {self.sk('--case ignore')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key("'abc")) self.tmux.until(lambda lines: lines.ready_with_matches(1)) @@ -843,7 +917,8 @@ def test_respect_case_fuzzy(self): """should behave correctly on case, #219""" # respect case - self.tmux.send_keys(f"echo -e 'aBcXyZ' | {self.sk('--case respect')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aBcXyZ' | {self.sk('--case respect')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key('abc')) self.tmux.until(lambda lines: lines.ready_with_matches(0)) @@ -852,7 +927,8 @@ def test_respect_case_exact(self): """should behave correctly on case, #219""" # respect case - self.tmux.send_keys(f"echo -e 'aBcXyZ' | {self.sk('--case respect')}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'aBcXyZ' | {self.sk('--case respect')}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Key("'abc")) self.tmux.until(lambda lines: lines.ready_with_matches(0)) @@ -862,10 +938,12 @@ def test_query_history(self): history_file = f'{self.tempname()}.history' - self.tmux.send_keys(f"echo -e 'a\nb\nc' > {history_file}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\nb\nc' > {history_file}", Key('Enter')) history_mtime = os.stat(history_file).st_mtime - self.tmux.send_keys(f"echo -e 'a\nb\nc' | {self.sk('--history', history_file)}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\nb\nc' | {self.sk('--history', history_file)}", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(3)) self.tmux.send_keys(Ctrl('p')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) @@ -888,19 +966,28 @@ def test_query_history(self): self.tmux.send_keys('d') self.tmux.until(lambda lines: lines[-1].startswith('> cd')) + open_lines = self.tmux.capture() self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f'[[ "$(echo -n $(cat {history_file}))" == "a b c cd" ]] && echo ok') - self.tmux.send_keys(Key('Enter')) - self.tmux.until(lambda lines: lines[-1].startswith('ok')) + self.tmux.until(lambda lines: lines != open_lines) + + with open(history_file, 'r') as f: + lines = f.readlines() + assert len(lines) == 4 + assert lines[0].strip() == "a" + assert lines[1].strip() == "b" + assert lines[2].strip() == "c" + assert lines[3].strip() == "cd" def test_cmd_history(self): """query history should work""" history_file = f'{self.tempname()}.cmd-history' - self.tmux.send_keys(f"echo -e 'a\nb\nc' > {history_file}", Key('Enter')) - self.tmux.send_keys(f"""{self.sk("-i -c 'echo {}'", '--cmd-history', history_file)}""", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'a\nb\nc' > {history_file}", Key('Enter')) + self.tmux.send_keys( + f"""{self.sk("-i -c 'echo {}'", '--cmd-history', history_file)}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.send_keys(Ctrl('p')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) @@ -923,25 +1010,35 @@ def test_cmd_history(self): self.tmux.send_keys('d') self.tmux.until(lambda lines: lines[-1].startswith('c> cd')) + open_lines = self.tmux.capture() self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f'[[ "$(echo -n $(cat {history_file}))" == "a b c cd" ]] && echo ok') - self.tmux.send_keys(Key('Enter')) - self.tmux.until(lambda lines: lines[-1].startswith('ok')) + self.tmux.until(lambda lines: lines != open_lines) + + with open(history_file, 'r') as f: + lines = f.readlines() + assert len(lines) == 4 + assert lines[0].strip() == "a" + assert lines[1].strip() == "b" + assert lines[2].strip() == "c" + assert lines[3].strip() == "cd" def test_execute_with_zero_result_ref(self): """execute should not panic with zero results #276""" - self.tmux.send_keys(f"""echo -n "" | {self.sk("--bind 'enter:execute(less {})'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n "" | {self.sk("--bind 'enter:execute(less {})'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(0)) self.tmux.send_keys(Key('Enter')) self.tmux.send_keys(Key('q')) self.tmux.until(lambda lines: lines.ready_with_lines(0)) - self.tmux.until(lambda lines: lines[-1].startswith('> q')) # less is not executed at all + # less is not executed at all + self.tmux.until(lambda lines: lines[-1].startswith('> q')) self.tmux.send_keys(Ctrl('g')) def test_execute_with_zero_result_no_ref(self): """execute should not panic with zero results #276""" - self.tmux.send_keys(f"""echo -n "" | {self.sk("--bind 'enter:execute(less)'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n "" | {self.sk("--bind 'enter:execute(less)'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(0)) self.tmux.send_keys(Key('Enter')) self.tmux.send_keys(Key('q')) @@ -950,26 +1047,30 @@ def test_execute_with_zero_result_no_ref(self): def test_if_non_matched(self): """commands only effect if no item is matched""" - self.tmux.send_keys(f"""echo "a\nb" | {self.sk("--bind 'enter:if-non-matched(backward-delete-char)'", "-q ab")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo "a\nb" | {self.sk("--bind 'enter:if-non-matched(backward-delete-char)'", "-q ab")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(0)) self.tmux.send_keys(Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) - self.tmux.send_keys(Key('Enter')) # not triggered anymore + self.tmux.send_keys(Key('Enter')) # not triggered anymore self.tmux.until(lambda lines: lines.ready_with_matches(1)) def test_nul_in_execute(self): """NUL should work in preview command see #278""" - self.tmux.send_keys(f"""echo -ne 'a\\0b' | {self.sk("--preview='echo -en {} | xxd'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -ne 'a\\0b' | {self.sk("--preview='echo -en {} | hexdump -C'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) - self.tmux.until(lambda lines: lines.any_include('6100 62')) + self.tmux.until(lambda lines: lines.any_include('61 00 62')) def test_skip_to_pattern(self): - self.tmux.send_keys(f"""echo -ne 'a/b/c' | {self.sk("--skip-to-pattern '[^/]*$'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -ne 'a/b/c' | {self.sk("--skip-to-pattern '[^/]*$'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(1)) self.tmux.until(lambda lines: lines.any_include('..c')) def test_multi_selection(self): - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk("-m")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk("-m")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(3)) self.tmux.until(lambda lines: lines[-3].startswith('> a')) self.tmux.send_keys(Key('b')) @@ -1013,7 +1114,8 @@ def test_multi_selection(self): self.assertEqual('b\na', self.readonce().strip()) def test_append_and_select(self): - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk("-m --bind 'ctrl-f:append-and-select'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk("-m --bind 'ctrl-f:append-and-select'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_lines(3)) self.tmux.send_keys(Key('xyz')) self.tmux.until(lambda lines: lines.ready_with_matches(0)) @@ -1026,30 +1128,35 @@ def test_append_and_select(self): self.tmux.until(lambda lines: lines[-3].startswith('> a')) def test_pre_select_n(self): - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk("-m --pre-select-n=1")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk("-m --pre-select-n=1")}""", Key('Enter')) self.tmux.until(lambda lines: lines[-5].startswith(' c')) self.tmux.until(lambda lines: lines[-4].startswith(' b')) self.tmux.until(lambda lines: lines[-3].startswith('>>a')) def test_pre_select_items(self): args = "-m --pre-select-items=$'b\\nc'" - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: lines[-5].startswith(' >c')) self.tmux.until(lambda lines: lines[-4].startswith(' >b')) self.tmux.until(lambda lines: lines[-3].startswith('> a')) def test_pre_select_pat(self): - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk("-m --pre-select-pat='[b|c]'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk("-m --pre-select-pat='[b|c]'")}""", Key('Enter')) self.tmux.until(lambda lines: lines[-5].startswith(' >c')) self.tmux.until(lambda lines: lines[-4].startswith(' >b')) self.tmux.until(lambda lines: lines[-3].startswith('> a')) def test_pre_select_file(self): pre_select_file = f'{self.tempname()}.pre_select' - self.tmux.send_keys(f"echo -e 'b\nc' > {pre_select_file}", Key('Enter')) + self.tmux.send_keys( + f"echo -e 'b\nc' > {pre_select_file}", Key('Enter')) args = f'''-m --pre-select-file={pre_select_file}''' - self.tmux.send_keys(f"""echo -n 'a\nb\nc' | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo -n 'a\nb\nc' | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: lines[-5].startswith(' >c')) self.tmux.until(lambda lines: lines[-4].startswith(' >b')) self.tmux.until(lambda lines: lines[-3].startswith('> a')) @@ -1069,33 +1176,39 @@ def test_no_clear_if_empty(self): self.tmux.until(lambda lines: lines[-3].startswith('> b')) def test_preview_scroll_const(self): - self.tmux.send_keys(f"""echo foo 123 321 | {self.sk("--preview 'seq 1000' --preview-window left:+123")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo foo 123 321 | {self.sk("--preview 'seq 1000' --preview-window left:+123")}""", Key('Enter')) self.tmux.until(lambda lines: re.match(r'123.*123/1000', lines[0])) def test_preview_scroll_expr(self): args = "--preview 'seq 1000' --preview-window left:+{3}" - self.tmux.send_keys(f"""echo foo 123 321 | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo foo 123 321 | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: re.match(r'321.*321/1000', lines[0])) def test_preview_scroll_and_offset(self): args = "--preview 'seq 1000' --preview-window left:+{2}-2" - self.tmux.send_keys(f"""echo foo 123 321 | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo foo 123 321 | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: re.match(r'121.*121/1000', lines[0])) self.tmux.send_keys(Key('Enter')) - self.tmux.send_keys(f"""echo foo :123: 321 | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo foo :123: 321 | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: re.match(r'121.*121/1000', lines[0])) self.tmux.send_keys(Key('Enter')) def test_issue_359_multi_byte_and_regex(self): - self.tmux.send_keys(f"""echo 'ああa' | {self.sk("--regex -q 'a'")}""", Key('Enter')) + self.tmux.send_keys( + f"""echo 'ああa' | {self.sk("--regex -q 'a'")}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) self.tmux.until(lambda lines: lines[-3].startswith('> ああa')) def test_issue_361_literal_space(self): args = '''-q "'foo\\ bar"''' - self.tmux.send_keys(f"""echo 'foo bar\nfoo bar' | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo 'foo bar\nfoo bar' | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) self.tmux.until(lambda lines: lines[-3].startswith('> foo bar')) self.tmux.send_keys(Key('Enter')) @@ -1104,7 +1217,8 @@ def test_issue_361_literal_space(self): self.tmux.send_keys(f"""set +o histexpand""", Key('Enter')) args = '''-q "'!foo\\ bar"''' - self.tmux.send_keys(f"""echo 'foo bar\nfoo bar' | {self.sk(args)}""", Key('Enter')) + self.tmux.send_keys( + f"""echo 'foo bar\nfoo bar' | {self.sk(args)}""", Key('Enter')) self.tmux.until(lambda lines: lines.ready_with_matches(1)) self.tmux.until(lambda lines: lines[-3].startswith('> foo bar')) self.tmux.send_keys(Key('Enter'))