Add tests for bash completion; fix Unicode bug that turned up
Note that argcomplete is also now required.
This commit is contained in:
parent
ea051c85b3
commit
9126980ed4
|
@ -12,10 +12,7 @@ import argparse
|
|||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||
import signal
|
||||
|
||||
try: # pragma: no cover
|
||||
import argcomplete
|
||||
except ImportError: # pragma: no cover
|
||||
argcomplete = None
|
||||
import argcomplete
|
||||
|
||||
# Valid subcommands. Defined in separate files just to break
|
||||
# things up -- they're still called with Cmdline as self.
|
||||
|
@ -40,7 +37,7 @@ class JimArgumentParser(argparse.ArgumentParser):
|
|||
self.print_usage(sys.stderr)
|
||||
self.exit(2, sprintf("error: %s\n", message))
|
||||
|
||||
class Complete(object): # pragma: no cover
|
||||
class Complete(object):
|
||||
# Completion helpers, for using argcomplete (see
|
||||
# extras/nilmtool-bash-completion.sh)
|
||||
def escape(self, s):
|
||||
|
@ -80,10 +77,6 @@ class Complete(object): # pragma: no cover
|
|||
if not path:
|
||||
return []
|
||||
results = []
|
||||
# prefix comes in as UTF-8, but results need to be Unicode,
|
||||
# weird. Still doesn't work in all cases, but that's bugs in
|
||||
# argcomplete.
|
||||
prefix = nilmdb.utils.str.decode(prefix)
|
||||
for (k,v) in client.stream_get_metadata(path).items():
|
||||
kv = self.escape(k + '=' + v)
|
||||
if kv.startswith(prefix):
|
||||
|
@ -98,6 +91,7 @@ class Cmdline(object):
|
|||
self.def_url = os.environ.get("NILMDB_URL", "http://localhost/nilmdb/")
|
||||
self.subcmd = {}
|
||||
self.complete = Complete()
|
||||
self.complete_output_stream = None # overridden by test suite
|
||||
|
||||
def arg_time(self, toparse):
|
||||
"""Parse a time string argument"""
|
||||
|
@ -153,8 +147,8 @@ class Cmdline(object):
|
|||
|
||||
# Run parser
|
||||
self.parser_setup()
|
||||
if argcomplete: # pragma: no cover
|
||||
argcomplete.autocomplete(self.parser)
|
||||
argcomplete.autocomplete(self.parser, exit_method=sys.exit,
|
||||
output_stream=self.complete_output_stream)
|
||||
self.args = self.parser.parse_args(self.argv)
|
||||
|
||||
# Run arg verify handler if there is one
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
argcomplete>=1.10.0
|
||||
CherryPy>=18.1.2
|
||||
coverage>=4.5.4
|
||||
cython>=0.29.13
|
||||
|
|
1
setup.py
1
setup.py
|
@ -6,7 +6,6 @@
|
|||
# Then just package it up:
|
||||
# python setup.py sdist
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import os
|
||||
from setuptools import setup
|
||||
|
|
|
@ -360,6 +360,12 @@ class TestCmdline(object):
|
|||
self.ok("metadata /newton/raw --update "
|
||||
"v_scale=1.234")
|
||||
|
||||
# unicode
|
||||
self.ok("metadata /newton/raw --set "
|
||||
"a_𝓴𝓮𝔂=value a_key=𝓿𝓪𝓵𝓾𝓮 a_𝗸𝗲𝘆=𝘃𝗮𝗹𝘂𝗲")
|
||||
self.ok("metadata /newton/raw --get")
|
||||
self.match("a_key=𝓿𝓪𝓵𝓾𝓮\na_𝓴𝓮𝔂=value\na_𝗸𝗲𝘆=𝘃𝗮𝗹𝘂𝗲\n")
|
||||
|
||||
# various parsing tests
|
||||
self.ok("metadata /newton/raw --update foo=")
|
||||
self.fail("metadata /newton/raw --update =bar")
|
||||
|
@ -1166,3 +1172,74 @@ class TestCmdline(object):
|
|||
|
||||
server_stop()
|
||||
server_start()
|
||||
|
||||
def test_05b_completion(self):
|
||||
# Test bash completion. This depends on some data put in the DB by
|
||||
# earlier tests, so the execution order is important.
|
||||
def complete(line, expect="<unspecified>"):
|
||||
# set env vars
|
||||
env = {
|
||||
'_ARGCOMPLETE': '1',
|
||||
'COMP_LINE': line,
|
||||
'COMP_POINT': str(len(line)),
|
||||
'COMP_TYPE': '8',
|
||||
'NILMDB_URL': "http://localhost:32180/",
|
||||
}
|
||||
for (k, v) in env.items():
|
||||
os.environ[k] = v
|
||||
|
||||
# create pipe for completion output
|
||||
output = io.BytesIO()
|
||||
|
||||
# ensure argcomplete won't mess with any FDs
|
||||
def fake_fdopen(fd, mode):
|
||||
return io.BytesIO()
|
||||
old_fdopen = os.fdopen
|
||||
os.fdopen = fake_fdopen
|
||||
|
||||
# run cli
|
||||
cmdline = nilmdb.cmdline.Cmdline([])
|
||||
cmdline.complete_output_stream = output
|
||||
try:
|
||||
cmdline.run()
|
||||
sys.exit(0)
|
||||
except SystemExit as e:
|
||||
exitcode = e.code
|
||||
eq_(exitcode, 0)
|
||||
|
||||
# clean up
|
||||
os.fdopen = old_fdopen
|
||||
for (k, v) in env.items():
|
||||
del os.environ[k]
|
||||
|
||||
# read completion output
|
||||
comp = output.getvalue()
|
||||
|
||||
# replace completion separators with commas, for clarity
|
||||
cleaned = comp.replace(b'\x0b', b',').decode('utf-8')
|
||||
|
||||
# expect the given match or prefix
|
||||
if expect.endswith('*'):
|
||||
if not cleaned.startswith(expect[:-1]):
|
||||
raise AssertionError(("completions:\n '%s'\n"
|
||||
"don't start with:\n '%s'") %
|
||||
(cleaned, expect[:-1]))
|
||||
else:
|
||||
if cleaned != expect:
|
||||
raise AssertionError(("completions:\n '%s'\n"
|
||||
"don't match:\n '%s'") %
|
||||
(cleaned, expect))
|
||||
|
||||
complete("nilmtool -u ", "")
|
||||
complete("nilmtool list ", "-h,--help,-E,--ext*")
|
||||
complete("nilmtool list --st", "--start ")
|
||||
complete("nilmtool list --start ", "")
|
||||
complete("nilmtool list /", "/newton/prep,/newton/raw*")
|
||||
complete("nilmtool create /foo int3", "int32_1,int32_2*")
|
||||
complete("nilmtool metadata /newton/raw --get a",
|
||||
"a_𝓴𝓮𝔂,a_key,a_𝗸𝗲𝘆")
|
||||
complete("nilmtool metadata /newton/raw --set a",
|
||||
"a_𝓴𝓮𝔂=value,a_key=𝓿𝓪𝓵𝓾𝓮,a_𝗸𝗲𝘆=𝘃𝗮𝗹𝘂𝗲")
|
||||
complete("nilmtool metadata /newton/raw --set a_𝗸", "a_𝗸𝗲𝘆=𝘃𝗮𝗹𝘂𝗲 ")
|
||||
complete("nilmtool metadata '' --set a", "")
|
||||
self.run("list")
|
||||
|
|
Loading…
Reference in New Issue
Block a user