mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 09:48:09 +02:00
Clearance of multicell tests
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
// TODO: Handle replay of dumped graphics_command and multicell_command
|
// TODO: Handle replay of dumped graphics_command and multicell_command
|
||||||
// TODO: Handle rewrap of multiline chars
|
// TODO: Handle rewrap of multiline chars
|
||||||
// TODO: Handle rewrap when a character is too wide/tall to fit on resized screen
|
// TODO: Handle rewrap when a character is too wide/tall to fit on resized screen
|
||||||
|
// TODO: Test serialization to ansi only using escape code for explicitly set multicells
|
||||||
|
|
||||||
typedef union CellAttrs {
|
typedef union CellAttrs {
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -1044,9 +1044,11 @@ draw_text_loop(Screen *self, const uint32_t *chars, size_t num_chars, text_loop_
|
|||||||
RAII_ListOfChars(lc);
|
RAII_ListOfChars(lc);
|
||||||
lc.chars[lc.count++] = ch;
|
lc.chars[lc.count++] = ch;
|
||||||
lc.chars[lc.count++] = mcd.val;
|
lc.chars[lc.count++] = mcd.val;
|
||||||
|
CPUCell *second = fc + 1;
|
||||||
|
if (second->is_multicell) nuke_multicell_char_at(self, self->cursor->x + 1, self->cursor->y, true);
|
||||||
cell_set_chars(fc, self->text_cache, &lc);
|
cell_set_chars(fc, self->text_cache, &lc);
|
||||||
fc->x = 0; fc->y = 0; fc->is_multicell = true;
|
fc->x = 0; fc->y = 0; fc->is_multicell = true;
|
||||||
*(fc + 1) = *fc; (fc + 1)->x = 1;
|
*second = *fc; second->x = 1;
|
||||||
s->gp[self->cursor->x + 1] = s->gp[self->cursor->x];
|
s->gp[self->cursor->x + 1] = s->gp[self->cursor->x];
|
||||||
self->cursor->x += 2;
|
self->cursor->x += 2;
|
||||||
} else {
|
} else {
|
||||||
@@ -1167,6 +1169,7 @@ screen_handle_multicell_command(Screen *self, const MultiCellCommand *cmd, const
|
|||||||
CPUCell c = s.cc;
|
CPUCell c = s.cc;
|
||||||
c.ch_is_idx = true; c.ch_or_idx = tc_get_or_insert_chars(self->text_cache, self->lc);
|
c.ch_is_idx = true; c.ch_or_idx = tc_get_or_insert_chars(self->text_cache, self->lc);
|
||||||
c.is_multicell = true;
|
c.is_multicell = true;
|
||||||
|
nuke_multicell_char_intersecting_with(self, self->cursor->x, self->cursor->x + width, self->cursor->y, self->cursor->y + height, true);
|
||||||
for (index_type y = self->cursor->y; y < self->cursor->y + height; y++) {
|
for (index_type y = self->cursor->y; y < self->cursor->y + height; y++) {
|
||||||
linebuf_init_cells(self->linebuf, y, &s.cp, &s.gp);
|
linebuf_init_cells(self->linebuf, y, &s.cp, &s.gp);
|
||||||
linebuf_mark_line_dirty(self->linebuf, y);
|
linebuf_mark_line_dirty(self->linebuf, y);
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ def test_multicell(self: TestMulticell) -> None:
|
|||||||
def ac(x_, y_, **assertions): # assert cell
|
def ac(x_, y_, **assertions): # assert cell
|
||||||
cell = s.cpu_cells(y_, x_)
|
cell = s.cpu_cells(y_, x_)
|
||||||
msg = f'Assertion failed for cell at ({x_}, {y_})\n{cell}\n'
|
msg = f'Assertion failed for cell at ({x_}, {y_})\n{cell}\n'
|
||||||
if 'is_multicell' in assertions:
|
|
||||||
if assertions['is_multicell']:
|
|
||||||
assert cell['mcd'] is not None, msg
|
|
||||||
else:
|
|
||||||
assert cell['mcd'] is None, msg
|
|
||||||
def ae(key):
|
def ae(key):
|
||||||
if key not in assertions:
|
if key not in assertions:
|
||||||
return
|
return
|
||||||
@@ -38,7 +33,8 @@ def test_multicell(self: TestMulticell) -> None:
|
|||||||
if mcd is None:
|
if mcd is None:
|
||||||
raise AssertionError(f'{msg}Unexpectedly not a multicell')
|
raise AssertionError(f'{msg}Unexpectedly not a multicell')
|
||||||
val = mcd[key]
|
val = mcd[key]
|
||||||
assert assertions[key] == val, f'{msg}{assertions[key]!r} != {val!r}'
|
if assertions[key] != val:
|
||||||
|
raise AssertionError(f'{msg}{assertions[key]!r} != {val!r}')
|
||||||
|
|
||||||
ae('x')
|
ae('x')
|
||||||
ae('y')
|
ae('y')
|
||||||
@@ -48,10 +44,30 @@ def test_multicell(self: TestMulticell) -> None:
|
|||||||
ae('vertical_align')
|
ae('vertical_align')
|
||||||
ae('text')
|
ae('text')
|
||||||
ae('explicitly_set')
|
ae('explicitly_set')
|
||||||
|
|
||||||
if 'cursor' in assertions:
|
if 'cursor' in assertions:
|
||||||
self.ae(assertions['cursor'], (s.cursor.x, s.cursor.y), msg)
|
self.ae(assertions['cursor'], (s.cursor.x, s.cursor.y), msg)
|
||||||
|
|
||||||
s = self.create_screen(cols=5, lines=5)
|
if 'is_multicell' in assertions:
|
||||||
|
q = cell['mcd']
|
||||||
|
if assertions['is_multicell']:
|
||||||
|
if q is None:
|
||||||
|
raise AssertionError(f'{msg}Unexpectedly not a multicell')
|
||||||
|
else:
|
||||||
|
if q is not None:
|
||||||
|
raise AssertionError(f'{msg}Unexpectedly is a multicell')
|
||||||
|
|
||||||
|
def count_multicells(with_text=''):
|
||||||
|
ans = 0
|
||||||
|
for y in range(s.lines):
|
||||||
|
for x in range(s.columns):
|
||||||
|
c = s.cpu_cells(y, x)
|
||||||
|
if c['mcd'] is not None and (not with_text or c['text'] == with_text):
|
||||||
|
ans += 1
|
||||||
|
return ans
|
||||||
|
|
||||||
|
# Test basic multicell drawing
|
||||||
|
s = self.create_screen(cols=6, lines=6)
|
||||||
ac(0, 0, is_multicell=False)
|
ac(0, 0, is_multicell=False)
|
||||||
multicell(s, 'a')
|
multicell(s, 'a')
|
||||||
ac(0, 0, is_multicell=True, width=1, scale=1, subscale=0, x=0, y=0, text='a', explicitly_set=True, cursor=(1, 0))
|
ac(0, 0, is_multicell=True, width=1, scale=1, subscale=0, x=0, y=0, text='a', explicitly_set=True, cursor=(1, 0))
|
||||||
@@ -60,4 +76,47 @@ def test_multicell(self: TestMulticell) -> None:
|
|||||||
ac(0, 0, is_multicell=True, width=1, scale=1, subscale=0, x=0, y=0, text='a', explicitly_set=True)
|
ac(0, 0, is_multicell=True, width=1, scale=1, subscale=0, x=0, y=0, text='a', explicitly_set=True)
|
||||||
ac(1, 0, is_multicell=True, width=2, scale=1, subscale=0, x=0, y=0, text='莊', explicitly_set=False, cursor=(3, 0))
|
ac(1, 0, is_multicell=True, width=2, scale=1, subscale=0, x=0, y=0, text='莊', explicitly_set=False, cursor=(3, 0))
|
||||||
ac(2, 0, is_multicell=True, width=2, scale=1, subscale=0, x=1, y=0, text='', explicitly_set=False)
|
ac(2, 0, is_multicell=True, width=2, scale=1, subscale=0, x=1, y=0, text='', explicitly_set=False)
|
||||||
ac(1, 0, is_multicell=False), ac(1, 1, is_multicell=False)
|
for x in range(s.columns):
|
||||||
|
ac(x, 1, is_multicell=False)
|
||||||
|
s.cursor.x = 0
|
||||||
|
multicell(s, 'a', width=2, scale=2, subscale=3)
|
||||||
|
ac(0, 0, is_multicell=True, width=2, scale=2, subscale=3, x=0, y=0, text='a', explicitly_set=True, cursor=(4, 0))
|
||||||
|
for x in range(1, 4):
|
||||||
|
ac(x, 0, is_multicell=True, width=2, scale=2, subscale=3, x=x, y=0, text='', explicitly_set=True)
|
||||||
|
for x in range(0, 4):
|
||||||
|
ac(x, 1, is_multicell=True, width=2, scale=2, subscale=3, x=x, y=1, text='', explicitly_set=True)
|
||||||
|
|
||||||
|
# Test draw with cursor in a multicell
|
||||||
|
s.reset()
|
||||||
|
s.draw('莊')
|
||||||
|
s.cursor.x -= 1
|
||||||
|
s.draw('a'), ac(0, 0, is_multicell=False), ac(1, 0, is_multicell=False)
|
||||||
|
s.reset()
|
||||||
|
s.draw('莊')
|
||||||
|
s.cursor.x = 0
|
||||||
|
s.draw('a'), ac(0, 0, is_multicell=False), ac(1, 0, is_multicell=False)
|
||||||
|
s.reset()
|
||||||
|
multicell(s, 'a', width=2, scale=2, subscale=3)
|
||||||
|
s.cursor.x, s.cursor.y = 1, 1
|
||||||
|
s.draw('b')
|
||||||
|
self.ae(0, count_multicells())
|
||||||
|
s.reset()
|
||||||
|
s.cursor.x = 1
|
||||||
|
s.draw('莊')
|
||||||
|
s.cursor.x = 0
|
||||||
|
s.draw('莊')
|
||||||
|
ac(2, 0, is_multicell=False, text=' ')
|
||||||
|
|
||||||
|
# Test multicell with cursor in a multicell
|
||||||
|
def big_a(x, y):
|
||||||
|
s.reset()
|
||||||
|
s.cursor.x, s.cursor.y = 1, 1
|
||||||
|
multicell(s, 'a', scale=4)
|
||||||
|
s.cursor.x, s.cursor.y = x, y
|
||||||
|
multicell(s, 'b', scale=2)
|
||||||
|
self.ae(4, count_multicells())
|
||||||
|
for x in range(1, 5):
|
||||||
|
ac(x, 4, text=' ')
|
||||||
|
big_a(0, 0), big_a(1, 1), big_a(2, 2), big_a(5, 1)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ class TestParser(BaseTest):
|
|||||||
e('s', 'Malformed GraphicsCommand control block, no = after key')
|
e('s', 'Malformed GraphicsCommand control block, no = after key')
|
||||||
e('s=', 'Malformed GraphicsCommand control block, expecting an integer value')
|
e('s=', 'Malformed GraphicsCommand control block, expecting an integer value')
|
||||||
e('s==', 'Malformed GraphicsCommand control block, expecting an integer value for key: s')
|
e('s==', 'Malformed GraphicsCommand control block, expecting an integer value for key: s')
|
||||||
e('s=1=', 'Malformed GraphicsCommand control block, expecting a comma or semi-colon after a value, found: 0x3d')
|
e('s=1=', 'Malformed GraphicsCommand control block, expecting a , or semi-colon after a value, found: 0x3d')
|
||||||
|
|
||||||
def test_deccara(self):
|
def test_deccara(self):
|
||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
|
|||||||
Reference in New Issue
Block a user