1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#!/usr/bin/env python
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
from . import BaseTest
class TestCommandPalette(BaseTest):
def test_collect_keys_data(self):
from kittens.command_palette.main import collect_keys_data
from kitty.actions import groups
opts = self.set_options()
data = collect_keys_data(opts)
self.assertIn('modes', data)
self.assertIn('mouse', data)
self.assertIn('', data['modes'], 'Default keyboard mode should be present')
default_mode = data['modes']['']
# Should have at least some categories
self.assertTrue(len(default_mode) > 0, 'Should have at least one category')
# All category names should be from the known groups
known_titles = set(groups.values())
for cat_name in default_mode:
self.assertIn(cat_name, known_titles, f'Unknown category: {cat_name}')
# Each category should have bindings with required fields
for cat_name, bindings in default_mode.items():
self.assertIsInstance(bindings, list)
for b in bindings:
self.assertIn('key', b)
self.assertIn('action', b)
self.assertIn('action_display', b)
self.assertIn('definition', b)
self.assertIn('help', b)
self.assertIn('long_help', b)
self.assertIsInstance(b['key'], str)
self.assertIsInstance(b['action'], str)
# key may be empty for unmapped actions; action must always be non-empty
self.assertTrue(len(b['action']) > 0)
# Mouse mappings
self.assertIsInstance(data['mouse'], list)
for b in data['mouse']:
self.assertIn('key', b)
self.assertIn('action', b)
self.assertIn('action_display', b)
def test_collect_keys_categories_ordered(self):
from kittens.command_palette.main import collect_keys_data
from kitty.actions import groups
opts = self.set_options()
data = collect_keys_data(opts)
default_mode = data['modes']['']
cat_names = list(default_mode.keys())
group_titles = list(groups.values())
# Categories should appear in the same order as defined in groups
indices = []
for cat in cat_names:
if cat in group_titles:
indices.append(group_titles.index(cat))
self.ae(indices, sorted(indices), 'Categories should be ordered according to groups dict')
def test_collect_keys_bindings_sorted(self):
from kittens.command_palette.main import collect_keys_data
opts = self.set_options()
data = collect_keys_data(opts)
# Within each category, mapped entries (non-empty key) come first sorted by key,
# then unmapped entries (empty key) sorted by action name.
for cat_name, bindings in data['modes'][''].items():
seen_unmapped = False
for b in bindings:
if b['key'] == '':
seen_unmapped = True
elif seen_unmapped:
self.fail(
f'In category {cat_name!r}, mapped binding {b!r} follows an unmapped one'
)
def test_collect_keys_has_help_text(self):
from kittens.command_palette.main import collect_keys_data
opts = self.set_options()
data = collect_keys_data(opts)
# At least some bindings should have help text
has_help = False
for cat_name, bindings in data['modes'][''].items():
for b in bindings:
if b['help']:
has_help = True
break
if has_help:
break
self.assertTrue(has_help, 'At least some bindings should have help text')
def test_ordering_arrays_present(self):
from kittens.command_palette.main import collect_keys_data
opts = self.set_options()
data = collect_keys_data(opts)
# mode_order should list all modes
self.assertIn('mode_order', data)
self.assertIsInstance(data['mode_order'], list)
self.ae(set(data['mode_order']), set(data['modes'].keys()))
# category_order should list categories for each mode
self.assertIn('category_order', data)
self.assertIsInstance(data['category_order'], dict)
for mode_name in data['modes']:
self.assertIn(mode_name, data['category_order'])
self.ae(
set(data['category_order'][mode_name]),
set(data['modes'][mode_name].keys()),
f'category_order for mode {mode_name!r} should match modes keys',
)
def test_always_includes_unmapped_actions(self):
from kittens.command_palette.main import collect_keys_data
opts = self.set_options()
data = collect_keys_data(opts)
# Unmapped actions (empty key) are always included
found_unmapped = False
for cats in data['modes'].values():
for bindings in cats.values():
for b in bindings:
if b['key'] == '':
found_unmapped = True
# Unmapped actions must still have action and definition
self.assertTrue(len(b['action']) > 0)
self.assertTrue(len(b['definition']) > 0)
break
self.assertTrue(found_unmapped, 'Expected at least one unmapped action to always be present')
def test_unmapped_actions_sorted_order(self):
from kittens.command_palette.main import collect_keys_data
opts = self.set_options()
data = collect_keys_data(opts)
# In each category, mapped bindings (non-empty key) should come before unmapped ones
for cat_name, bindings in data['modes'].get('', {}).items():
seen_unmapped = False
for b in bindings:
if b['key'] == '':
seen_unmapped = True
elif seen_unmapped:
self.fail(
f'In category {cat_name!r}, mapped binding {b!r} follows an unmapped one'
)
|