Repository: pimutils/todoman
Pull request #163 (2017-03-02 13:24:52)

Add support for LOCATIONS(#11)
Add support for locations.

untitaker: One nitpick, LGTM otherwise!
untitaker: A changelog entry as well please, otherwise LGTM!

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f911460..e09293a 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -23,6 +23,7 @@ v3.0.0
 * Porcelain now outputs proper JSON, rather than one-JSON-per-line.
 * Increment sequence number upon edits.
 * Print a descriptive message when no lists are found.
+* Add full support for locations.
 
 v2.1.0
 ------
diff --git a/todoman/cli.py b/todoman/cli.py
index 27f220b..43c0df2 100644
--- a/todoman/cli.py
+++ b/todoman/cli.py
@@ -85,6 +85,8 @@ def _sort_callback(ctx, param, val):
 
 
 def _todo_property_options(command):
+    click.option('--location', help=('The location where '
+                 'this todo takes place.'))(command)
     click.option(
         '--due', '-d', default='', callback=_validate_date_param,
         help=('The due date of the task, in the format specified in the '
@@ -96,7 +98,7 @@ def _todo_property_options(command):
     @functools.wraps(command)
     def command_wrap(*a, **kw):
         kw['todo_properties'] = {key: kw.pop(key) for key in
-                                 ('due', 'start')}
+                                 ('due', 'start', 'location')}
         return command(*a, **kw)
 
     return command_wrap
diff --git a/todoman/ui.py b/todoman/ui.py
index 8e6c583..f650d04 100644
--- a/todoman/ui.py
+++ b/todoman/ui.py
@@ -270,7 +270,9 @@ class TodoFormatter:
         """
         rv = self.compact_multiple([todo])
         if todo.description:
-            rv = "{}\n\n{}".format(rv, todo.description)
+            rv = "{}\n\nDescription: {}".format(rv, todo.description)
+        if todo.location:
+            rv = "{}\n\nLocation: {}".format(rv, todo.location)
         return rv
 
     def _format_date(self, date, humanize=True):
@@ -314,13 +316,15 @@ class TodoFormatter:
         )))
 
     def parse_priority(self, priority):
+        if priority is None or priority is '':
+            return None
         if priority == 'low':
             return 9
         elif priority == 'medium':
             return 5
         elif priority == 'high':
             return 4
-        elif priority == 'none' or priority is None:
+        elif priority == 'none':
             return 0
         else:
             raise ValueError('Priority has to be one of low, medium,'
@@ -392,7 +396,7 @@ class PorcelainFormatter(TodoFormatter):
 
     def parse_priority(self, priority):
         if priority is None:
-            return 0
+            return None
         try:
             if int(priority) in range(0, 10):
                 return int(priority)


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 9cfed4a..a51e9ca 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -69,6 +69,19 @@ def now_for_tz():
     return inner
 
 
+@pytest.fixture
+def todo_factory(default_database):
+    def inner():
+        todo = model.FileTodo()
+        todo.list = list(default_database.lists())[0]
+        todo.summary = 'YARR!'
+        todo.save()
+
+        return todo
+
+    return inner
+
+
 settings.register_profile("ci", settings(
     max_examples=1000,
     verbosity=Verbosity.verbose,
diff --git a/tests/test_basic.py b/tests/test_basic.py
index 0aff3e3..8725679 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -438,5 +438,25 @@ def test_empty_list(tmpdir, runner, create):
 
     assert expected in result.output
 
+
+def test_show_location(tmpdir, runner, create):
+    create(
+        'test.ics',
+        'SUMMARY:harhar\n'
+        'LOCATION:Boston\n'
+    )
+
+    result = runner.invoke(cli, ['show', '1'])
+    assert 'Boston' in result.output
+
+
+def test_location(runner):
+    result = runner.invoke(cli, [
+        'new', '-l', 'default', '--location', 'Chembur', 'Event Test'
+    ])
+
+    assert 'Chembur' in result.output
+
+
 # TODO: test aware/naive datetime sorting
 # TODO: test --grep
diff --git a/tests/test_ui.py b/tests/test_ui.py
index 67b804f..57f8680 100644
--- a/tests/test_ui.py
+++ b/tests/test_ui.py
@@ -1,26 +1,24 @@
-from todoman.model import FileTodo
-from todoman.ui import PorcelainFormatter, TodoEditor
+import pytest
+from urwid import ExitMainLoop
 
+from todoman.ui import TodoEditor, TodoFormatter
 
-def test_todo_editor(default_database):
-    """
-    Tests TodoEditor
+DATE_FORMAT = "%d-%m-%y"
+TIME_FORMAT = "%H:%M"
 
-    While this is a pretty lame test, it's a lot better than nothing until we
-    have a proper testing framework for the interactive parts.
-
-    It basically makes sure that we don't refer to any obsolete methods, etc.
-    """
 
+def test_todo_editor_priority(default_database, todo_factory):
+    todo = todo_factory()
     lists = list(default_database.lists())
+    formatter = TodoFormatter(DATE_FORMAT, TIME_FORMAT, '')
 
-    todo = FileTodo(new=True)
-    todo.list = lists[0]
-    todo.summary = 'YARR!'
-    todo.save()
-
-    porcelain_formatter = PorcelainFormatter()
+    editor = TodoEditor(todo, lists, formatter)
+    editor._priority.edit_text = ''
 
-    editor = TodoEditor(todo, lists, porcelain_formatter)
+    with pytest.raises(ExitMainLoop):  # Look at editor._msg_text if this fails
+        editor._keypress('ctrl s')
 
-    editor._keypress('ctrl s')
+    # FileTodo exposes 0
+    assert todo.priority is 0
+    # The actual todo contains None
+    assert todo.todo.get('priority', None) is None