Commit 28dbb843 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'master' into reldate-cur-weekday

parents 33794435 f6a80405
[run] [run]
source = topydo source = topydo
branch = True
[report] [report]
exclude_lines = exclude_lines =
...@@ -11,5 +12,5 @@ exclude_lines = ...@@ -11,5 +12,5 @@ exclude_lines =
if __name__ == .__main__.: if __name__ == .__main__.:
omit = omit =
topydo/lib/ExitCommand.py topydo/commands/ExitCommand.py
topydo/lib/Version.py topydo/lib/Version.py
...@@ -14,11 +14,17 @@ matrix: ...@@ -14,11 +14,17 @@ matrix:
- python: "pypy" - python: "pypy"
- python: "pypy3" - python: "pypy3"
install: install:
- "python -m pip install pip --upgrade"
- "pip install ." - "pip install ."
- "pip install icalendar" - "pip install .[ical]"
- "pip install pylint" - "pip install .[test]"
script: "./run-tests.sh" - "pip install codecov"
script:
- "green -vvr"
- "python -m pylint --errors-only topydo test"
# Cache Dependencies # Cache Dependencies
after_script:
- codecov
cache: cache:
directories: directories:
- $HOME/travis/.cache/pip - $HOME/travis/.cache/pip
......
Main author / maintainer: Bram Schoenmakers (@bram85)
For a list of contributors, please refer to the Contributors page on
[Github](https://github.com/bram85/topydo/graphs/contributors).
0.7
---
* New subcommand: `revert`. Revert the last executed command(s). The number of
revisions can be tuned in the configuration file:
[topydo]
backup_count = 25
* New feature: aliases. Aliases can be defined in the configuration file:
[aliases]
showall = ls -x
(thanks to @mruwek)
* Filter based on priorities (thanks to @mruwek)
ls (A)
ls (<A)
* `ls` has a `-n` flag to limit the number of todo items (similar to the
list_limit option in the configuration file:
ls -n 5
* Prompt mode no longer warns about background modifications to todo.txt when a
read-only command is entered (e.g. `ls`).
* Removed restriction in `edit` mode that requires keeping the same amount of
lines in the todo.txt file.
* `edit` only processes the todo items when edits were actually made in the
editor.
* Bugfix: not all tags were properly hidden with the `hide_tags` configuration
option.
* Better PEP8 compliance (thanks to @MinchinWeb)
* Various test/CI improvements (thanks to @MinchinWeb)
* Support for Python 3.2 removed.
* Many other minor improvements (a.o. thanks to @MinchinWeb)
0.6 0.6
--- ---
...@@ -16,7 +54,9 @@ ...@@ -16,7 +54,9 @@
--- ---
* Remove 'ical' subcommand in favor of 'topydo ls -f ical' * Remove 'ical' subcommand in favor of 'topydo ls -f ical'
* Remove options highlight_projects_colors in favor of colorscheme options. In case you wish to disable the project/context colors, assign an empty value in the configuration file: * Remove options highlight_projects_colors in favor of colorscheme options. In
case you wish to disable the project/context colors, assign an empty value in
the configuration file:
[colorscheme] [colorscheme]
project_color = project_color =
......
...@@ -15,36 +15,38 @@ smoothly into topydo. ...@@ -15,36 +15,38 @@ smoothly into topydo.
possible. I won't be very picky about long lines, but please try to avoid possible. I won't be very picky about long lines, but please try to avoid
them. them.
* I strongly prefer simple and short functions, doing only one thing. I'll * I strongly prefer simple and short functions, doing only one thing. I'll
request you to refactor functions with massive indentation or don't fit ask you to refactor functions with massive indentation or don't fit
otherwise on a screen. otherwise on a screen.
### Testing ### Testing
* Run tests with: * First make sure to have the prerequisites installed to perform the tests:
./run-tests.sh [python2|python3] pip install .[test]
* Then, run the tests with:
green -r
Obviously, I won't accept anything that makes the tests fail. When you submit Obviously, I won't accept anything that makes the tests fail. When you submit
a Pull Request, Travis CI will automatically run all tests for various Python a Pull Request, Travis CI will automatically run all tests for various Python
versions, but it's better if you run the tests locally first. versions, but it's better if you run the tests locally first.
Make sure you have the `mock` package installed if you test on a Python
version older than 3.3.
* Add tests for your change(s): * Add tests for your change(s):
* Bugfixes: add a testcase that covers your bugfix, so the bug won't happen * Bugfixes: add a test case that covers your bugfix, so the bug won't happen
ever again. ever again.
* Features: add testcases that checks various inputs and outputs of your * Features: add test cases that checks various inputs and outputs of your
feature. Be creative in trying to break the feature you've just implemented. feature. Be creative in trying to break the feature you've just implemented.
* Check the test coverage of your contributed code, in particular if you * Check the test coverage of your contributed code, in particular if you touched
touched code in the topydo.lib or topydo.command packages: code in the topydo.lib or topydo.command packages:
pip install coverage coverage report -m
coverage run setup.py test
coverage report
Or alternatively, for a more friendly output, run: Or alternatively, for a more friendly output, run:
coverage html coverage html
Which will generate annotated files in the *htmlcov* folder. The new code which will generate annotated files in the *htmlcov* folder. The new code
should be marked green (i.e. covered). should be marked green (i.e. covered).
When you create a Pull Request, code coverage will be automatically checked
and reported by [Codecov.io](https://codecov.io/github/bram85/topydo).
topydo topydo
====== ======
[![Build Status](https://travis-ci.org/bram85/topydo.svg?branch=master)](https://travis-ci.org/bram85/topydo) [![Join the chat at https://gitter.im/bram85/topydo](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bram85/topydo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=bram85&url=https://github.com/bram85/topydo&title=topydo&language=&tags=github&category=software) [![Build Status](https://travis-ci.org/bram85/topydo.svg?branch=master)](https://travis-ci.org/bram85/topydo) [![codecov.io](https://codecov.io/github/bram85/topydo/coverage.svg?branch=master)](https://codecov.io/github/bram85/topydo?branch=master) [![Join the chat at https://gitter.im/bram85/topydo](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bram85/topydo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=bram85&url=https://github.com/bram85/topydo&title=topydo&language=&tags=github&category=software)
topydo is a todo list application using the [todo.txt format][1]. It is heavily topydo is a todo list application using the [todo.txt format][1]. It is heavily
inspired by the [todo.txt CLI][2] by Gina Trapani. This tool is actually a inspired by the [todo.txt CLI][2] by Gina Trapani. This tool is actually a
......
#!/bin/bash
if [ "$1" = "python2" ] || [ "$1" = "python3" ]; then
PYTHON=$1
else
# run whatever is active
PYTHON=python
fi
# Run normal tests
if ! $PYTHON setup.py test; then
exit 1
fi
# pylint is not supported on 3.2, so skip the test there
if $PYTHON --version 2>&1 | grep 'Python 3\.2' > /dev/null; then
exit 0
fi
if ! $PYTHON -m pylint --errors-only topydo test; then
exit 1
fi
exit 0
...@@ -34,9 +34,12 @@ setup( ...@@ -34,9 +34,12 @@ setup(
], ],
extras_require = { extras_require = {
':sys_platform=="win32"': ['colorama>=0.2.5'], ':sys_platform=="win32"': ['colorama>=0.2.5'],
':python_version=="2.7"': ['ushlex'],
'ical': ['icalendar'], 'ical': ['icalendar'],
'prompt-toolkit': ['prompt-toolkit >= 0.53'], 'prompt-toolkit': ['prompt-toolkit >= 0.53'],
'edit-cmd-tests': ['mock'], 'test': ['freezegun', 'coverage', 'green'],
'test:python_version=="2.7"': ['mock'],
'test:python_version!="3.2"': ['pylint'],
}, },
entry_points= { entry_points= {
'console_scripts': ['topydo = topydo.cli.UILoader:main'], 'console_scripts': ['topydo = topydo.cli.UILoader:main'],
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
class ConfigTest(TopydoTest):
def test_config1(self):
self.assertEqual(config("test/data/config1").default_command(), 'do')
def test_config2(self):
self.assertNotEqual(config("").default_command(), 'do')
def test_config3(self):
self.assertTrue(config("test/data/config2").ignore_weekends())
def test_config4(self):
""" Test that value in file is overridden by parameter. """
overrides = {
('topydo', 'default_command'): 'edit'
}
self.assertEqual(config("test/data/config1", p_overrides=overrides).default_command(), 'edit')
if __name__ == '__main__':
unittest.main()
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
......
[topydo]
colors = junk
[add]
auto_creation_date = junk
[ls]
indent = junk
list_limit = junk
human_readable_dates = junk
[sort]
keep_sorted = junk
ignore_weekends = junk
[dep]
append_parent_projects = junk
append_parent_contexts = junk
[colorscheme]
priority_colors = junk
project_color = junk
context_color = junk
metadata_color = junk
link_color = junk
[colorscheme]
; priority_colors = junk
; project_color = junk
; context_color = junk
; metadata_color = junk
; link_color = junk
Todo item with +project3 @context1
Todo item with +Project2 @Context2
Todo item with +project1 @context3
Todo item with +project1 @context3
Todo item with +Project2 @Context2
Todo item with +project3 @context1
Todo item with +Project2 @Context2
Todo item with +project1 @context3
Todo item with +project3 @context1
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
foo = rm -f test foo = rm -f test
baz = FooBar baz = FooBar
format = ls -F "|I| x c d {(}p{)} s k" -n 25 format = ls -F "|I| x c d {(}p{)} s k" -n 25
smile = ls
...@@ -20,7 +20,7 @@ from io import StringIO ...@@ -20,7 +20,7 @@ from io import StringIO
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands import AddCommand, ListCommand from topydo.commands import AddCommand, ListCommand
from topydo.lib import TodoList from topydo.lib import TodoList
from topydo.lib.Config import config from topydo.lib.Config import config
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.AppendCommand import AppendCommand from topydo.commands.AppendCommand import AppendCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from test.Facilities import load_file_to_todolist from test.facilities import load_file_to_todolist
from topydo.commands.ArchiveCommand import ArchiveCommand from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
import unittest import unittest
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Colors import NEUTRAL_COLOR, Colors from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config from topydo.lib.Config import config
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from unittest import skip
from test.topydo_testcase import TopydoTest
from topydo.lib.Config import config
class ConfigTest(TopydoTest):
def test_config01(self):
self.assertEqual(config("test/data/ConfigTest1.conf").default_command(), 'do')
def test_config02(self):
self.assertNotEqual(config("").default_command(), 'do')
def test_config03(self):
self.assertTrue(config("test/data/ConfigTest2.conf").ignore_weekends())
def test_config04(self):
""" Test that value in file is overridden by parameter. """
overrides = {
('topydo', 'default_command'): 'edit'
}
self.assertEqual(config("test/data/ConfigTest1.conf",
p_overrides=overrides).default_command(),
'edit')
def test_config05(self):
""" Bad colour switch value. """
# boolean settings must first be typecast to integers, because all
# strings evaulate to 'True'
self.assertEqual(config("test/data/ConfigTest4.conf").colors(),
bool(int(config().defaults["topydo"]["colors"])))
def test_config06(self):
""" Bad auto creation date switch value. """
self.assertEqual(config("test/data/ConfigTest4.conf").auto_creation_date(),
bool(int(config().defaults["add"]["auto_creation_date"])))
def test_config07(self):
""" Bad indent value. """
self.assertEqual(config("test/data/ConfigTest4.conf").list_indent(),
int(config().defaults["ls"]["indent"]))
def test_config08(self):
""" Bad list limit value. """
self.assertEqual(config("test/data/ConfigTest4.conf").list_limit(),
int(config().defaults["ls"]["list_limit"]))
def test_config10(self):
""" Bad keep sorted switch value. """
self.assertEqual(config("test/data/ConfigTest4.conf").keep_sorted(),
bool(int(config().defaults["sort"]["keep_sorted"])))
def test_config11(self):
""" Bad ignore weekends switch value. """
self.assertEqual(config("test/data/ConfigTest4.conf").ignore_weekends(),
bool(int(config().defaults["sort"]["ignore_weekends"])))
def test_config12(self):
""" Bad append parent projects switch value. """
self.assertEqual(config("test/data/ConfigTest4.conf").append_parent_projects(),
bool(int(config().defaults["dep"]["append_parent_projects"])))
def test_config13(self):
""" Bad append parent project contexts switch value. """
self.assertEqual(config("test/data/ConfigTest4.conf").append_parent_contexts(),
bool(int(config().defaults["dep"]["append_parent_contexts"])))
@skip("Error checking not yet implemented")
def test_config14(self):
""" Bad priority color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").priority_colors(),
config().defaults["colorscheme"]["priority_colors"])
@skip("Error checking not yet implemented")
def test_config15(self):
""" Bad project color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").project_color(),
config().defaults["colorscheme"]["project_color"])
@skip("Error checking not yet implemented")
def test_config16(self):
""" Bad context color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").context_color(),
config().defaults["colorscheme"]["context_color"])
@skip("Error checking not yet implemented")
def test_config17(self):
""" Bad metadata color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").metadata_color(),
config().defaults["colorscheme"]["metadata_color"])
@skip("Error checking not yet implemented")
def test_config18(self):
""" Bad link color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").link_color(),
config().defaults["colorscheme"]["link_color"])
@skip("Test not yet implemented")
# the test needs to be of the internal function _str_to_dict
def test_config19(self):
""" No priority color value. """
self.assertEqual(config("test/data/ConfigTest4.conf").priority_colors(),
config().defaults["colorscheme"]["priority_colors"])
def test_config20(self):
""" No project color value. """
self.assertEqual(config("test/data/ConfigTest5.conf").project_color(),
config().defaults["colorscheme"]["project_color"])
def test_config21(self):
""" No context color value. """
self.assertEqual(config("test/data/ConfigTest5.conf").context_color(),
config().defaults["colorscheme"]["context_color"])
def test_config22(self):
""" No metadata color value. """
self.assertEqual(config("test/data/ConfigTest5.conf").metadata_color(),
config().defaults["colorscheme"]["metadata_color"])
def test_config23(self):
""" No link color value. """
self.assertEqual(config("test/data/ConfigTest5.conf").link_color(),
config().defaults["colorscheme"]["link_color"])
if __name__ == '__main__':
unittest.main()
...@@ -18,7 +18,7 @@ import unittest ...@@ -18,7 +18,7 @@ import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.DeleteCommand import DeleteCommand from topydo.commands.DeleteCommand import DeleteCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.DepCommand import DepCommand from topydo.commands.DepCommand import DepCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -18,7 +18,7 @@ import unittest ...@@ -18,7 +18,7 @@ import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.DepriCommand import DepriCommand from topydo.commands.DepriCommand import DepriCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -19,7 +19,7 @@ from datetime import date, timedelta ...@@ -19,7 +19,7 @@ from datetime import date, timedelta
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.DoCommand import DoCommand from topydo.commands.DoCommand import DoCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -19,7 +19,7 @@ import unittest ...@@ -19,7 +19,7 @@ import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.EditCommand import EditCommand from topydo.commands.EditCommand import EditCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
...@@ -198,5 +198,14 @@ class EditCommandTest(CommandTest): ...@@ -198,5 +198,14 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.todolist.print_todos(), result) self.assertEqual(self.todolist.print_todos(), result)
mock_call.assert_called_once_with([editor, todotxt]) mock_call.assert_called_once_with([editor, todotxt])
def test_help(self):
command = EditCommand(["help"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
import unittest import unittest
from datetime import date, timedelta from datetime import date, timedelta
from test.Facilities import (load_file, load_file_to_todolist, from test.facilities import (load_file, load_file_to_todolist,
todolist_to_string) todolist_to_string)
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib import Filter from topydo.lib import Filter
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
......
...@@ -18,7 +18,7 @@ import unittest ...@@ -18,7 +18,7 @@ import unittest
from six import u from six import u
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.Commands import get_subcommand from topydo.Commands import get_subcommand
from topydo.commands.AddCommand import AddCommand from topydo.commands.AddCommand import AddCommand
from topydo.commands.DeleteCommand import DeleteCommand from topydo.commands.DeleteCommand import DeleteCommand
...@@ -54,6 +54,14 @@ class GetSubcommandTest(TopydoTest): ...@@ -54,6 +54,14 @@ class GetSubcommandTest(TopydoTest):
self.assertTrue(issubclass(real_cmd, ListCommand)) self.assertTrue(issubclass(real_cmd, ListCommand))
self.assertEqual(final_args, ["-F", "|I| x c d {(}p{)} s k", "-n", "25"]) self.assertEqual(final_args, ["-F", "|I| x c d {(}p{)} s k", "-n", "25"])
def test_alias03(self):
config("test/data/aliases.conf")
args = ["smile"]
real_cmd, final_args = get_subcommand(args)
self.assertTrue(issubclass(real_cmd, ListCommand))
self.assertEqual(final_args, [u("\u263b")])
def test_default_cmd01(self): def test_default_cmd01(self):
args = ["bar"] args = ["bar"]
real_cmd, final_args = get_subcommand(args) real_cmd, final_args = get_subcommand(args)
...@@ -82,6 +90,22 @@ class GetSubcommandTest(TopydoTest): ...@@ -82,6 +90,22 @@ class GetSubcommandTest(TopydoTest):
self.assertTrue(issubclass(real_cmd, DeleteCommand)) self.assertTrue(issubclass(real_cmd, DeleteCommand))
self.assertEqual(final_args, ["-f", "test"]) self.assertEqual(final_args, ["-f", "test"])
def test_alias_default_cmd03(self):
config("test/data/aliases.conf", {('topydo', 'default_command'): 'nonexisting_default'})
args = ['nonexisting']
real_cmd, final_args = get_subcommand(args)
self.assertFalse(real_cmd)
self.assertEqual(final_args, ['nonexisting'])
def test_alias_default_cmd04(self):
config("test/data/aliases.conf", {('topydo', 'default_command'): 'nonexisting_default'})
args = []
real_cmd, final_args = get_subcommand(args)
self.assertFalse(real_cmd)
self.assertEqual(final_args, [])
def test_wrong_alias(self): def test_wrong_alias(self):
config("test/data/aliases.conf") config("test/data/aliases.conf")
...@@ -89,5 +113,10 @@ class GetSubcommandTest(TopydoTest): ...@@ -89,5 +113,10 @@ class GetSubcommandTest(TopydoTest):
real_cmd, final_args = get_subcommand(args) real_cmd, final_args = get_subcommand(args)
self.assertEqual(real_cmd, None) self.assertEqual(real_cmd, None)
def test_help(self):
real_cmd, final_args = get_subcommand(['help', 'nonexisting'])
self.assertFalse(real_cmd)
self.assertEqual(final_args, ['help', 'nonexisting'])
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Graph import DirectedGraph from topydo.lib.Graph import DirectedGraph
......
...@@ -15,31 +15,46 @@ ...@@ -15,31 +15,46 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from datetime import date from datetime import date, timedelta
from freezegun import freeze_time
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Importance import importance from topydo.lib.Importance import importance
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
@freeze_time("2015, 11, 06")
class ImportanceTest(TopydoTest): class ImportanceTest(TopydoTest):
def test_importance1(self): def test_importance01(self):
todo = Todo("Foo") todo = Todo("Foo")
self.assertEqual(importance(todo), 2) self.assertEqual(importance(todo), 2)
def test_importance2(self): def test_importance02(self):
todo = Todo("(A) Foo") todo = Todo("(A) Foo")
self.assertEqual(importance(todo), 5) self.assertEqual(importance(todo), 5)
def test_importance3(self): def test_importance03(self):
todo = Todo("(A) Foo " + config().tag_star() + ":1") todo = Todo("(A) Foo " + config().tag_star() + ":1")
self.assertEqual(importance(todo), 6) self.assertEqual(importance(todo), 6)
def test_importance4(self): def test_importance04(self):
today_str = date.today().isoformat() today_str = date.today().isoformat()
todo = Todo("(C) Foo " + config().tag_due() + ":" + today_str) todo = Todo("(C) Foo " + config().tag_due() + ":" + today_str)
self.assertEqual(importance(todo), 8) self.assertEqual(importance(todo), 8)
def test_importance05(self):
todo = Todo("(C) Foo " + config().tag_due() + ":" + "2015-11-14")
self.assertEqual(importance(todo), 4)
def test_importance06(self):
todo = Todo("(C) Foo " + config().tag_due() + ":" + "2015-11-10")
self.assertEqual(importance(todo), 5)
def test_importance07(self):
config(p_overrides={('sort', 'ignore_weekends'): '1'})
todo = Todo("(C) Foo " + config().tag_due() + ":" + "2015-11-09")
self.assertEqual(importance(todo), 6)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.JsonPrinter import JsonPrinter from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
......
...@@ -20,8 +20,8 @@ import unittest ...@@ -20,8 +20,8 @@ import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from test.Facilities import load_file_to_todolist from test.facilities import load_file_to_todolist
from topydo.commands.ListCommand import ListCommand from topydo.commands.ListCommand import ListCommand
from topydo.lib.Config import config from topydo.lib.Config import config
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from test.Facilities import load_file_to_todolist from test.facilities import load_file_to_todolist
from topydo.commands.ListContextCommand import ListContextCommand from topydo.commands.ListContextCommand import ListContextCommand
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from test.Facilities import load_file_to_todolist from test.facilities import load_file_to_todolist
from topydo.commands.ListProjectCommand import ListProjectCommand from topydo.commands.ListProjectCommand import ListProjectCommand
......
...@@ -19,7 +19,7 @@ from datetime import date, timedelta ...@@ -19,7 +19,7 @@ from datetime import date, timedelta
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.PostponeCommand import PostponeCommand from topydo.commands.PostponeCommand import PostponeCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -18,7 +18,7 @@ import unittest ...@@ -18,7 +18,7 @@ import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.PriorityCommand import PriorityCommand from topydo.commands.PriorityCommand import PriorityCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
import unittest import unittest
from datetime import date, timedelta from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
import unittest import unittest
from datetime import date, timedelta from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os import os
import tempfile
import unittest import unittest
from datetime import date from datetime import date
...@@ -22,7 +23,7 @@ from glob import glob ...@@ -22,7 +23,7 @@ from glob import glob
from six import u from six import u
from uuid import uuid4 from uuid import uuid4
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.AddCommand import AddCommand from topydo.commands.AddCommand import AddCommand
from topydo.commands.ArchiveCommand import ArchiveCommand from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.commands.DeleteCommand import DeleteCommand from topydo.commands.DeleteCommand import DeleteCommand
...@@ -47,8 +48,8 @@ class RevertCommandTest(CommandTest): ...@@ -47,8 +48,8 @@ class RevertCommandTest(CommandTest):
self.tmp_name = str(uuid4().hex.upper()[0:6]) self.tmp_name = str(uuid4().hex.upper()[0:6])
archive_filename = '/tmp/' + self.tmp_name + '_archive' archive_filename = tempfile.gettempdir() + os.sep + self.tmp_name + '_archive'
todo_filename = '/tmp/' + self.tmp_name + '_todo' todo_filename = tempfile.gettempdir() + os.sep + self.tmp_name + '_todo'
config(p_overrides={('topydo', 'archive_filename'): archive_filename, config(p_overrides={('topydo', 'archive_filename'): archive_filename,
('topydo', 'filename'): todo_filename, ('topydo', 'backup_count'): '5'}) ('topydo', 'filename'): todo_filename, ('topydo', 'backup_count'): '5'})
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from test.Facilities import load_file_to_todolist from test.facilities import load_file_to_todolist
from topydo.commands.SortCommand import SortCommand from topydo.commands.SortCommand import SortCommand
from topydo.lib.Config import config from topydo.lib.Config import config
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
import unittest import unittest
from test.Facilities import (load_file, load_file_to_todolist, print_view, from test.facilities import (load_file, load_file_to_todolist, print_view,
todolist_to_string) todolist_to_string)
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
...@@ -170,5 +170,24 @@ class SorterTest(TopydoTest): ...@@ -170,5 +170,24 @@ class SorterTest(TopydoTest):
self.assertEqual(print_view(view), todolist_to_string(result)) self.assertEqual(print_view(view), todolist_to_string(result))
def test_sort17(self):
"""
Check sorting by project.
"""
sorter = Sorter('project')
self.sort_file('test/data/SorterTest13.txt',
'test/data/SorterTest13-result-project.txt', sorter)
def test_sort18(self):
"""
Check sorting by context.
"""
sorter = Sorter('context')
self.sort_file('test/data/SorterTest13.txt',
'test/data/SorterTest13-result-context.txt', sorter)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from test.CommandTestCase import CommandTest from test.command_testcase import CommandTest
from topydo.commands.TagCommand import TagCommand from topydo.commands.TagCommand import TagCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
import unittest import unittest
from datetime import date, timedelta from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
......
...@@ -20,7 +20,7 @@ import re ...@@ -20,7 +20,7 @@ import re
import unittest import unittest
from datetime import date, timedelta from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.TodoBase import TodoBase from topydo.lib.TodoBase import TodoBase
......
...@@ -18,8 +18,8 @@ import unittest ...@@ -18,8 +18,8 @@ import unittest
from six import u from six import u
from test.Facilities import load_file from test.facilities import load_file
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
class TodoFileTest(TopydoTest): class TodoFileTest(TopydoTest):
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
import re import re
import unittest import unittest
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile from topydo.lib.TodoFile import TodoFile
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import unittest import unittest
from test.Facilities import load_file, print_view, todolist_to_string from test.facilities import load_file, print_view, todolist_to_string
from test.TopydoTestCase import TopydoTest from test.topydo_testcase import TopydoTest
from topydo.lib import Filter from topydo.lib import Filter
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from topydo.lib.TodoFile import TodoFile from topydo.lib.TodoFile import TodoFile
......
...@@ -5,7 +5,8 @@ default_command = ls ...@@ -5,7 +5,8 @@ default_command = ls
; filename = todo.txt ; filename = todo.txt
; archive_filename = done.txt ; archive_filename = done.txt
colors = 1 colors = 1
identifiers = linenumber ; or: text ; identifiers can be 'linenumber' or 'text'
identifiers = linenumber
backup_count = 5 backup_count = 5
[add] [add]
......
...@@ -103,7 +103,7 @@ class PromptApplication(CLIApplicationBase): ...@@ -103,7 +103,7 @@ class PromptApplication(CLIApplicationBase):
# refuse to perform operations such as 'del' and 'do' if the # refuse to perform operations such as 'del' and 'do' if the
# todo.txt file has been changed in the background. # todo.txt file has been changed in the background.
if not self.is_read_only(subcommand) and self.mtime != mtime_after: if subcommand and not self.is_read_only(subcommand) and self.mtime != mtime_after:
error("WARNING: todo.txt file was modified by another application.\nTo prevent unintended changes, this operation was not executed.") error("WARNING: todo.txt file was modified by another application.\nTo prevent unintended changes, this operation was not executed.")
continue continue
......
...@@ -17,9 +17,13 @@ ...@@ -17,9 +17,13 @@
import os import os
import shlex import shlex
from six import iteritems from six import iteritems, PY2
from six.moves import configparser from six.moves import configparser
if PY2:
import ushlex as shlex
import codecs
class ConfigError(Exception): class ConfigError(Exception):
def __init__(self, p_text): def __init__(self, p_text):
self.text = p_text self.text = p_text
...@@ -132,7 +136,15 @@ class _Config: ...@@ -132,7 +136,15 @@ class _Config:
if p_path is not None: if p_path is not None:
files = [p_path] files = [p_path]
self.cp.read(files) if PY2:
for path in files:
try:
with codecs.open(path, 'r', encoding='utf-8') as f:
self.cp.readfp(f)
except IOError:
pass
else:
self.cp.read(files)
self._supplement_sections() self._supplement_sections()
......
...@@ -38,6 +38,8 @@ def get_field_function(p_field): ...@@ -38,6 +38,8 @@ def get_field_function(p_field):
if is_priority_field(p_field): if is_priority_field(p_field):
# assign dummy priority when a todo has no priority # assign dummy priority when a todo has no priority
result = lambda a: a.priority() or 'ZZ' result = lambda a: a.priority() or 'ZZ'
elif p_field == 'context' or p_field == 'contexts':
result = lambda a: sorted([c.lower() for c in a.contexts()])
elif p_field == 'creationdate' or p_field == 'creation': elif p_field == 'creationdate' or p_field == 'creation':
# when a task has no creation date, push it to the end by assigning it # when a task has no creation date, push it to the end by assigning it
# the maximum possible date. # the maximum possible date.
...@@ -50,6 +52,8 @@ def get_field_function(p_field): ...@@ -50,6 +52,8 @@ def get_field_function(p_field):
result = importance result = importance
elif p_field == 'importance-avg' or p_field == 'importance-average': elif p_field == 'importance-avg' or p_field == 'importance-average':
result = average_importance result = average_importance
elif p_field == 'project' or p_field == 'projects':
result = lambda a: sorted([c.lower() for c in a.projects()])
elif p_field == 'text': elif p_field == 'text':
result = lambda a: a.text() result = lambda a: a.text()
else: else:
......
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