async def test_target_dispatch_with_given_event_path(targets): first, _, third, fourth = targets calls = [] async def capture_click_handler(event: Event) -> None: nonlocal calls calls.append('capture') async def bubble_click_handler(event: Event) -> None: nonlocal calls calls.append('bubble') first.listen('click', capture_click_handler, True) assert capture_click_handler in first._capture_listeners['click'] fourth.listen('click', bubble_click_handler) assert bubble_click_handler in fourth._bubble_listeners['click'] assert fourth.parent.parent == first event = Event('Mouse', 'click', y=9, x=7) event.path = [ fourth, third ] await fourth.dispatch(event) # Dispatch assert len(first._capture_listeners['click']) == 1 assert len(fourth._bubble_listeners['click']) == 1 assert calls == ['bubble']
async def test_listbox_page_up(root): data = [['001', 'Hugo', '*****@*****.**'], ['002', 'Paco', '*****@*****.**'], ['003', 'Luis', '*****@*****.**'], ['004', 'Juan', '*****@*****.**'], ['005', 'Nico', '*****@*****.**'], ['006', 'Luka', '*****@*****.**'], ['007', 'Mark', '*****@*****.**'], ['008', 'Paul', '*****@*****.**'], ['009', 'Mike', '*****@*****.**'], ['010', 'Fran', '*****@*****.**'], ['011', 'Karl', '*****@*****.**'], ['012', 'Marx', '*****@*****.**'], ['013', 'Anne', '*****@*****.**'], ['014', 'Luke', '*****@*****.**']] connect_called = False def mock_connect(self): nonlocal connect_called connect_called = True return self listbox = Listbox(root, data=data, limit=4, offset=8) listbox.connect = MethodType(mock_connect, listbox) assert listbox.offset == 8 await listbox.dispatch(Event('Keyboard', 'keydown', key='A')) await listbox.dispatch(Event('Keyboard', 'keydown', key=chr(339))) assert listbox.offset == 4 assert connect_called is True await listbox.dispatch(Event('Keyboard', 'keydown', key=chr(339))) assert listbox.offset == 0 await listbox.dispatch(Event('Keyboard', 'keydown', key=chr(339))) assert listbox.offset == 0
async def test_modal_middle_button_close(root): close_modal_called = False async def close_modal(event: Event): nonlocal close_modal_called close_modal_called = True modal = Modal(root, done_command=close_modal) modal.build() await modal.close.dispatch(Event('Mouse', 'click', button=1)) await modal.close.dispatch(Event('Mouse', 'click', button=2)) assert close_modal_called is True
async def test_entry_character(entry): entry.canvas.move(6, 0) assert len(entry.canvas.buffer[6]) == 61 event = Event('Keyboard', 'keydown', key='A', data='A') await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (6, 2) assert len(entry.canvas.buffer[6]) == 63 assert entry.canvas.content == ("Lorem ipsum dolor sit amet, c\n" "ac felis enim. Praesent facil\n" "et quis elit. Quisque nec mol\n" "ut interdum vitae, hendrerit \n" "eu auctor enim. Etiam a phare\n" "at aliquam metus rhoncus in. \n" "AAmollis orci. Cras quis matt\n" "tristique senectus et netus e\n" "Donec scelerisque nec tellus \n" "ut tincidunt. Morbi et libero\n") entry.canvas.move(0, 28) event = Event('Keyboard', 'keydown', key='W', data='W') await entry.canvas.dispatch(event) assert entry.canvas.content == ("orem ipsum dolor sit amet, Wc\n" "c felis enim. Praesent facili\n" "t quis elit. Quisque nec mole\n" "t interdum vitae, hendrerit s\n" "u auctor enim. Etiam a pharet\n" "t aliquam metus rhoncus in. N\n" "Amollis orci. Cras quis matti\n" "ristique senectus et netus et\n" "onec scelerisque nec tellus s\n" "t tincidunt. Morbi et libero \n") entry.canvas.setup(content='') entry.render() entry.canvas.base_x = 0 entry.canvas.base_y = 0 entry.canvas.move(0, 0) event = Event('Keyboard', 'keydown', key='Z', data='Z') await entry.canvas.dispatch(event) assert entry.canvas.buffer[0] == 'Z'
def test_event_instantiation_arguments(): event = Event('Custom', 'alert', y=5, x=3, details={'hello': 'world'}) assert event.category == 'Custom' assert event.type == 'alert' assert event.y == 5 assert event.x == 3 assert event.details == {'hello': 'world'}
async def test_entry_backspace(entry): entry.canvas.move(4, 2) assert len(entry.canvas.buffer[4]) == 67 event = Event('Keyboard', 'keydown', key=chr(curses.KEY_BACKSPACE)) await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (4, 0) assert len(entry.canvas.buffer[4]) == 65 assert len(entry.canvas.buffer) == 11 assert entry.canvas.content == ("Lorem ipsum dolor sit amet, c\n" "ac felis enim. Praesent facil\n" "et quis elit. Quisque nec mol\n" "ut interdum vitae, hendrerit \n" " auctor enim. Etiam a pharetr\n" "at aliquam metus rhoncus in. \n" "mollis orci. Cras quis mattis\n" "tristique senectus et netus e\n" "Donec scelerisque nec tellus \n" "ut tincidunt. Morbi et libero\n") entry.canvas.move(1, 0) await entry.canvas.dispatch(event) assert len(entry.canvas.buffer) == 10 assert entry.canvas.cursor() == (0, 5) assert entry.canvas.content == ("cenasac felis enim. Praesent \n" "utate\n" "acus,\n" "magna\n" " amet\n" "i\n" "stas.\n" " justo\n" "\n" "\n") entry.canvas.base_y = 0 entry.canvas.base_x = 40 entry.render() entry.canvas.move(1, 1) await entry.canvas.dispatch(event) assert entry.canvas.base_x == 39 assert entry.canvas.content == (' adipiscing elit. Maecenasac \n' 'm Nunc sem est, vulputate\n' 'gue. In vel iaculis lacus,\n' 'ras scelerisque erat magna\n' 'e sodales mauris, sit amet\n' 'ntesque habitant morbi\n' 'a fames ac turpis egestas.\n' 't. Mauris eleifend et justo\n' ' efficitur odio eu,\n' '\n')
async def test_entry_up(entry): entry.canvas.move(4, 4) event = Event('Keyboard', 'keydown', key=chr(curses.KEY_UP)) await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (2, 4) entry.canvas.base_y = 1 entry.render() assert entry.canvas.content == ("ac felis enim. Praesent facil\n" "et quis elit. Quisque nec mol\n" "ut interdum vitae, hendrerit \n" "eu auctor enim. Etiam a phare\n" "at aliquam metus rhoncus in. \n" "mollis orci. Cras quis mattis\n" "tristique senectus et netus e\n" "Donec scelerisque nec tellus \n" "ut tincidunt. Morbi et libero\n" "iaculis dui.\n") entry.canvas.move(0, 0) await entry.canvas.dispatch(event) assert entry.canvas.content == ("Lorem ipsum dolor sit amet, c\n" "ac felis enim. Praesent facil\n" "et quis elit. Quisque nec mol\n" "ut interdum vitae, hendrerit \n" "eu auctor enim. Etiam a phare\n" "at aliquam metus rhoncus in. \n" "mollis orci. Cras quis mattis\n" "tristique senectus et netus e\n" "Donec scelerisque nec tellus \n" "ut tincidunt. Morbi et libero\n") entry.canvas.base_x = 40 entry.canvas.render() entry.canvas.move(7, 25) assert entry.canvas.cursor() == (7, 25) assert entry.canvas.content == ("adipiscing elit. Maecenas\n" "vitae nunc posuere volutpat\n" ". Nunc sem est, vulputate\n" "ue. In vel iaculis lacus,\n" "Cras scelerisque erat magna\n" " sodales mauris, sit amet\n" "tesque habitant morbi\n" " fames ac turpis egestas.\n" ". Mauris eleifend et justo\n" "efficitur odio eu,\n") await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (6, 1)
async def test_entry_on_click(root): entry = Entry(root, content='QWERTY') root.render() event = Event('Mouse', 'click', y=10, x=10) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (0, 6)
def test_target_not_hit(): event = Event('Mouse', 'click', y=3, x=15) target = Target() target._y_min = 1 target._x_min = 6 target._y_max = 5 target._x_max = 10 hit = target.hit(event) assert hit is False
async def test_listbox_focus_on_click(root): listbox = Listbox(root) focus_called = False def mock_focus(self): nonlocal focus_called focus_called = True return self listbox.focus = MethodType(mock_focus, listbox) event = Event('Mouse', 'click') await listbox.dispatch(event) assert focus_called is True event.target = Target() await listbox.on_click(event) await asyncio.sleep(0) await listbox.dispatch(event)
async def test_entry_enter(entry): entry.canvas.move(3, 0) assert len(entry.canvas.buffer[3]) == 65 assert len(entry.canvas.buffer[4]) == 67 assert len(entry.canvas.buffer) == 11 event = Event('Keyboard', 'keydown', key='\n') await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert len(entry.canvas.buffer[3]) == 0 assert len(entry.canvas.buffer[4]) == 0 assert entry.canvas.cursor() == (5, 0) assert len(entry.canvas.buffer) == 13
async def test_listbox_command(root): data = ['first', 'second', 'third'] clicked_item = None async def on_click(event: Event) -> None: nonlocal clicked_item clicked_item = event.target listbox = Listbox(root, data=data, command=on_click).render() await listbox.children[2].dispatch(Event('Mouse', 'click', y=15, x=45)) assert len(listbox.children) == 3 assert clicked_item == listbox.children[2]
async def test_button_command(root): command_called = False async def custom_command(event: Event): nonlocal command_called command_called = True button = Button(root, content='Accept', command=custom_command) event = Event('Custom', 'click') await button.dispatch(event) assert button.content == 'Accept' assert command_called is True
def test_event_instantiation_defaults(): event = Event('Mouse', 'click') assert event.category == 'Mouse' assert event.type == 'click' assert event.y == 0 assert event.x == 0 assert event.key == '' assert event.data == '' assert event.button == 0 assert event.bubbles is True assert event.stop is False assert event.details == {} assert event.phase == '' assert event.path == [] assert event.current is None assert event.target is None
async def test_modal_done_external(root): modal = Modal(root).render() external_event_details = None async def external_handler(event: Event): nonlocal external_event_details external_event_details = event.details modal.setup(done_command=None).listen('done', external_handler).connect() await modal.close.dispatch(Event('Mouse', 'click')) await asyncio.sleep(1 / 15) assert external_event_details == {'result': 'closed'} assert len(modal.close._bubble_listeners) == 1
async def test_entry_delete(entry): entry.canvas.move(8, 2) assert len(entry.canvas.buffer[8]) == 66 event = Event('Keyboard', 'keydown', key=chr(curses.KEY_DC)) await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (8, 2) assert len(entry.canvas.buffer[8]) == 64 entry.canvas.base_y = 0 entry.canvas.base_x = 50 entry.canvas.render() assert len(entry.canvas.buffer) == 11 assert entry.canvas.content == (" elit. Maecenas\n" " posuere volutpat\n" " est, vulputate\n" " iaculis lacus,\n" "risque erat magna\n" "auris, sit amet\n" "itant morbi\n" "turpis egestas.\n" "ifend et justo\n" "odio eu,\n") entry.canvas.move(3, 15) await entry.canvas.dispatch(event) assert len(entry.canvas.buffer) == 10 assert entry.canvas.cursor() == (3, 15) assert entry.canvas.content == (" elit. Maecenas\n" " posuere volutpat\n" " est, vulputate\n" " iaculis lacus,eu auctor enim\n" "auris, sit amet\n" "itant morbi\n" "turpis egestas.\n" "ifend et justo\n" "odio eu,\n" "\n")
async def test_target_dispatch_event_stop_capturing(targets): first, _, third, fourth = targets calls = [] async def capture_click_handler(event: Event) -> None: nonlocal calls calls.append('capture') async def bubble_click_handler(event: Event) -> None: nonlocal calls calls.append('bubble') async def stop_click_handler(event: Event) -> None: nonlocal calls calls.append('capture:stopped') event.stop = True first.listen('click', capture_click_handler, True) assert capture_click_handler in first._capture_listeners['click'] third.listen('click', stop_click_handler, True) assert stop_click_handler in third._capture_listeners['click'] assert third.parent == first fourth.listen('click', capture_click_handler, True) fourth.listen('click', bubble_click_handler) assert capture_click_handler in fourth._capture_listeners['click'] assert bubble_click_handler in fourth._bubble_listeners['click'] assert fourth.parent.parent == first event = Event('Mouse', 'click', y=9, x=7) await fourth.dispatch(event) # Dispatch assert len(first._capture_listeners['click']) == 1 assert len(third._bubble_listeners['click']) == 0 assert len(third._capture_listeners['click']) == 1 assert len(fourth._capture_listeners['click']) == 1 assert len(fourth._bubble_listeners['click']) == 1 assert calls == ['capture', 'capture:stopped']
async def test_modal_done_modal(root): async def done_modal(event: Event): pass modal = Modal(root, done_command=done_modal).render() assert done_modal is modal.done_command event_details = None async def new_done_modal(event: Event): nonlocal event_details event_details = event.details modal.setup(done_command=new_done_modal).connect() await asyncio.sleep(1 / 15) await modal.close.dispatch(Event('Mouse', 'click')) assert event_details == {'result': 'closed'}
async def test_entry_left(entry): entry.canvas.move(2, 4) event = Event('Keyboard', 'keydown', key=chr(curses.KEY_LEFT)) await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.cursor() == (2, 2) entry.canvas.base_x = 2 entry.render() assert entry.canvas.content == ("rem ipsum dolor sit amet, con\n" " felis enim. Praesent facilis\n" " quis elit. Quisque nec moles\n" " interdum vitae, hendrerit so\n" " auctor enim. Etiam a pharetr\n" " aliquam metus rhoncus in. Nu\n" "llis orci. Cras quis mattis e\n" "istique senectus et netus et \n" "nec scelerisque nec tellus se\n" " tincidunt. Morbi et libero v\n") entry.canvas.move(0, 0) await entry.canvas.dispatch(event) await entry.canvas.dispatch(event) assert entry.canvas.content == ("Lorem ipsum dolor sit amet, c\n" "ac felis enim. Praesent facil\n" "et quis elit. Quisque nec mol\n" "ut interdum vitae, hendrerit \n" "eu auctor enim. Etiam a phare\n" "at aliquam metus rhoncus in. \n" "mollis orci. Cras quis mattis\n" "tristique senectus et netus e\n" "Donec scelerisque nec tellus \n" "ut tincidunt. Morbi et libero\n")
async def stop_click_handler(event: Event) -> None: nonlocal calls calls.append('capture:stopped') event.stop = True