Commit b653b329 authored by Michał Góral's avatar Michał Góral

Merge branch 'test-actions' into 'master'

Added tests for actions.

See merge request !5
parents 98ba278a d52098cd
Pipeline #9942442 passed with stage
in 3 minutes and 56 seconds
......@@ -42,32 +42,22 @@ class CommandMapping:
return name
class UnhandledAction(Exception):
'''Base class of exceptions called when handling action is impossible.'''
def handle_key(key, actions, cmd_map, default=None):
'''Handles a given key according to the rules of a `actions` dictionary and
urwid's command map (`cmd_map`). If a given key cannot be handled, calls
returns `default()` or a key otherwise (according to urwid rules of handling
action_name = cmd_map[key]
return handle_action(action_name, actions, cmd_map)
except UnhandledAction:
if default is not None:
return default()
return key
def handle_action(action_name, actions, cmd_map, default=None):
'''Call an action with a given name from actions map. If it's impossible to
call any action, raises UnhandledAction exception.'''
action = actions.get(action_name, default)
if action is not None:
action_name = cmd_map[key]
except KeyError: # support for both urwid.CommandMap and ordinary dict
action_name = None
action = actions.get(action_name)
if action:
return action()
raise UnhandledAction(action_name)
if default is not None:
return default()
return key
class CommandHandler:
......@@ -79,7 +69,7 @@ class CommandHandler:
'''Register action under a given name as a valid command.'''
def register_actions(self, action_mapping, obj):
def register_actions(self, action_mapping):
'''Register multiple actions at once. `action_mapping` is a dict-like
for name, fn in action_mapping.items():
......@@ -298,7 +298,7 @@ class ArticleList(urwid.ListBox):
'star-toggle': self._toggle_star_current,
display.cmd_handler.register_actions(self._actions, self)
self._indicators_count = 0
......@@ -601,7 +601,7 @@ class DisplayController(urwid.Columns):
'sync': self._sync
self.cmd_handler.register_actions(self._actions, self)
urwid.connect_signal(self._menu, 'active_changed',
from unittest.mock import Mock, call
import pytest
import feedcommas.actions as actions
def manager():
manager = Mock()
manager.attach_mock(Mock(), 'foo')
manager.attach_mock(Mock(), 'bar')
manager.attach_mock(Mock(), 'baz')
manager.attach_mock(Mock(), 'foobar')
return manager
def action_map(manager):
return {
'baz': manager.baz,
'foobar': manager.foobar,
def command_map():
return {
'f': 'foo',
'b': 'bar',
'B': 'baz',
'F': 'foobar'
def handler(action_map):
ret = actions.CommandHandler()
return ret
def test_command_handler_call(handler, manager):'foo')'baz')'foob')'foobar')'bar')
assert manager.mock_calls == [, call.baz(), call.foobar(),
def test_command_handler_call_ambiguous(handler, manager):'fo')
assert manager.mock_calls == []'ba')
assert manager.mock_calls == []
def test_command_handler_get_abbrev_names(handler, manager):
assert sorted(handler.get_abbrev_names('foo')) == ['foo', 'foobar']
assert sorted(handler.get_abbrev_names('f')) == ['foo', 'foobar']
assert sorted(handler.get_abbrev_names('foob')) == ['foobar']
assert sorted(handler.get_abbrev_names('ba')) == ['bar', 'baz']
assert sorted(handler.get_abbrev_names('')) == ['bar', 'baz', 'foo',
assert handler.get_abbrev_names('ladsfhadsfhdsaf') == []
assert handler.get_abbrev_names('foobarbaz') == []
assert manager.mock_calls == []
def test_handle_key(command_map, action_map, manager):
assert actions.handle_key('b', action_map, command_map) == \
assert manager.mock_calls == []
assert actions.handle_key('B', action_map, command_map) == \
assert manager.mock_calls == [call.baz()]
assert actions.handle_key('f', action_map, command_map) == \
assert manager.mock_calls == []
assert actions.handle_key('F', action_map, command_map) == \
assert manager.mock_calls == [call.foobar()]
def test_handle_not_mapped_key(command_map, action_map, manager):
default = Mock()
assert actions.handle_key('u', action_map, command_map) == 'u'
assert actions.handle_key('u', action_map, command_map, default) == \
assert manager.mock_calls == []
assert default.called
for key in 'fbFB':
assert actions.handle_key(key, {}, command_map) == key
assert actions.handle_key(key, action_map, {}) == key
assert manager.mock_calls == []
assert actions.handle_key(key, {}, command_map, default) == \
assert manager.mock_calls == []
assert default.called
assert actions.handle_key(key, action_map, {}, default) == \
assert manager.mock_calls == []
assert default.called
def test_CommandMapping():
mapping = actions.CommandMapping()
assert mapping['nav-up'] == 'cursor up'
assert mapping['nav-down'] == 'cursor down'
assert mapping['nav-left'] == 'cursor left'
assert mapping['nav-right'] == 'cursor right'
assert mapping['Nav-Right'] == 'Nav-Right'
assert mapping['foobar'] == 'foobar'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment