feat(cli): improve file discovery and completion
- Render remote files as an aligned table with JSON and TSV alternatives. - Add Bash and Zsh completion for commands, options, paths, and remote files. - Allow downloads by exact filename while rejecting ambiguous duplicate names. - Cover table formatting, completion scripts, and selector resolution with tests.
This commit is contained in:
@@ -8,6 +8,8 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'cli'))
|
||||
|
||||
from nanoshare_client import cli
|
||||
from nanoshare_client.auth import _CallbackServer
|
||||
from nanoshare_client.completion import script as completion_script
|
||||
from nanoshare_client.table import format_table
|
||||
|
||||
class FakeClient:
|
||||
def __init__(self):
|
||||
@@ -55,6 +57,53 @@ def test_sync_uploads_new_local_file_and_writes_state(tmp_path, monkeypatch):
|
||||
state = json.loads((tmp_path / '.nanoshare-sync' / 'state.json').read_text())
|
||||
assert state['files']['hello.txt']['file_id'] == 'file_1'
|
||||
|
||||
def test_completion_scripts_include_commands():
|
||||
zsh = completion_script('zsh')
|
||||
bash = completion_script('bash')
|
||||
|
||||
assert 'compdef _nanoshare nanoshare' in zsh
|
||||
assert 'complete -F _nanoshare nanoshare' in bash
|
||||
assert 'login upload list download sync watch completion' in zsh
|
||||
assert 'login upload list download sync watch completion' in bash
|
||||
|
||||
def test_resolve_remote_file_accepts_id_or_exact_name():
|
||||
files = [
|
||||
{'file_id': 'file_1', 'file_name': 'report.pdf'},
|
||||
{'file_id': 'file_2', 'file_name': 'photo.png'},
|
||||
]
|
||||
|
||||
assert cli._resolve_remote_file(files, 'file_1')['file_name'] == 'report.pdf'
|
||||
assert cli._resolve_remote_file(files, 'photo.png')['file_id'] == 'file_2'
|
||||
|
||||
def test_resolve_remote_file_rejects_duplicate_names():
|
||||
files = [
|
||||
{'file_id': 'file_1', 'file_name': 'report.pdf'},
|
||||
{'file_id': 'file_2', 'file_name': 'report.pdf'},
|
||||
]
|
||||
|
||||
try:
|
||||
cli._resolve_remote_file(files, 'report.pdf')
|
||||
except RuntimeError as exc:
|
||||
assert 'multiple remote files' in str(exc)
|
||||
else:
|
||||
raise AssertionError('expected duplicate names to raise')
|
||||
|
||||
def test_format_table_aligns_columns():
|
||||
output = format_table(
|
||||
['ID', 'Name', 'Size'],
|
||||
[
|
||||
['abc', 'short.txt', '1 KB'],
|
||||
['longer-id', 'a much longer file name.png', '22 MB'],
|
||||
],
|
||||
)
|
||||
|
||||
assert output.splitlines() == [
|
||||
'ID Name Size',
|
||||
'--------- --------------------------- -----',
|
||||
'abc short.txt 1 KB',
|
||||
'longer-id a much longer file name.png 22 MB',
|
||||
]
|
||||
|
||||
def test_login_callback_returns_without_waiting_for_timeout():
|
||||
server = _CallbackServer('127.0.0.1', 0, 'expected-state')
|
||||
result = {}
|
||||
|
||||
Reference in New Issue
Block a user