add initial bulk run from pre-commit over all files

This commit is contained in:
Felix Schurk
2024-07-29 22:34:51 +02:00
parent 665aeeef61
commit 93356b39c3
418 changed files with 21354 additions and 23858 deletions

View File

@@ -139,4 +139,4 @@ For anyone looking for test-related tasks to take on, here are some suggestions:
* All the attribute modifiers need to be tested, only a few are.
* Aliases are not well tested, and fragile.
* Aliases are not well tested, and fragile.

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -88,10 +89,11 @@ class TestAbbreviation(TestCase):
class TestBug1006(TestCase):
"""Bug with expansion of abbreviation "des" in task descriptions and annotations.
It happens for all the shortcuts for column attributes that are automatically
completed. This is because DOM elements are checked before standard words
when strings are tokenized.
It happens for all the shortcuts for column attributes that are automatically
completed. This is because DOM elements are checked before standard words
when strings are tokenized.
"""
def setUp(self):
self.t = Task()
self.t.config("verbose", "affected")
@@ -158,6 +160,7 @@ class TestBug1687(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -58,11 +59,11 @@ class TestAdd(TestCase):
def test_floating_point_preservation(self):
"""924: Verify that floating point numbers are unmolested
Bug 924: '1.0' --> '1.0000'
Bug 924: '1.0' --> '1.0000'
"""
self.t("add release 1.0")
self.t("add 'release 2.0'")
self.t("add \\\"release 3.0\\\"")
self.t('add \\"release 3.0\\"')
code, out, err = self.t("_get 1.description")
self.assertEqual(out, "release 1.0\n")
@@ -76,19 +77,19 @@ class TestAdd(TestCase):
def test_escaped_quotes_are_preserved(self):
"""917: Verify that escaped quotes are preserved
Bug 917: escaping runs amok
Bug 917: escaping runs amok
"""
self.t("add one \\'two\\' three")
self.t("add four \\\"five\\\" six")
self.t('add four \\"five\\" six')
code, out, err = self.t("list")
self.assertIn("one 'two' three", out)
self.assertIn("four \"five\" six", out)
self.assertIn('four "five" six', out)
def test_extra_space_in_path(self):
"""884: Test that path-like args are preserved
Bug 884: Extra space in path name.
Bug 884: Extra space in path name.
"""
self.t("add /one/two/three/")
self.t("add '/four/five/six/'")
@@ -100,9 +101,9 @@ class TestAdd(TestCase):
def test_parentheses_and_spaces_preserved(self):
"""819: Test parentheses and spacing is preserved on add
Bug 819: When I run "task add foo\'s bar." the description of the new task is "foo 's bar .".
Bug 819: When I run "task add foo\'s bar." the description of the new task is "foo 's bar .".
"""
self.t("add foo\\\'s bar")
self.t("add foo\\'s bar")
self.t("add foo (bar)")
self.t("add 'baz (qux)'")
@@ -114,11 +115,11 @@ class TestAdd(TestCase):
def test_single_quote_preserved(self):
"""1642: Test single quote in a terminated multi-word string is preserved
TW-1642: After "--", an apostrophe unexpectedly ends the task description
TW-1642: After "--", an apostrophe unexpectedly ends the task description
"""
self.t("add -- \"Return Randy's stuff\"")
self.t('add -- "Return Randy\'s stuff"')
code, out, err = self.t ("_get 1.description")
code, out, err = self.t("_get 1.description")
self.assertIn("Return Randy's stuff\n", out)
@@ -190,7 +191,7 @@ class Test1549(TestCase):
"""
# This command will hang and therefore timeout in 2.4.1.
code, out, err = self.t('rc.verbose:new-id add 1e x')
code, out, err = self.t("rc.verbose:new-id add 1e x")
self.assertIn("Created task 1.", out)
@@ -202,7 +203,7 @@ class TestBug1612(TestCase):
def test_spurious_whitespace(self):
"""1612: ensure that extra whitespace does not get added.
tw-1612: Spurious whitespace added in task descriptions around certain symbols
tw-1612: Spurious whitespace added in task descriptions around certain symbols
"""
self.t("add 'foo-bar (http://baz.org/)'")
self.t("add 'spam (foo bar)'")
@@ -232,8 +233,8 @@ class TestBug1719(TestCase):
def test_improper_ordinals(self):
"""1719: Description cannot contain improper ordinals"""
self.t("add one 1th");
self.t("add two 23rd");
self.t("add one 1th")
self.t("add two 23rd")
code, out, err = self.t("_get 1.description")
self.assertEqual("one 1th\n", out)
@@ -244,6 +245,7 @@ class TestBug1719(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
from datetime import datetime
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -55,28 +56,25 @@ class TestAlias(TestCase):
# Sanity check that _projects command outputs the "Home" project
code, out, err = self.t("_projects")
self.assertIn(expected, out,
msg="task _projects -> Home")
self.assertIn(expected, out, msg="task _projects -> Home")
# Check that foo command outputs the "Home" project
code, out, err = self.t("foo")
self.assertIn(expected, out,
msg="task foo -> _projects > Home")
self.assertIn(expected, out, msg="task foo -> _projects > Home")
# Check that bar command outputs the "Home" project
code, out, err = self.t("bar")
self.assertIn(expected, out,
msg="task bar -> foo > _projects > Home")
self.assertIn(expected, out, msg="task bar -> foo > _projects > Home")
# Check that baz command outputs the "Home" project
code, out, err = self.t("baz")
self.assertIn(expected, out,
msg="task baz -> bar > foo > _projects > Home")
self.assertIn(expected, out, msg="task baz -> bar > foo > _projects > Home")
# Check that qux command outputs the "Home" project
code, out, err = self.t("qux")
self.assertIn(expected, out,
msg="task qux -> baz > bar > foo > _projects > Home")
self.assertIn(
expected, out, msg="task qux -> baz > bar > foo > _projects > Home"
)
def test_alias_with_implicit_filter(self):
"""Test alias containing simple filter string"""
@@ -91,17 +89,17 @@ class TestAlias(TestCase):
# Sanity check that _projects command outputs
# both the "Home" and "Work" projects
code, out, err = self.t("_projects")
self.assertIn("Home", out,
msg="task _projects -> Home")
self.assertIn("Work", out,
msg="task _projects -> Work")
self.assertIn("Home", out, msg="task _projects -> Home")
self.assertIn("Work", out, msg="task _projects -> Work")
# Check that foo command outputs the "Home" project
code, out, err = self.t("foofilter")
self.assertIn("Home", out,
msg="task foofilter -> project:Home _projects > Home")
self.assertNotIn("Work", out,
msg="task foofilter -> project:Home _projects > Work")
self.assertIn(
"Home", out, msg="task foofilter -> project:Home _projects > Home"
)
self.assertNotIn(
"Work", out, msg="task foofilter -> project:Home _projects > Work"
)
def test_alias_with_implicit_complex_filter(self):
"""Test alias containing filter string with conjuction"""
@@ -116,20 +114,28 @@ class TestAlias(TestCase):
# Check that hometoday command outputs the "Home urgent task"
code, out, err = self.t("hometoday")
self.assertIn("Home urgent task", out,
msg="task hometoday -> project:Home and due:today minimal > "
"Home urgent task")
self.assertIn(
"Home urgent task",
out,
msg="task hometoday -> project:Home and due:today minimal > "
"Home urgent task",
)
# It should not output "Home task", as that one is not due:today
self.assertNotIn("Home task", out,
msg="task hometoday -> project:Home and due:today minimal > "
"Home task")
self.assertNotIn(
"Home task",
out,
msg="task hometoday -> project:Home and due:today minimal > " "Home task",
)
# It should not output "Work task" either, it has entirely wrong
# project
self.assertNotIn("Work task", out,
msg="task hometoday -> project:Home and due:today minimal > "
"Work task")
self.assertNotIn(
"Work task",
out,
msg="task hometoday -> project:Home and due:today minimal > " "Work task",
)
class TestAliasesCommand(TestCase):
def setUp(self):
@@ -142,6 +148,7 @@ class TestAliasesCommand(TestCase):
code, out, err = self.t("_aliases")
self.assertIn("foo", out)
class TestBug1652(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -156,6 +163,7 @@ class TestBug1652(TestCase):
self.assertIn("Deleted 1 task.", out)
self.assertNotIn("No matches.", err)
class TestBug1031(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -196,23 +204,24 @@ class Test1445(TestCase):
def test_alias_single_word(self):
"""1445: Verify single-word aliases"""
self.t.config('alias.when', 'execute date')
code, out, err = self.t('when')
self.t.config("alias.when", "execute date")
code, out, err = self.t("when")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn(str(datetime.now().year), out)
def test_alias_multi_word(self):
"""1445: Verify multi-word aliases"""
self.t.config('alias.worktasks', 'list +work')
self.t('add one +work')
self.t('add two')
code, out, err = self.t('worktasks')
self.t.config("alias.worktasks", "list +work")
self.t("add one +work")
self.t("add two")
code, out, err = self.t("worktasks")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('one', out)
self.assertIn("one", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -77,27 +78,45 @@ class TestAnnotate(TestCase):
# NOTE: Use 'rrr' to guarantee a unique report name. Using 'r'
# conflicts with 'recurring'.
self.t.config("report.rrr.description", "rrr")
self.t.config("report.rrr.columns", "id,description")
self.t.config("report.rrr.sort", "id+")
self.t.config("dateformat", "m/d/Y")
self.t.config("color", "0")
self.t.config("report.rrr.columns", "id,description")
self.t.config("report.rrr.sort", "id+")
self.t.config("dateformat", "m/d/Y")
self.t.config("color", "0")
code, out, err = self.t("rrr")
self.assertTasksExist(out)
self.assertRegex(out, "one\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo1",
msg='full - first annotation task 1')
self.assertRegex(out, "foo1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo2",
msg='full - first annotation task 1')
self.assertRegex(out, "foo2\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo3",
msg='full - first annotation task 1')
self.assertRegex(out, "two\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar1",
msg='full - first annotation task 1')
self.assertRegex(out, "bar1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar2",
msg='full - first annotation task 1')
self.assertRegex(out, "three\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+baz1",
msg='full - first annotation task 1')
self.assertRegex(
out,
"one\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo1",
msg="full - first annotation task 1",
)
self.assertRegex(
out,
"foo1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo2",
msg="full - first annotation task 1",
)
self.assertRegex(
out,
"foo2\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo3",
msg="full - first annotation task 1",
)
self.assertRegex(
out,
"two\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar1",
msg="full - first annotation task 1",
)
self.assertRegex(
out,
"bar1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar2",
msg="full - first annotation task 1",
)
self.assertRegex(
out,
"three\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+baz1",
msg="full - first annotation task 1",
)
def test_annotate_dateformat(self):
"""Testing annotations in reports using dateformat.annotation"""
@@ -105,26 +124,45 @@ class TestAnnotate(TestCase):
# NOTE: Use 'rrr' to guarantee a unique report name. Using 'r'
# conflicts with 'recurring'.
self.t.config("report.rrr.description", "rrr")
self.t.config("report.rrr.columns", "id,description")
self.t.config("report.rrr.sort", "id+")
self.t.config("dateformat.annotation", "yMD HNS")
self.t.config("report.rrr.columns", "id,description")
self.t.config("report.rrr.sort", "id+")
self.t.config("dateformat.annotation", "yMD HNS")
code, out, err = self.t("rrr")
self.assertTasksExist(out)
self.assertRegex(out, "one\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo1",
msg="dateformat - first annotation task 1")
self.assertRegex(out, "foo1\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo2",
msg="dateformat - second annotation task 1")
self.assertRegex(out, "foo2\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo3",
msg="dateformat - third annotation task 1")
self.assertRegex(out, "two\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar1",
msg="dateformat - first annotation task 2")
self.assertRegex(out, "bar1\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar2",
msg="dateformat - second annotation task 2")
self.assertRegex(out, "three\n.+\\d{1,6}\\s+\\d{1,6}\\s+baz1",
msg="dateformat - first annotation task 3")
self.assertRegex(
out,
"one\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo1",
msg="dateformat - first annotation task 1",
)
self.assertRegex(
out,
"foo1\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo2",
msg="dateformat - second annotation task 1",
)
self.assertRegex(
out,
"foo2\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo3",
msg="dateformat - third annotation task 1",
)
self.assertRegex(
out,
"two\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar1",
msg="dateformat - first annotation task 2",
)
self.assertRegex(
out,
"bar1\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar2",
msg="dateformat - second annotation task 2",
)
self.assertRegex(
out,
"three\n.+\\d{1,6}\\s+\\d{1,6}\\s+baz1",
msg="dateformat - first annotation task 3",
)
class TestAnnotationPropagation(TestCase):
def setUp(self):
@@ -138,7 +176,7 @@ class TestAnnotationPropagation(TestCase):
def test_annotate_recurring(self):
"""Test propagation of annotation to recurring siblings"""
self.t("add foo due:eom recur:weekly")
self.t("list") # GC/handleRecurrence
self.t("list") # GC/handleRecurrence
self.t("2 annotate bar", input="y\n")
code, out, err = self.t("all rc.verbose:nothing")
@@ -194,6 +232,7 @@ class TestBug495(TestCase):
code, out, err = self.t("_get 1.annotations.1.description")
self.assertEqual("This is -- a -- test\n", out)
class TestBug694(TestCase):
def setUp(self):
self.t = Task()
@@ -211,6 +250,7 @@ class TestBug694(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -89,6 +90,7 @@ class TestBug440(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -44,27 +45,33 @@ class TestArgs(TestCase):
self.t("add project:p pri:H +tag foo")
code, out, err = self.t("_get 1.description")
self.assertIn("foo\n", out, msg='add project:p pri:H +tag foo')
self.assertIn("foo\n", out, msg="add project:p pri:H +tag foo")
self.t("1 modify project:p pri:H +tag -- foo")
code, out, err = self.t("_get 1.description")
self.assertIn("foo\n", out, msg='add project:p pri:H +tag -- foo')
self.assertIn("foo\n", out, msg="add project:p pri:H +tag -- foo")
self.t("1 modify project:p pri:H -- +tag foo")
code, out, err = self.t("_get 1.description")
self.assertIn("+tag foo\n", out, msg='add project:p pri:H -- +tag foo')
self.assertIn("+tag foo\n", out, msg="add project:p pri:H -- +tag foo")
self.t("1 modify project:p -- pri:H +tag foo")
code, out, err = self.t("_get 1.description")
self.assertIn("pri:H +tag foo\n", out, msg='add project:p -- pri:H +tag foo')
self.assertIn("pri:H +tag foo\n", out, msg="add project:p -- pri:H +tag foo")
self.t("1 modify -- project:p pri:H +tag foo")
code, out, err = self.t("_get 1.description")
self.assertIn("project:p pri:H +tag foo\n", out, msg='add -- project:p pri:H +tag foo')
self.assertIn(
"project:p pri:H +tag foo\n", out, msg="add -- project:p pri:H +tag foo"
)
self.t("1 modify -- project:p pri:H +tag foo --")
code, out, err = self.t("_get 1.description")
self.assertIn("project:p pri:H +tag foo --\n", out, msg='add -- project:p pri:H +tag foo --')
self.assertIn(
"project:p pri:H +tag foo --\n",
out,
msg="add -- project:p pri:H +tag foo --",
)
class TestIDPosition(TestCase):
@@ -94,6 +101,7 @@ class TestIDPosition(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -5,4 +5,4 @@ configure_file(hooks.py hooks.py COPYONLY)
configure_file(meta.py meta.py COPYONLY)
configure_file(task.py task.py COPYONLY)
configure_file(testing.py testing.py COPYONLY)
configure_file(utils.py utils.py)
configure_file(utils.py utils.py)

View File

@@ -1,25 +1,29 @@
import signal
sig_names = dict((k, v) for v, k in reversed(sorted(signal.__dict__.items()))
if v.startswith('SIG') and not v.startswith('SIG_'))
sig_names = dict(
(k, v)
for v, k in reversed(sorted(signal.__dict__.items()))
if v.startswith("SIG") and not v.startswith("SIG_")
)
class CommandError(Exception):
def __init__(self, cmd, code, out, err=None, msg=None):
DEFAULT = ("Command '{{0}}' was {signal}'ed. "
"SIGABRT usually means task timed out.\n")
DEFAULT = (
"Command '{{0}}' was {signal}'ed. "
"SIGABRT usually means task timed out.\n"
)
if msg is None:
msg_suffix = "\n*** Start STDOUT ***\n{2}\n*** End STDOUT ***\n"
if err is not None:
msg_suffix += (
"\n*** Start STDERR ***\n{3}\n*** End STDERR ***\n"
)
msg_suffix += "\n*** Start STDERR ***\n{3}\n*** End STDERR ***\n"
if code < 0:
self.msg = DEFAULT.format(signal=sig_names[abs(code)])
else:
self.msg = ("Command '{0}' finished with unexpected exit "
"code '{1}'.\n")
self.msg = (
"Command '{0}' finished with unexpected exit " "code '{1}'.\n"
)
self.msg += msg_suffix
else:
@@ -43,12 +47,12 @@ class TimeoutWaitingFor(object):
self.name = name
def __repr__(self):
return "*** Timeout reached while waiting for {0} ***".format(
self.name)
return "*** Timeout reached while waiting for {0} ***".format(self.name)
class StreamsAreMerged(object):
def __repr__(self):
return "*** Streams are merged, STDERR is not available ***"
# vim: ai sts=4 et sw=4

View File

@@ -4,6 +4,7 @@ import os
from sys import stderr
import shutil
import stat
try:
import simplejson as json
except ImportError:
@@ -15,8 +16,8 @@ from .exceptions import HookError
class InvalidJSON(object):
"""Object representing the original unparsed JSON string and the JSON error
"""
"""Object representing the original unparsed JSON string and the JSON error"""
def __init__(self, original, error):
self.original = original
self.error = error
@@ -38,6 +39,7 @@ class Hooks(object):
"""Abstraction to help interact with hooks (add, remove) during tests and
keep track of which are active.
"""
def __init__(self, datadir):
"""Initialize hooks container which keeps track of active hooks and
@@ -63,8 +65,7 @@ class Hooks(object):
enabled = ", ".join(enabled) or None
disabled = ", ".join(disabled) or None
return "<Hooks: enabled: {0} | disabled: {1}>".format(enabled,
disabled)
return "<Hooks: enabled: {0} | disabled: {1}>".format(enabled, disabled)
def __getitem__(self, name):
return self._hooks[name]
@@ -134,8 +135,7 @@ class Hooks(object):
hook._delete()
def clear(self):
"""Remove all existing hooks and empty the hook registry
"""
"""Remove all existing hooks and empty the hook registry"""
self._hooks = {}
# Remove any existing hooks
@@ -150,10 +150,11 @@ class Hooks(object):
class Hook(object):
"""Represents a hook script and provides methods to enable/disable hooks
"""
def __init__(self, hookname, hookdir, content=None, default=False,
default_hookpath=None):
"""Represents a hook script and provides methods to enable/disable hooks"""
def __init__(
self, hookname, hookdir, content=None, default=False, default_hookpath=None
):
"""Initialize and create the hook
This class supports creating hooks in two ways:
@@ -181,24 +182,25 @@ class Hook(object):
self._check_hook_not_exists(self.hookfile)
if not default and content is None:
raise HookError("Cannot create hookfile {0} without content. "
"If using a builtin hook pass default=True"
.format(self.hookname))
raise HookError(
"Cannot create hookfile {0} without content. "
"If using a builtin hook pass default=True".format(self.hookname)
)
if os.path.isfile(self.hookfile):
raise HookError("Hook with name {0} already exists. "
"Did you forget to remove() it before recreating?"
.format(self.hookname))
raise HookError(
"Hook with name {0} already exists. "
"Did you forget to remove() it before recreating?".format(self.hookname)
)
if default:
self.default_hookfile = os.path.join(self.default_hookpath,
self.hookname)
self.default_hookfile = os.path.join(self.default_hookpath, self.hookname)
self._check_hook_exists(self.default_hookfile)
# Symlinks change permission of source file, cannot use one here
shutil.copy(self.default_hookfile, self.hookfile)
else:
self.default_hookfile = None
with open(self.hookfile, 'w') as fh:
with open(self.hookfile, "w") as fh:
fh.write(content)
def __eq__(self, other):
@@ -250,16 +252,19 @@ class Hook(object):
if self.hookname.startswith(hooktype):
break
else:
stderr.write("WARNING: {0} is not a valid hook type. "
"It will not be triggered\n".format(self.hookname))
stderr.write(
"WARNING: {0} is not a valid hook type. "
"It will not be triggered\n".format(self.hookname)
)
def _remove_file(self, file):
try:
os.remove(file)
except OSError as e:
if e.errno == errno.ENOENT:
raise HookError("Hook with name {0} was not found on "
"hooks/ folder".format(file))
raise HookError(
"Hook with name {0} was not found on " "hooks/ folder".format(file)
)
else:
raise
@@ -271,18 +276,15 @@ class Hook(object):
self._remove_hookfile(self.hookfile)
def enable(self):
"""Make hookfile executable to allow triggering
"""
"""Make hookfile executable to allow triggering"""
os.chmod(self.hookfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
def disable(self):
"""Remove hookfile executable bit to deny triggering
"""
"""Remove hookfile executable bit to deny triggering"""
os.chmod(self.hookfile, stat.S_IREAD | stat.S_IWRITE)
def is_active(self):
"""Check if hook is active by verifying the execute bit
"""
"""Check if hook is active by verifying the execute bit"""
return os.access(self.hookfile, os.X_OK)
@@ -290,6 +292,7 @@ class LoggedHook(Hook):
"""A variant of a Hook that allows checking that the hook was called, what
was received via STDIN and what was answered to STDOUT
"""
def __init__(self, *args, **kwargs):
super(LoggedHook, self).__init__(*args, **kwargs)
@@ -300,8 +303,7 @@ class LoggedHook(Hook):
self.wrappedname = "original_" + self.hookname
self.wrappedfile = os.path.join(self.hookdir, self.wrappedname)
self.original_wrapper = os.path.join(self.default_hookpath,
"wrapper.sh")
self.original_wrapper = os.path.join(self.default_hookpath, "wrapper.sh")
self.hooklog_in = self.wrappedfile + ".log.in"
self.hooklog_out = self.wrappedfile + ".log.out"
@@ -326,11 +328,10 @@ class LoggedHook(Hook):
self._remove_file(self.hooklog_out)
def _setup_wrapper(self):
"""Setup wrapper shell script to allow capturing input/output of hook
"""
"""Setup wrapper shell script to allow capturing input/output of hook"""
# Create empty hooklog to allow checking that hook executed
open(self.hooklog_in, 'w').close()
open(self.hooklog_out, 'w').close()
open(self.hooklog_in, "w").close()
open(self.hooklog_out, "w").close()
# Rename the original hook to the name that will be used by wrapper
self._check_hook_not_exists(self.wrappedfile)
@@ -340,8 +341,7 @@ class LoggedHook(Hook):
shutil.copy(self.original_wrapper, self.hookfile)
def _get_log_stat(self):
"""Return the most recent change timestamp and size of both logfiles
"""
"""Return the most recent change timestamp and size of both logfiles"""
stdin = os.stat(self.hooklog_in)
stdout = os.stat(self.hooklog_out)
@@ -349,8 +349,7 @@ class LoggedHook(Hook):
return last_change, stdin.st_size, stdout.st_size
def _use_cache(self):
"""Check if log files were changed since last check
"""
"""Check if log files were changed since last check"""
try:
last_change = self._cache["last_change"]
except KeyError:
@@ -367,20 +366,17 @@ class LoggedHook(Hook):
return True
def enable(self):
"""Make hookfile executable to allow triggering
"""
"""Make hookfile executable to allow triggering"""
super(LoggedHook, self).enable()
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
def disable(self):
"""Remove hookfile executable bit to deny triggering
"""
"""Remove hookfile executable bit to deny triggering"""
super(LoggedHook, self).disable()
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE)
def is_active(self):
"""Check if hook is active by verifying the execute bit
"""
"""Check if hook is active by verifying the execute bit"""
parent_is_active = super(LoggedHook, self).disable()
return parent_is_active and os.access(self.wrappedfile, os.X_OK)
@@ -407,16 +403,17 @@ class LoggedHook(Hook):
if self._use_cache():
return self._cache["log"]
log = {"calls": [],
"input": {
"json": [],
},
"output": {
"json": [],
"msgs": [],
},
"exitcode": None,
}
log = {
"calls": [],
"input": {
"json": [],
},
"output": {
"json": [],
"msgs": [],
},
"exitcode": None,
}
with open(self.hooklog_in) as fh:
for i, line in enumerate(fh):
@@ -426,16 +423,19 @@ class LoggedHook(Hook):
# Timestamp includes nanosecond resolution
timestamp = tstamp.split(" ")[-1]
# convert timestamp to python datetime object
log["calls"].append({
"timestamp": datetime.fromtimestamp(float(timestamp)),
"args": args,
})
log["calls"].append(
{
"timestamp": datetime.fromtimestamp(float(timestamp)),
"args": args,
}
)
elif line.startswith("{"):
# Decode json input (to hook)
log["input"]["json"].append(json_decoder(line))
else:
raise IOError("Unexpected content on STDIN line {0}: {1}"
.format(i, line))
raise IOError(
"Unexpected content on STDIN line {0}: {1}".format(i, line)
)
with open(self.hooklog_out) as fh:
for line in fh:
@@ -464,49 +464,43 @@ class LoggedHook(Hook):
"""
log = self.get_logs()
assert len(log["calls"]) == count, ("{0} calls expected for {1} but "
"found {2}".format(
count,
self.hookname,
log["calls"]
))
assert (
len(log["calls"]) == count
), "{0} calls expected for {1} but " "found {2}".format(
count, self.hookname, log["calls"]
)
def assertExitcode(self, exitcode):
"""Check if current hook finished with the expected exit code
"""
"""Check if current hook finished with the expected exit code"""
log = self.get_logs()
assert log["exitcode"] == exitcode, ("Expected exit code {0} for {1} "
"but found {2}".format(
exitcode,
self.hookname,
log["exitcode"]
))
assert (
log["exitcode"] == exitcode
), "Expected exit code {0} for {1} " "but found {2}".format(
exitcode, self.hookname, log["exitcode"]
)
def assertValidJSONOutput(self):
"""Check if current hook output is valid JSON in all expected replies
"""
"""Check if current hook output is valid JSON in all expected replies"""
log = self.get_logs()
for i, out in enumerate(log["output"]["json"]):
assert not isinstance(out, InvalidJSON), ("Invalid JSON found at "
"reply number {0} with "
"content {1}".format(
i + 1,
out.original
))
assert not isinstance(out, InvalidJSON), (
"Invalid JSON found at "
"reply number {0} with "
"content {1}".format(i + 1, out.original)
)
def assertInvalidJSONOutput(self):
"""Check if current hook output is invalid JSON in any expected reply
"""
"""Check if current hook output is invalid JSON in any expected reply"""
log = self.get_logs()
for i, out in enumerate(log["output"]["json"]):
assert isinstance(out, InvalidJSON), ("Valid JSON found at reply "
"number {0} with content "
"{1}".format(
i + 1,
out.original
))
assert isinstance(out, InvalidJSON), (
"Valid JSON found at reply "
"number {0} with content "
"{1}".format(i + 1, out.original)
)
# vim: ai sts=4 et sw=4

View File

@@ -7,6 +7,7 @@ class MetaTest(type):
Creates test_methods in the TestCase class dynamically named after the
arguments used.
"""
@staticmethod
def make_function(classname, *args, **kwargs):
def test(self):
@@ -35,4 +36,5 @@ class MetaTest(type):
return super(MetaTest, meta).__new__(meta, classname, bases, dct)
# vim: ai sts=4 et sw=4

View File

@@ -21,6 +21,7 @@ class Task(object):
A taskw client should not be used after being destroyed.
"""
DEFAULT_TASK = task_binary_location()
def __init__(self, taskw=DEFAULT_TASK):
@@ -43,11 +44,13 @@ class Task(object):
self.reset_env()
with open(self.taskrc, 'w') as rc:
rc.write("data.location={0}\n"
"hooks=off\n"
"news.version=2.6.0\n"
"".format(self.datadir))
with open(self.taskrc, "w") as rc:
rc.write(
"data.location={0}\n"
"hooks=off\n"
"news.version=2.6.0\n"
"".format(self.datadir)
)
# Hooks disabled until requested
self.hooks = None
@@ -61,14 +64,12 @@ class Task(object):
return self.runSuccess(*args, **kwargs)
def activate_hooks(self):
"""Enable self.hooks functionality and activate hooks on config
"""
"""Enable self.hooks functionality and activate hooks on config"""
self.config("hooks", "1")
self.hooks = Hooks(self.datadir)
def reset_env(self):
"""Set a new environment derived from the one used to launch the test
"""
"""Set a new environment derived from the one used to launch the test"""
# Copy all env variables to avoid clashing subprocess environments
self.env = os.environ.copy()
@@ -78,15 +79,13 @@ class Task(object):
self.env["TASKRC"] = self.taskrc
def config(self, var, value):
"""Run setup `var` as `value` in taskd config
"""
"""Run setup `var` as `value` in taskd config"""
# Add -- to avoid misinterpretation of - in things like UUIDs
cmd = (self.taskw, "config", "--", var, value)
return run_cmd_wait(cmd, env=self.env, input="y\n")
def del_config(self, var):
"""Remove `var` from taskd config
"""
"""Remove `var` from taskd config"""
cmd = (self.taskw, "config", var)
return run_cmd_wait(cmd, env=self.env, input="y\n")
@@ -104,8 +103,9 @@ class Task(object):
if export_filter is None:
export_filter = ""
code, out, err = self.runSuccess("rc.json.array=1 {0} export"
"".format(export_filter))
code, out, err = self.runSuccess(
"rc.json.array=1 {0} export" "".format(export_filter)
)
return json.loads(out)
@@ -118,16 +118,16 @@ class Task(object):
result = self.export(export_filter=export_filter)
if len(result) != 1:
descriptions = [task.get('description') or '[description-missing]'
for task in result]
descriptions = [
task.get("description") or "[description-missing]" for task in result
]
raise ValueError(
"One task should match the '{0}' filter, '{1}' "
"matches:\n {2}".format(
export_filter or '',
len(result),
'\n '.join(descriptions)
))
export_filter or "", len(result), "\n ".join(descriptions)
)
)
return result[0]
@@ -146,8 +146,7 @@ class Task(object):
return args
def runSuccess(self, args="", input=None, merge_streams=False,
timeout=5):
def runSuccess(self, args="", input=None, merge_streams=False, timeout=5):
"""Invoke task with given arguments and fail if exit code != 0
Use runError if you want exit_code to be tested automatically and
@@ -171,10 +170,9 @@ class Task(object):
args = self._split_string_args_if_string(args)
command.extend(args)
output = run_cmd_wait_nofail(command, input,
merge_streams=merge_streams,
env=self.env,
timeout=timeout)
output = run_cmd_wait_nofail(
command, input, merge_streams=merge_streams, env=self.env, timeout=timeout
)
if output[0] != 0:
raise CommandError(command, *output)
@@ -205,10 +203,9 @@ class Task(object):
args = self._split_string_args_if_string(args)
command.extend(args)
output = run_cmd_wait_nofail(command, input,
merge_streams=merge_streams,
env=self.env,
timeout=timeout)
output = run_cmd_wait_nofail(
command, input, merge_streams=merge_streams, env=self.env, timeout=timeout
)
# output[0] is the exit code
if output[0] == 0 or output[0] is None:
@@ -217,8 +214,7 @@ class Task(object):
return output
def destroy(self):
"""Cleanup the data folder and release server port for other instances
"""
"""Cleanup the data folder and release server port for other instances"""
try:
shutil.rmtree(self.datadir)
except OSError as e:
@@ -237,8 +233,10 @@ class Task(object):
self.destroy = lambda: None
def __destroyed(self, *args, **kwargs):
raise AttributeError("Task instance has been destroyed. "
"Create a new instance if you need a new client.")
raise AttributeError(
"Task instance has been destroyed. "
"Create a new instance if you need a new client."
)
def diag(self, merge_streams_with=None):
"""Run task diagnostics.
@@ -302,4 +300,5 @@ class Task(object):
# Use advanced time format
self._command = [cmd, "-f", faketime] + self._command
# vim: ai sts=4 et sw=4

View File

@@ -7,14 +7,14 @@ class BaseTestCase(unittest.TestCase):
def tap(self, out):
sys.stderr.write("--- tap output start ---\n")
for line in out.splitlines():
sys.stderr.write(line + '\n')
sys.stderr.write(line + "\n")
sys.stderr.write("--- tap output end ---\n")
@unittest.skipIf(TASKW_SKIP, "TASKW_SKIP set, skipping task tests.")
class TestCase(BaseTestCase):
"""Automatically skips tests if TASKW_SKIP is present in the environment
"""
"""Automatically skips tests if TASKW_SKIP is present in the environment"""
pass

View File

@@ -9,11 +9,13 @@ import atexit
import tempfile
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty
from time import sleep
try:
import simplejson as json
except ImportError:
@@ -21,15 +23,13 @@ except ImportError:
from .exceptions import CommandError, TimeoutWaitingFor
USED_PORTS = set()
ON_POSIX = 'posix' in sys.builtin_module_names
ON_POSIX = "posix" in sys.builtin_module_names
# Directory relative to basetest module location
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
# Location of binary files (usually the src/ folder)
BIN_PREFIX = os.path.abspath(
os.path.join("${CMAKE_BINARY_DIR}","src")
)
BIN_PREFIX = os.path.abspath(os.path.join("${CMAKE_BINARY_DIR}", "src"))
# Default location of test hooks
DEFAULT_HOOK_PATH = os.path.abspath(
@@ -45,7 +45,7 @@ TASKW_SKIP = os.environ.get("TASKW_SKIP", False)
# Environment flags to control use of PATH or in-tree binaries
TASK_USE_PATH = os.environ.get("TASK_USE_PATH", False)
UUID_REGEXP = ("[0-9A-Fa-f]{8}-" + ("[0-9A-Fa-f]{4}-" * 3) + "[0-9A-Fa-f]{12}")
UUID_REGEXP = "[0-9A-Fa-f]{8}-" + ("[0-9A-Fa-f]{4}-" * 3) + "[0-9A-Fa-f]{12}"
def task_binary_location(cmd="task"):
@@ -65,9 +65,8 @@ def binary_location(cmd, USE_PATH=False):
return os.path.join(BIN_PREFIX, cmd)
def wait_condition(cond, timeout=10, sleeptime=.01):
"""Wait for condition to return anything other than None
"""
def wait_condition(cond, timeout=10, sleeptime=0.01):
"""Wait for condition to return anything other than None"""
# NOTE Increasing sleeptime can dramatically increase testsuite runtime
# It also reduces CPU load significantly
if timeout is None:
@@ -92,8 +91,8 @@ def wait_condition(cond, timeout=10, sleeptime=.01):
def wait_process(pid, timeout=None):
"""Wait for process to finish
"""
"""Wait for process to finish"""
def process():
try:
os.kill(pid, 0)
@@ -120,13 +119,18 @@ def _queue_output(arguments, pidq, outputq):
# pid None is read by the main thread as a crash of the process
pidq.put(None)
outputq.put((
"",
("Unexpected exception caught during execution of taskw: '{0}' . "
"If you are running out-of-tree tests set TASK_USE_PATH=1 "
"in shell env before execution and add the "
"location of the task(d) binary to the PATH".format(e)),
255)) # false exitcode
outputq.put(
(
"",
(
"Unexpected exception caught during execution of taskw: '{0}' . "
"If you are running out-of-tree tests set TASK_USE_PATH=1 "
"in shell env before execution and add the "
"location of the task(d) binary to the PATH".format(e)
),
255,
)
) # false exitcode
return
@@ -137,15 +141,14 @@ def _queue_output(arguments, pidq, outputq):
out, err = proc.communicate(input_data)
if sys.version_info > (3,):
out, err = out.decode('utf-8'), err.decode('utf-8')
out, err = out.decode("utf-8"), err.decode("utf-8")
# Give the output back to the caller
outputq.put((out, err, proc.returncode))
def _retrieve_output(thread, timeout, queue, thread_error):
"""Fetch output from taskw subprocess queues
"""
"""Fetch output from taskw subprocess queues"""
# Try to join the thread on failure abort
thread.join(timeout)
if thread.is_alive():
@@ -184,16 +187,16 @@ def _get_output(arguments, timeout=None):
# Process crashed or timed out for some reason
if pid is None:
return _retrieve_output(t, output_timeout, outputq,
"TaskWarrior to start")
return _retrieve_output(t, output_timeout, outputq, "TaskWarrior to start")
# Wait for process to finish (normal execution)
state = wait_process(pid, timeout)
if state:
# Process finished
return _retrieve_output(t, output_timeout, outputq,
"TaskWarrior thread to join")
return _retrieve_output(
t, output_timeout, outputq, "TaskWarrior thread to join"
)
# If we reach this point we assume the process got stuck or timed out
for sig in (signal.SIGABRT, signal.SIGTERM, signal.SIGKILL):
@@ -210,15 +213,21 @@ def _get_output(arguments, timeout=None):
if state:
# Process finished
return _retrieve_output(t, output_timeout, outputq,
"TaskWarrior to die")
return _retrieve_output(t, output_timeout, outputq, "TaskWarrior to die")
# This should never happen but in case something goes really bad
raise OSError("TaskWarrior stopped responding and couldn't be killed")
def run_cmd_wait(cmd, input=None, stdout=PIPE, stderr=PIPE,
merge_streams=False, env=os.environ, timeout=None):
def run_cmd_wait(
cmd,
input=None,
stdout=PIPE,
stderr=PIPE,
merge_streams=False,
env=os.environ,
timeout=None,
):
"Run a subprocess and wait for it to finish"
if input is None:
@@ -265,8 +274,7 @@ def run_cmd_wait_nofail(*args, **kwargs):
def memoize(obj):
"""Keep an in-memory cache of function results given its inputs
"""
"""Keep an in-memory cache of function results given its inputs"""
cache = obj.cache = {}
@functools.wraps(obj)
@@ -275,11 +283,13 @@ def memoize(obj):
if key not in cache:
cache[key] = obj(*args, **kwargs)
return cache[key]
return memoizer
try:
from shutil import which
which = memoize(which)
except ImportError:
# NOTE: This is shutil.which backported from python-3.3.3
@@ -294,12 +304,12 @@ except ImportError:
path.
"""
# Check that a given file can be accessed with the correct mode.
# Additionally check that `file` is not a directory, as on Windows
# directories pass the os.access check.
def _access_check(fn, mode):
return (os.path.exists(fn) and os.access(fn, mode) and
not os.path.isdir(fn))
return os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn)
# If we're given a path with a directory part, look it up directly
# rather than referring to PATH directories. This includes checking
@@ -348,16 +358,15 @@ except ImportError:
def parse_datafile(file):
"""Parse .data files on the client and server treating files as JSON
"""
"""Parse .data files on the client and server treating files as JSON"""
data = []
with open(file) as fh:
for line in fh:
line = line.rstrip("\n")
# Turn [] strings into {} to be treated properly as JSON hashes
if line.startswith('[') and line.endswith(']'):
line = '{' + line[1:-1] + '}'
if line.startswith("[") and line.endswith("]"):
line = "{" + line[1:-1] + "}"
if line.startswith("{"):
data.append(json.loads(line))
@@ -370,6 +379,7 @@ def mkstemp(data):
"""
Create a temporary file that is removed at process exit
"""
def rmtemp(name):
try:
os.remove(name)
@@ -377,7 +387,7 @@ def mkstemp(data):
pass
f = tempfile.NamedTemporaryFile(delete=False)
f.write(data.encode('utf-8') if not isinstance(data, bytes) else data)
f.write(data.encode("utf-8") if not isinstance(data, bytes) else data)
f.close()
# Ensure removal at end of python session
@@ -387,11 +397,11 @@ def mkstemp(data):
def mkstemp_exec(data):
"""Create a temporary executable file that is removed at process exit
"""
"""Create a temporary executable file that is removed at process exit"""
name = mkstemp(data)
os.chmod(name, 0o755)
return name
# vim: ai sts=4 et sw=4

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
from contextlib import contextmanager
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -66,16 +67,18 @@ def prepare_tasksh(t):
tasksh.append(line)
tasksh.extend([
'COMP_WORDS=("$@")',
'COMP_CWORD=$(($#-1))',
'_task',
'for reply_iter in "${COMPREPLY[@]}"; do',
' echo $reply_iter',
'done',
])
tasksh.extend(
[
'COMP_WORDS=("$@")',
"COMP_CWORD=$(($#-1))",
"_task",
'for reply_iter in "${COMPREPLY[@]}"; do',
" echo $reply_iter",
"done",
]
)
return '\n'.join(tasksh)
return "\n".join(tasksh)
class TestBashCompletionBase(TestCase):
@@ -88,7 +91,7 @@ class TestBashCompletionBase(TestCase):
self.t.tasksh_script = os.path.join(self.t.datadir, "task.sh")
with open(self.t.tasksh_script, 'w') as tasksh:
with open(self.t.tasksh_script, "w") as tasksh:
tasksh.write(prepare_tasksh(self.t))
@@ -170,6 +173,7 @@ class TestProject(TestBashCompletionBase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
@@ -49,6 +50,7 @@ class TestBug1381(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import signal
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -138,7 +139,9 @@ class TestBulk(TestCase):
self.assertNotIn("Deleting task", out)
# Test with 3 tasks, denying delete.
code, out, err = self.t.runError("1-3 delete rc.confirmation:1", input="n\nn\nn\n")
code, out, err = self.t.runError(
"1-3 delete rc.confirmation:1", input="n\nn\nn\n"
)
self.assertNotIn("(yes/no)", out)
self.assertIn("(yes/no/all/quit)", out)
self.assertNotIn("Deleted task 1", out)
@@ -208,6 +211,7 @@ class TestBugBulk(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -97,6 +98,7 @@ class TestBurndownCommand(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -30,6 +30,7 @@ import os
import re
import signal
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -39,8 +40,9 @@ from basetest.utils import BIN_PREFIX, run_cmd_wait, run_cmd_wait_nofail
CALC = os.path.join(BIN_PREFIX, "calc")
@unittest.skipIf(not os.path.isfile(CALC),
"calc binary not available in {0}".format(CALC))
@unittest.skipIf(
not os.path.isfile(CALC), "calc binary not available in {0}".format(CALC)
)
class TestCalc(TestCase):
def test_regular_math(self):
"""regular math"""
@@ -56,7 +58,9 @@ class TestCalc(TestCase):
def test_postfix_math(self):
"""postfix math"""
code, out, err = run_cmd_wait((CALC, "--debug", "--postfix", "12 3600 * 34 60 * 56 + +"))
code, out, err = run_cmd_wait(
(CALC, "--debug", "--postfix", "12 3600 * 34 60 * 56 + +")
)
self.assertIn("Eval literal number ↑'12'", out)
self.assertIn("Eval literal number ↑'3600'", out)
@@ -122,18 +126,17 @@ class TestBug1254(TestCase):
self.assertEqual(expected, code, "Exit code was non-zero ({0})".format(code))
def test_no_segmentation_fault_calc_negative_multiplication(self):
"""1254: calc can multiply zero and negative numbers
"""
"""1254: calc can multiply zero and negative numbers"""
self.run_command("calc 0*-1")
def test_calc_positive_multiplication(self):
"""1254: calc can multiply negative zero and positive
"""
"""1254: calc can multiply negative zero and positive"""
self.run_command("calc 0*1")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
from datetime import datetime, timedelta
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -38,6 +39,7 @@ from basetest import Task, TestCase
def timestamp_in_holiday_format(time):
return time.strftime("%Y%m%d")
class TestCalendarCommandLine(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -56,7 +58,9 @@ class TestCalendarCommandLine(TestCase):
def test_basic_command_offset(self):
"""Verify 'calendar rc.calendar.offset:on rc.calendar.offset.value:1' does not fail"""
code, out, err = self.t("calendar rc.calendar.offset:on rc.calendar.offset.value:1")
code, out, err = self.t(
"calendar rc.calendar.offset:on rc.calendar.offset.value:1"
)
self.assertIn("Su Mo Tu We Th Fr Sa", out)
def test_basic_command(self):
@@ -72,13 +76,17 @@ class TestCalendarCommandLine(TestCase):
def test_basic_command_details(self):
"""Verify 'calendar rc.calendar.details:full rc.calendar.details.report:list' does not fail"""
self.t("add task_with_due_date due:tomorrow")
code, out, err = self.t("calendar rc.calendar.details:full rc.calendar.details.report:list")
code, out, err = self.t(
"calendar rc.calendar.details:full rc.calendar.details.report:list"
)
self.assertIn("task_with_due_date", out)
def test_basic_command_details_color(self):
"""Verify 'calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on' does not fail"""
self.t("add task_with_due_date due:tomorrow")
code, out, err = self.t("calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on")
code, out, err = self.t(
"calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on"
)
self.assertIn("task_with_due_date", out)
def test_basic_command_holidays(self):
@@ -88,29 +96,37 @@ class TestCalendarCommandLine(TestCase):
def test_basic_command_single_holiday(self):
"""Verify 'calendar rc.holiday.test.name:donkeyday rc.holiday.test.date:[tomorrws date] rc.calendar.holidays:full' does not fail"""
code, out, err = self.t("calendar rc.holiday.test.name:donkeyday rc.holliday.test.date:{0} rc.calendar.holidays:full".format(self.tomorrow))
code, out, err = self.t(
"calendar rc.holiday.test.name:donkeyday rc.holliday.test.date:{0} rc.calendar.holidays:full".format(
self.tomorrow
)
)
self.assertRegex(out, "Date +Holiday")
def test_basic_command_multiday_holiday(self):
"""Verify 'calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:[tomorrws date] rc.holiday.test.end:[date a month later] rc.calendar.holidays:full' does not fail"""
code, out, err = self.t("calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:{0} rc.holiday.test.end:{1} rc.calendar.holidays:full".format(self.tomorrow, self.next_month))
code, out, err = self.t(
"calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:{0} rc.holiday.test.end:{1} rc.calendar.holidays:full".format(
self.tomorrow, self.next_month
)
)
self.assertRegex(out, "Date +Holiday")
def test_y_argument(self):
"""Verify 'calendar y' does not fail"""
code, out, err = self.t("calendar y")
self.assertIn("January", out)
self.assertIn("February", out)
self.assertIn("March", out)
self.assertIn("April", out)
self.assertIn("May", out)
self.assertIn("June", out)
self.assertIn("July", out)
self.assertIn("August", out)
self.assertIn("January", out)
self.assertIn("February", out)
self.assertIn("March", out)
self.assertIn("April", out)
self.assertIn("May", out)
self.assertIn("June", out)
self.assertIn("July", out)
self.assertIn("August", out)
self.assertIn("September", out)
self.assertIn("October", out)
self.assertIn("November", out)
self.assertIn("December", out)
self.assertIn("October", out)
self.assertIn("November", out)
self.assertIn("December", out)
self.assertNotIn("Could not recognize argument", err)
def test_due_argument(self):
@@ -249,6 +265,7 @@ class TestCalendarCommandLine(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -38,11 +39,11 @@ class TestCaseless(TestCase):
@classmethod
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task ()
cls.t = Task()
cls.t.config("report.ls.columns", "id,project,priority,description")
cls.t.config("report.ls.labels", "ID,Proj,Pri,Description")
cls.t.config("report.ls.sort", "priority-,project+")
cls.t.config("report.ls.filter", "status:pending")
cls.t.config("report.ls.labels", "ID,Proj,Pri,Description")
cls.t.config("report.ls.sort", "priority-,project+")
cls.t.config("report.ls.filter", "status:pending")
def setUp(self):
"""Executed before each test in the class"""
@@ -102,21 +103,30 @@ class TestCaseless(TestCase):
def test_annotation_filter(self):
"""Verify annotation filter with and without case sensitivity"""
code, out, err = self.t.runError("rc.search.case.sensitive:yes ls description.contains:Three")
code, out, err = self.t.runError(
"rc.search.case.sensitive:yes ls description.contains:Three"
)
self.assertNotIn("one two three", out)
code, out, err = self.t("rc.search.case.sensitive:no ls description.contains:Three")
code, out, err = self.t(
"rc.search.case.sensitive:no ls description.contains:Three"
)
self.assertIn("one two three", out)
code, out, err = self.t.runError("rc.search.case.sensitive:yes ls description.contains:Six")
code, out, err = self.t.runError(
"rc.search.case.sensitive:yes ls description.contains:Six"
)
self.assertNotIn("one two three", out)
code, out, err = self.t("rc.search.case.sensitive:no ls description.contains:Six")
code, out, err = self.t(
"rc.search.case.sensitive:no ls description.contains:Six"
)
self.assertIn("one two three", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -27,19 +27,18 @@
#include <cmake.h>
// cmake.h include header must come first
#include <stdlib.h>
#include <columns/ColID.h>
#include <main.h>
#include <stdlib.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest test (12);
int main(int, char**) {
UnitTest test(12);
// Ensure environment has no influence.
unsetenv ("TASKDATA");
unsetenv ("TASKRC");
unsetenv("TASKDATA");
unsetenv("TASKRC");
ColumnID columnID;
unsigned int minimum = 0;
@@ -47,37 +46,36 @@ int main (int, char**)
Task t1;
t1.id = 3;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 1, "id:3 --> ColID::measure minimum 1");
test.is ((int)maximum, 1, "id:3 --> ColID::measure maximum 1");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 1, "id:3 --> ColID::measure minimum 1");
test.is((int)maximum, 1, "id:3 --> ColID::measure maximum 1");
t1.id = 33;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 2, "id:33 --> ColID::measure minimum 2");
test.is ((int)maximum, 2, "id:33 --> ColID::measure maximum 2");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 2, "id:33 --> ColID::measure minimum 2");
test.is((int)maximum, 2, "id:33 --> ColID::measure maximum 2");
t1.id = 333;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 3, "id:333 --> ColID::measure minimum 3");
test.is ((int)maximum, 3, "id:333 --> ColID::measure maximum 3");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 3, "id:333 --> ColID::measure minimum 3");
test.is((int)maximum, 3, "id:333 --> ColID::measure maximum 3");
t1.id = 3333;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 4, "id:3333 --> ColID::measure minimum 4");
test.is ((int)maximum, 4, "id:3333 --> ColID::measure maximum 4");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 4, "id:3333 --> ColID::measure minimum 4");
test.is((int)maximum, 4, "id:3333 --> ColID::measure maximum 4");
t1.id = 33333;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 5, "id:33333 --> ColID::measure minimum 5");
test.is ((int)maximum, 5, "id:33333 --> ColID::measure maximum 5");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 5, "id:33333 --> ColID::measure minimum 5");
test.is((int)maximum, 5, "id:33333 --> ColID::measure maximum 5");
t1.id = 333333;
columnID.measure (t1, minimum, maximum);
test.is ((int)minimum, 6, "id:333333 --> ColID::measure minimum 6");
test.is ((int)maximum, 6, "id:333333 --> ColID::measure maximum 6");
columnID.measure(t1, minimum, maximum);
test.is((int)minimum, 6, "id:333333 --> ColID::measure minimum 6");
test.is((int)maximum, 6, "id:333333 --> ColID::measure maximum 6");
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import platform
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -45,12 +46,12 @@ class TestColorCommand(TestCase):
self.t = Task()
def test_colors_off(self):
""" Verify 'task colors' shows an error with color:off"""
"""Verify 'task colors' shows an error with color:off"""
code, out, err = self.t.runError("colors")
self.assertIn("Color is currently turned off", out)
def test_colors_all(self):
""" Verify 'task colors' shows all colors"""
"""Verify 'task colors' shows all colors"""
code, out, err = self.t("colors rc._forcecolor:on")
self.assertIn("Basic colors", out)
self.assertIn("Effects", out)
@@ -60,12 +61,12 @@ class TestColorCommand(TestCase):
self.assertIn("Try running 'task color white on red'.", out)
def test_colors_sample(self):
""" Verify 'task colors red' shows a sample"""
"""Verify 'task colors red' shows a sample"""
code, out, err = self.t("colors rc._forcecolor:on red")
self.assertRegex(out, "Your sample:\n\n .\\[31mtask color red.\\[0m")
def test_colors_legend(self):
""" Verify 'task colors legend' shows theme colors"""
"""Verify 'task colors legend' shows theme colors"""
code, out, err = self.t("colors rc._forcecolor:on legend")
self.assertRegex(out, r"color.debug\s+.\[0m\s.\[38;5;4mcolor4\s+.\[0m")
@@ -74,8 +75,10 @@ class TestColorCommand(TestCase):
code, out, err = self.t("colors rc._forcecolor:on rc.color.debug:red legend")
self.assertRegex(out, r"color.debug\s+.\[0m\s.\[31mred\s+.\[0m")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import platform
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,181 +43,182 @@ class TestColorRules(TestCase):
cls.t = Task()
# Controlling peripheral color.
cls.t.config('_forcecolor', 'on')
cls.t.config('fontunderline', 'off') # label underlining complicates the tests.
cls.t.config('color.alternate', '') # alternating color complicateѕ the tests.
cls.t.config('default.command', 'list')
cls.t.config('uda.xxx.type', 'numeric')
cls.t.config('uda.xxx.label', 'XXX')
cls.t.config("_forcecolor", "on")
cls.t.config("fontunderline", "off") # label underlining complicates the tests.
cls.t.config("color.alternate", "") # alternating color complicateѕ the tests.
cls.t.config("default.command", "list")
cls.t.config("uda.xxx.type", "numeric")
cls.t.config("uda.xxx.label", "XXX")
# Color rules.
cls.t.config('color.active', 'red')
cls.t.config('color.blocked', 'red')
cls.t.config('color.blocking', 'blue')
cls.t.config('color.due', 'red')
cls.t.config('color.overdue', 'blue')
cls.t.config('color.error', 'blue')
cls.t.config('color.header', 'blue')
cls.t.config('color.footnote', 'red')
cls.t.config('color.debug', 'green')
cls.t.config('color.project.x', 'red')
cls.t.config('color.project.none', '')
cls.t.config('color.uda.priority.H', 'red')
cls.t.config('color.uda.priority.M', 'blue')
cls.t.config('color.uda.priority.L', 'green')
cls.t.config('color.keyword.keyword', 'red')
cls.t.config('color.tagged', '')
cls.t.config('color.tag.none', '')
cls.t.config('color.tag.x', 'red')
cls.t.config('color.recurring', 'red')
cls.t.config('color.uda.xxx', 'red')
cls.t.config('color.uda.xxx.4', 'blue')
cls.t.config("color.active", "red")
cls.t.config("color.blocked", "red")
cls.t.config("color.blocking", "blue")
cls.t.config("color.due", "red")
cls.t.config("color.overdue", "blue")
cls.t.config("color.error", "blue")
cls.t.config("color.header", "blue")
cls.t.config("color.footnote", "red")
cls.t.config("color.debug", "green")
cls.t.config("color.project.x", "red")
cls.t.config("color.project.none", "")
cls.t.config("color.uda.priority.H", "red")
cls.t.config("color.uda.priority.M", "blue")
cls.t.config("color.uda.priority.L", "green")
cls.t.config("color.keyword.keyword", "red")
cls.t.config("color.tagged", "")
cls.t.config("color.tag.none", "")
cls.t.config("color.tag.x", "red")
cls.t.config("color.recurring", "red")
cls.t.config("color.uda.xxx", "red")
cls.t.config("color.uda.xxx.4", "blue")
cls.t('add control task') # 1
cls.t('add active task') # 2
cls.t('2 start')
cls.t('add blocked task') # 3
cls.t('add blocking task') # 4
cls.t('3 modify depends:4')
cls.t('add tomorrow due:tomorrow') # 5
cls.t('add yesterday due:yesterday') # 6
cls.t('add anhourago due:now-1h') # 7
cls.t('add someday due:yesterday') # 8
cls.t('add project_x project:x') # 9
cls.t('add pri_h priority:H') # 10
cls.t('add pri_m priority:M') # 11
cls.t('add pri_l priority:L') # 12
cls.t('add keyword') # 13
cls.t('add tag_x +x') # 14
cls.t('add uda_xxx_1 xxx:1') # 15
cls.t('add uda_xxx_4 xxx:4') # 16
cls.t('add recurring due:tomorrow recur:1week') # 17 Keep this last
cls.t("add control task") # 1
cls.t("add active task") # 2
cls.t("2 start")
cls.t("add blocked task") # 3
cls.t("add blocking task") # 4
cls.t("3 modify depends:4")
cls.t("add tomorrow due:tomorrow") # 5
cls.t("add yesterday due:yesterday") # 6
cls.t("add anhourago due:now-1h") # 7
cls.t("add someday due:yesterday") # 8
cls.t("add project_x project:x") # 9
cls.t("add pri_h priority:H") # 10
cls.t("add pri_m priority:M") # 11
cls.t("add pri_l priority:L") # 12
cls.t("add keyword") # 13
cls.t("add tag_x +x") # 14
cls.t("add uda_xxx_1 xxx:1") # 15
cls.t("add uda_xxx_4 xxx:4") # 16
cls.t("add recurring due:tomorrow recur:1week") # 17 Keep this last
def test_control(self):
"""No color on control task."""
code, out, err = self.t('1 info')
self.assertNotIn('\x1b[', out)
code, out, err = self.t("1 info")
self.assertNotIn("\x1b[", out)
def test_disable_in_pipe(self):
"""No color in pipe unless forced."""
code, out, err = self.t('2 info rc._forcecolor:off')
self.assertNotIn('\x1b[', out)
code, out, err = self.t("2 info rc._forcecolor:off")
self.assertNotIn("\x1b[", out)
def test_active(self):
"""Active color rule."""
code, out, err = self.t('/active/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/active/ info")
self.assertIn("\x1b[31m", out)
def test_blocked(self):
"""Blocked color rule."""
code, out, err = self.t('/blocked/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/blocked/ info")
self.assertIn("\x1b[31m", out)
def test_blocking(self):
"""Blocking color rule."""
code, out, err = self.t('/blocking/ info')
self.assertIn('\x1b[34m', out)
code, out, err = self.t("/blocking/ info")
self.assertIn("\x1b[34m", out)
def test_due_yesterday(self):
"""Overdue color rule."""
code, out, err = self.t('/yesterday/ info')
self.assertIn('\x1b[34m', out)
code, out, err = self.t("/yesterday/ info")
self.assertIn("\x1b[34m", out)
def test_due_anhourago(self):
"""Overdue color rule from an hour ago."""
code, out, err = self.t('/anhourago/ info')
code, out, err = self.t("/anhourago/ info")
# Match 4-bit or 8-bit blue color code
self.assertRegex(out, '\x1b\\[(38;5;4|34)m')
self.assertRegex(out, "\x1b\\[(38;5;4|34)m")
def test_due_tomorrow(self):
"""Due tomorrow color rule."""
code, out, err = self.t('/tomorrow/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/tomorrow/ info")
self.assertIn("\x1b[31m", out)
def test_due_someday(self):
"""Due someday color rule."""
code, out, err = self.t('/someday/ info')
self.assertIn('\x1b[', out)
code, out, err = self.t("/someday/ info")
self.assertIn("\x1b[", out)
def test_color_error(self):
"""Error color."""
code, out, err = self.t.runError('add error priority:X')
self.assertIn('\x1b[34m', err)
code, out, err = self.t.runError("add error priority:X")
self.assertIn("\x1b[34m", err)
def test_color_header(self):
"""Header color."""
code, out, err = self.t('rc.verbose=header,default /control/')
self.assertIn('\x1b[34m', err)
code, out, err = self.t("rc.verbose=header,default /control/")
self.assertIn("\x1b[34m", err)
def test_color_footnote(self):
"""Footnote color."""
code, out, err = self.t('rc.verbose=on /control/')
self.assertIn('\x1b[31mConfiguration override', err)
code, out, err = self.t("rc.verbose=on /control/")
self.assertIn("\x1b[31mConfiguration override", err)
def test_color_debug(self):
"""Debug color."""
code, out, err = self.t('rc.debug=1 /control/')
self.assertIn('\x1b[32mTimer', err)
code, out, err = self.t("rc.debug=1 /control/")
self.assertIn("\x1b[32mTimer", err)
def test_project_x(self):
"""Project x color rule."""
code, out, err = self.t('/project_x/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/project_x/ info")
self.assertIn("\x1b[31m", out)
def test_project_none(self):
"""Project none color rule."""
code, out, err = self.t('/control/ rc.color.project.none=red info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/control/ rc.color.project.none=red info")
self.assertIn("\x1b[31m", out)
def test_priority_h(self):
"""Priority H color rule."""
code, out, err = self.t('/pri_h/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/pri_h/ info")
self.assertIn("\x1b[31m", out)
def test_priority_m(self):
"""Priority M color rule."""
code, out, err = self.t('/pri_m/ info')
self.assertIn('\x1b[34m', out)
code, out, err = self.t("/pri_m/ info")
self.assertIn("\x1b[34m", out)
def test_priority_l(self):
"""Priority L color rule."""
code, out, err = self.t('/pri_l/ info')
self.assertIn('\x1b[32m', out)
code, out, err = self.t("/pri_l/ info")
self.assertIn("\x1b[32m", out)
def test_keyword(self):
"""Keyword color rule."""
code, out, err = self.t('/keyword/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/keyword/ info")
self.assertIn("\x1b[31m", out)
def test_tag_x(self):
"""Tag x color rule."""
code, out, err = self.t('/tag_x/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/tag_x/ info")
self.assertIn("\x1b[31m", out)
def test_tag_none(self):
"""Tag none color rule."""
code, out, err = self.t('/control/ rc.color.tag.none=red info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/control/ rc.color.tag.none=red info")
self.assertIn("\x1b[31m", out)
def test_tagged(self):
"""Tagged color rule."""
code, out, err = self.t('/tag_x/ rc.color.tag.x= rc.color.tagged=blue info')
self.assertIn('\x1b[34m', out)
code, out, err = self.t("/tag_x/ rc.color.tag.x= rc.color.tagged=blue info")
self.assertIn("\x1b[34m", out)
def test_recurring(self):
"""Recurring color rule."""
code, out, err = self.t('/recurring/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/recurring/ info")
self.assertIn("\x1b[31m", out)
def test_uda(self):
"""UDA color rule."""
code, out, err = self.t('/uda_xxx_1/ info')
self.assertIn('\x1b[31m', out)
code, out, err = self.t("/uda_xxx_1/ info")
self.assertIn("\x1b[31m", out)
def test_uda_value(self):
"""UDA Value color rule."""
code, out, err = self.t('/uda_xxx_4/ rc.color.uda.xxx= info')
self.assertIn('\x1b[34m', out)
code, out, err = self.t("/uda_xxx_4/ rc.color.uda.xxx= info")
self.assertIn("\x1b[34m", out)
class TestColorRulesMerging(TestCase):
@@ -225,37 +227,48 @@ class TestColorRulesMerging(TestCase):
self.t = Task()
# Controlling peripheral color.
self.t.config('_forcecolor', 'on')
self.t.config('fontunderline', 'off') # label underlining complicates the tests.
self.t.config('color.alternate', '') # alternating color complicateѕ the tests.
self.t.config('default.command', 'list')
self.t.config("_forcecolor", "on")
self.t.config(
"fontunderline", "off"
) # label underlining complicates the tests.
self.t.config("color.alternate", "") # alternating color complicateѕ the tests.
self.t.config("default.command", "list")
# Color rules. Only due and tagged affect resulting color.
self.t.config('color.due', 'red')
self.t.config('color.tagged','on white')
self.t.config('rule.color.precedence', 'due,tagged')
self.t.config("color.due", "red")
self.t.config("color.tagged", "on white")
self.t.config("rule.color.precedence", "due,tagged")
self.t('add due:tomorrow +home hometask') # Task that matches both color rules
self.t("add due:tomorrow +home hometask") # Task that matches both color rules
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping color merge test for Cygwin')
@unittest.skipIf('FreeBSD' in platform.system(), 'Skipping color merge test for FREEBSD')
@unittest.skipIf(
"CYGWIN" in platform.system(), "Skipping color merge test for Cygwin"
)
@unittest.skipIf(
"FreeBSD" in platform.system(), "Skipping color merge test for FREEBSD"
)
def test_colors_merge(self):
"""Tests whether colors merge"""
code, out, err = self.t('1 info')
self.assertIn('\x1b[31;47mhometask', out) # Red on white
code, out, err = self.t("1 info")
self.assertIn("\x1b[31;47mhometask", out) # Red on white
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping color merge test for Cygwin')
@unittest.skipIf('FreeBSD' in platform.system(), 'Skipping color merge test for FREEBSD')
@unittest.skipIf(
"CYGWIN" in platform.system(), "Skipping color merge test for Cygwin"
)
@unittest.skipIf(
"FreeBSD" in platform.system(), "Skipping color merge test for FREEBSD"
)
def test_colors_merge_off(self):
"""No color merge behaviour with rule.color.merge=no"""
self.t.config('rule.color.merge', 'no')
self.t.config("rule.color.merge", "no")
code, out, err = self.t('1 info')
self.assertIn('\x1b[31mhometask', out) # Red
code, out, err = self.t("1 info")
self.assertIn("\x1b[31mhometask", out) # Red
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -40,7 +41,7 @@ class TestDescriptionFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,description")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add zero")
cls.t("add one long description to exceed a certain string size")
@@ -65,13 +66,18 @@ class TestDescriptionFormats(TestCase):
def test_description_oneline(self):
"""Verify formatting of 'description.oneline' column"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,description.oneline")
self.assertRegex(out, r"one long description to exceed a certain string size \d{4}-\d{2}-\d{2}")
self.assertRegex(
out,
r"one long description to exceed a certain string size \d{4}-\d{2}-\d{2}",
)
self.assertIn("annotation", out)
self.assertNotIn("[1]", out)
def test_description_truncated(self):
"""Verify formatting of 'description.truncated' column"""
code, out, err = self.t("xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated")
code, out, err = self.t(
"xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated"
)
self.assertIn("exceed a c...", out)
self.assertNotIn("annotation", out)
self.assertNotIn("[1]", out)
@@ -84,13 +90,17 @@ class TestDescriptionFormats(TestCase):
def test_description_truncated_count(self):
"""Verify formatting of 'description.truncated_count' column"""
code, out, err = self.t("xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated_count")
code, out, err = self.t(
"xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated_count"
)
self.assertIn("exceed... [1]", out)
self.assertNotIn("annotation", out)
def test_description_format_unrecognized(self):
"""Verify descriptionuuid.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,description.donkey")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,description.donkey"
)
self.assertEqual(err, "Unrecognized column format 'description.donkey'\n")
@@ -100,7 +110,7 @@ class TestUUIDFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,uuid")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add zero")
code, out, err = cls.t("_get 1.uuid")
@@ -131,7 +141,7 @@ class TestUrgencyFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,urgency")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add one project:A due:yesterday +tag")
@@ -161,7 +171,7 @@ class TestIDFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add zero")
@@ -186,7 +196,7 @@ class TestStatusFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,status")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add zero")
cls.t("add one")
@@ -231,7 +241,7 @@ class TestRecurringAttributeFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add one due:eoy recur:monthly")
cls.t("list")
@@ -241,22 +251,34 @@ class TestRecurringAttributeFormats(TestCase):
def test_recurrence_formats_short(self):
"""Verify formatting of assorted short recurrence columns"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,status,due,recur.indicator,mask,imask,parent.short")
code, out, err = self.t(
"xxx rc.report.xxx.columns:id,status,due,recur.indicator,mask,imask,parent.short"
)
self.assertRegex(out, r"1\sRecurring\s+\d{4}-\d{2}-\d{2}\s+R\s+-")
self.assertRegex(out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+R\s+0\s+[0-9a-fA-F]{8}")
self.assertRegex(
out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+R\s+0\s+[0-9a-fA-F]{8}"
)
def test_recurrence_formats_long(self):
"""Verify formatting of assorted long recurrence columns"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.long")
code, out, err = self.t(
"xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.long"
)
self.assertRegex(out, r"1\sRecurring\s+\d{4}-\d{2}-\d{2}\s+P30D\s+-")
self.assertRegex(out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+P30D\s+0\s+[0-9a-fA-F-]{36}")
self.assertRegex(
out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+P30D\s+0\s+[0-9a-fA-F-]{36}"
)
def test_recurrence_format_unrecognized(self):
"""Verify *.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,status,due,recur.donkey,mask,imask,parent.long")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,status,due,recur.donkey,mask,imask,parent.long"
)
self.assertEqual(err, "Unrecognized column format 'recur.donkey'\n")
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.donkey")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.donkey"
)
self.assertEqual(err, "Unrecognized column format 'parent.donkey'\n")
@@ -266,7 +288,7 @@ class TestProjectFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,project,description")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add one project:TOP")
cls.t("add two project:TOP.MIDDLE")
@@ -278,27 +300,33 @@ class TestProjectFormats(TestCase):
def test_project_format_full(self):
"""Verify project.full formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,project.full,description")
self.assertRegex(out, r'1\s+TOP\s+one')
self.assertRegex(out, r'2\s+TOP.MIDDLE\s+two')
self.assertRegex(out, r'3\s+TOP.MIDDLE.BOTTOM\s+three')
self.assertRegex(out, r"1\s+TOP\s+one")
self.assertRegex(out, r"2\s+TOP.MIDDLE\s+two")
self.assertRegex(out, r"3\s+TOP.MIDDLE.BOTTOM\s+three")
def test_project_format_parent(self):
"""Verify project.parent formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,project.parent,description")
self.assertRegex(out, r'1\s+TOP\s+one')
self.assertRegex(out, r'2\s+TOP\s+two')
self.assertRegex(out, r'3\s+TOP\s+three')
code, out, err = self.t(
"xxx rc.report.xxx.columns:id,project.parent,description"
)
self.assertRegex(out, r"1\s+TOP\s+one")
self.assertRegex(out, r"2\s+TOP\s+two")
self.assertRegex(out, r"3\s+TOP\s+three")
def test_project_format_indented(self):
"""Verify project.indented formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,project.indented,description")
self.assertRegex(out, r'1\s+TOP\s+one')
self.assertRegex(out, r'2\s+MIDDLE\s+two')
self.assertRegex(out, r'3\s+BOTTOM\s+three')
code, out, err = self.t(
"xxx rc.report.xxx.columns:id,project.indented,description"
)
self.assertRegex(out, r"1\s+TOP\s+one")
self.assertRegex(out, r"2\s+MIDDLE\s+two")
self.assertRegex(out, r"3\s+BOTTOM\s+three")
def test_project_format_unrecognized(self):
"""Verify project.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,project.donkey,description")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,project.donkey,description"
)
self.assertEqual(err, "Unrecognized column format 'project.donkey'\n")
@@ -308,28 +336,30 @@ class TestTagsFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,tags,description")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add one +tag1 +tag2")
def test_tags_format_list(self):
"""Verify tags.list formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.list")
self.assertRegex(out, r'1\s+tag1\stag2$')
self.assertRegex(out, r"1\s+tag1\stag2$")
def test_tags_format_indicator(self):
"""Verify tags.indicator formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.indicator")
self.assertRegex(out, r'1\s+\+$')
self.assertRegex(out, r"1\s+\+$")
def test_tags_format_count(self):
"""Verify tags.count formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.count")
self.assertRegex(out, r'1\s+\[2\]$')
self.assertRegex(out, r"1\s+\[2\]$")
def test_tags_format_unrecognized(self):
"""Verify tags.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,tags.donkey,description")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,tags.donkey,description"
)
self.assertEqual(err, "Unrecognized column format 'tags.donkey'\n")
@@ -339,7 +369,7 @@ class TestDateFormats(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,due")
cls.t.config("verbose", "nothing")
cls.t.config("verbose", "nothing")
cls.t("add one due:yesterday")
cls.t("add two due:tomorrow")
@@ -347,54 +377,56 @@ class TestDateFormats(TestCase):
def test_date_format_formatted(self):
"""Verify due.formatted formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.formatted")
self.assertRegex(out, r'1\s+\d{4}-\d{2}-\d{2}')
self.assertRegex(out, r'2\s+\d{4}-\d{2}-\d{2}')
self.assertRegex(out, r"1\s+\d{4}-\d{2}-\d{2}")
self.assertRegex(out, r"2\s+\d{4}-\d{2}-\d{2}")
def test_date_format_julian(self):
"""Verify due.julian formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.julian")
self.assertRegex(out, r'1\s+\d+\.\d+')
self.assertRegex(out, r'2\s+\d+\.\d+')
self.assertRegex(out, r"1\s+\d+\.\d+")
self.assertRegex(out, r"2\s+\d+\.\d+")
def test_date_format_epoch(self):
"""Verify due.epoch formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.epoch")
self.assertRegex(out, r'1\s+\d{10}')
self.assertRegex(out, r'2\s+\d{10}')
self.assertRegex(out, r"1\s+\d{10}")
self.assertRegex(out, r"2\s+\d{10}")
def test_date_format_iso(self):
"""Verify due.iso formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.iso")
self.assertRegex(out, r'1\s+\d{8}T\d{6}Z')
self.assertRegex(out, r'2\s+\d{8}T\d{6}Z')
self.assertRegex(out, r"1\s+\d{8}T\d{6}Z")
self.assertRegex(out, r"2\s+\d{8}T\d{6}Z")
def test_date_format_age(self):
"""Verify due.age formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.age")
self.assertRegex(out, r'1\s+[0-9.]+d')
self.assertRegex(out, r'2\s+-[0-9.]+[hmin]+')
self.assertRegex(out, r"1\s+[0-9.]+d")
self.assertRegex(out, r"2\s+-[0-9.]+[hmin]+")
def test_date_format_remaining(self):
"""Verify due.remaining formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.remaining")
self.assertRegex(out, r'1')
self.assertRegex(out, r'2\s+\d+\S+')
self.assertRegex(out, r"1")
self.assertRegex(out, r"2\s+\d+\S+")
def test_date_format_relative(self):
"""Verify due.relative formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.relative")
self.assertRegex(out, r'1\s+-[0-9.]+d')
self.assertRegex(out, r'2\s+[0-9.]+[hmin]+')
self.assertRegex(out, r"1\s+-[0-9.]+d")
self.assertRegex(out, r"2\s+[0-9.]+[hmin]+")
def test_date_format_countdown(self):
"""Verify due.countdown formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,due.countdown")
self.assertRegex(out, r'1\s+')
self.assertRegex(out, r'2\s+\d+\S+')
self.assertRegex(out, r"1\s+")
self.assertRegex(out, r"2\s+\d+\S+")
def test_date_format_unrecognized(self):
"""Verify due.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,due.donkey,description")
code, out, err = self.t.runError(
"xxx rc.report.xxx.columns:id,due.donkey,description"
)
self.assertEqual(err, "Unrecognized column format 'due.donkey'\n")
@@ -406,9 +438,9 @@ class TestCustomColumns(TestCase):
def test_unrecognized_column(self):
"""verify that using a bogus colum generates an error"""
self.t.config("report.foo.description", "DESC")
self.t.config("report.foo.columns", "id,foo,description")
self.t.config("report.foo.sort", "id+")
self.t.config("report.foo.filter", "project:A")
self.t.config("report.foo.columns", "id,foo,description")
self.t.config("report.foo.sort", "id+")
self.t.config("report.foo.filter", "project:A")
# Generate the usage screen, and locate the custom report on it.
code, out, err = self.t.runError("foo")
@@ -420,8 +452,8 @@ class TestUDAFormats(TestCase):
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,priority")
cls.t.config("verbose", "nothing")
cls.t.config("report.xxx.columns", "id,priority")
cls.t.config("verbose", "nothing")
cls.t.config("uda.priority.indicator", "P")
cls.t("add one priority:H")
@@ -429,19 +461,18 @@ class TestUDAFormats(TestCase):
def test_uda_format_formatted(self):
"""Verify priority.default formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,priority.default")
self.assertRegex(out, r'1\s+H')
self.assertRegex(out, r"1\s+H")
def test_uda_format_indicator(self):
"""Verify priority.indicator formatting"""
code, out, err = self.t("xxx rc.report.xxx.columns:id,priority.indicator")
self.assertRegex(out, r'1\s+P')
self.assertRegex(out, r"1\s+P")
def test_uda_format_unrecognized(self):
"""Verify priority.donkey formatting fails"""
code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,priority.donkey")
self.assertEqual(err, "Unrecognized column format 'priority.donkey'\n")
"""
depends list* 1 2 10
count [3]
@@ -450,6 +481,7 @@ depends list* 1 2 10
start active* ✓
"""
class TestFeature1061(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -479,6 +511,7 @@ class TestFeature1061(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,19 +43,24 @@ class TestCommands(TestCase):
"""Verify 'add', 'modify', 'list' dna"""
code, out, err = self.t("commands")
self.assertRegex(out, r"add\s+operation\s+RW\s+Ctxt\s+Mods\s+Adds a new task")
self.assertRegex(out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of")
self.assertRegex(
out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of"
)
self.assertRegex(out, r"modify\s+operation\s+RW\s+Filt\s+Mods\s+Modifies the")
def test_command_dna_color(self):
"""Verify 'add', 'modify', 'list' dna"""
code, out, err = self.t("commands rc._forcecolor:on")
self.assertRegex(out, r"add\s+operation\s+RW\s+Ctxt\s+Mods\s+Adds a new task")
self.assertRegex(out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of")
self.assertRegex(
out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of"
)
self.assertRegex(out, r"modify\s+operation\s+RW\s+Filt\s+Mods\s+Modifies the")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -49,13 +50,14 @@ class TestCompleted(TestCase):
self.t("2 delete", input="y\n")
code, out, err = self.t("completed")
self.assertIn('one', out)
self.assertNotIn('two', out)
self.assertNotIn('three', out)
self.assertIn("one", out)
self.assertNotIn("two", out)
self.assertNotIn("three", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -58,8 +59,8 @@ class TestConfiguration(TestCase):
def test_config_completion(self):
"""verify that the '_config' command generates a full list"""
code, out, err = self.t("_config")
self.assertIn("_forcecolor", out) # first
self.assertIn("xterm.title", out) # last
self.assertIn("_forcecolor", out) # first
self.assertIn("xterm.title", out) # last
def test_config_nothing(self):
"""Verify error handling with no args"""
@@ -94,6 +95,7 @@ class TestBug1475(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -44,7 +45,7 @@ class TestConfirmation(TestCase):
self.t.config("confirmation", "on")
# Create some playthings.
for id in range(1,11):
for id in range(1, 11):
self.t("add foo")
# Test the various forms of "Yes".
@@ -87,7 +88,9 @@ class TestBug1438(TestCase):
code, out, err = self.t("list")
self.assertIn("Sometimes", out)
code, out, err = self.t("rc.confirmation=off rc.recurrence.confirmation=off 2 mod /Sometimes/Everytime/")
code, out, err = self.t(
"rc.confirmation=off rc.recurrence.confirmation=off 2 mod /Sometimes/Everytime/"
)
self.assertIn("Modified 1 task", out)
code, out, err = self.t("list")
self.assertIn("Everytime", out)
@@ -95,6 +98,7 @@ class TestBug1438(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -44,186 +44,205 @@ class ContextManagementTest(TestCase):
"""With confirmation active, prompt if context filter matches no tasks"""
self.t.config("confirmation", "on")
code, out, err = self.t.runError('context define work project:Work', input="y\nn\n")
code, out, err = self.t.runError(
"context define work project:Work", input="y\nn\n"
)
self.assertIn("The filter 'project:Work' matches 0 pending tasks.", out)
self.assertNotIn("Context 'work' defined", out)
# Assert the config contains context definition
self.assertNotIn('context.work=project:Work\n', self.t.taskrc_content)
self.assertNotIn("context.work=project:Work\n", self.t.taskrc_content)
def test_context_define(self):
"""Test simple context definition."""
code, out, err = self.t('context define work project:Work', input="y\ny\nn\n")
code, out, err = self.t("context define work project:Work", input="y\ny\nn\n")
self.assertIn("Context 'work' defined", out)
# Assert the config contains read context definition
context_line = 'context.work.read=project:Work\n'
context_line = "context.work.read=project:Work\n"
self.assertIn(context_line, self.t.taskrc_content)
# Assert that it contains the definition only once
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
# Assert the config does not contain write context definition
context_line = 'context.work.write=project:Work\n'
context_line = "context.work.write=project:Work\n"
self.assertNotIn(context_line, self.t.taskrc_content)
# Assert that legacy style was not used
# Assert the config contains read context definition
context_line = 'context.work=project:Work\n'
context_line = "context.work=project:Work\n"
self.assertNotIn(context_line, self.t.taskrc_content)
def test_context_redefine_same_definition(self):
"""Test re-defining the context with the same definition."""
self.t('context define work project:Work', input='y\ny\ny\n')
code, out, err = self.t('context define work project:Work', input='y\ny\ny\n')
self.t("context define work project:Work", input="y\ny\ny\n")
code, out, err = self.t("context define work project:Work", input="y\ny\ny\n")
self.assertIn("Context 'work' defined (read, write).", out)
# Assert the config contains context definition
context_line = 'context.work.read=project:Work\n'
context_line = "context.work.read=project:Work\n"
self.assertIn(context_line, self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
context_line = 'context.work.write=project:Work\n'
context_line = "context.work.write=project:Work\n"
self.assertIn(context_line, self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
def test_context_redefine_different_definition(self):
"""Test re-defining the context with different definition."""
self.t('context define work project:Work', input='y\ny\ny\n')
code, out, err = self.t('context define work +work', input='y\ny\ny\n')
self.t("context define work project:Work", input="y\ny\ny\n")
code, out, err = self.t("context define work +work", input="y\ny\ny\n")
self.assertIn("Context 'work' defined", out)
# Assert the config does not contain the old context definition
self.assertNotIn('context.work.read=project:Work\n', self.t.taskrc_content)
self.assertNotIn('context.work.write=project:Work\n', self.t.taskrc_content)
self.assertNotIn("context.work.read=project:Work\n", self.t.taskrc_content)
self.assertNotIn("context.work.write=project:Work\n", self.t.taskrc_content)
# Assert the config contains context definition
context_line = 'context.work.read=+work\n'
context_line = "context.work.read=+work\n"
self.assertIn(context_line, self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
context_line = 'context.work.write=+work\n'
context_line = "context.work.write=+work\n"
self.assertIn(context_line, self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
def test_context_define_invalid_for_write_due_to_modifier(self):
"""Test definition of a context that is not a valid write context."""
self.t.config("confirmation", "off")
code, out, err = self.t('context define urgent due.before:today')
code, out, err = self.t("context define urgent due.before:today")
self.assertIn("Context 'urgent' defined", out)
# Assert the config contains read context definition
context_line = 'context.urgent.read=due.before:today\n'
context_line = "context.urgent.read=due.before:today\n"
self.assertIn(context_line, self.t.taskrc_content)
# Assert that it contains the definition only once
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
# Assert the config does not contain write context definition
context_line = 'context.urgent.write=due.before:today\n'
context_line = "context.urgent.write=due.before:today\n"
self.assertNotIn(context_line, self.t.taskrc_content)
# Assert that the write context was not set at all
self.assertNotIn('context.urgent.write=', self.t.taskrc_content)
self.assertNotIn("context.urgent.write=", self.t.taskrc_content)
# Assert that legacy style was not used
# Assert the config contains read context definition
context_line = 'context.urgent=due.before:today\n'
context_line = "context.urgent=due.before:today\n"
self.assertNotIn(context_line, self.t.taskrc_content)
def test_context_define_invalid_for_write_due_to_operator(self):
"""Test definition of a context that is not a valid write context because it uses an OR operator."""
self.t.config("confirmation", "off")
code, out, err = self.t('context define urgent due:today or +next')
code, out, err = self.t("context define urgent due:today or +next")
self.assertIn("Context 'urgent' defined", out)
# Assert the config contains read context definition
context_line = 'context.urgent.read=due:today or +next\n'
context_line = "context.urgent.read=due:today or +next\n"
self.assertIn(context_line, self.t.taskrc_content)
# Assert that it contains the definition only once
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
# Assert the config does not contain write context definition
context_line = 'context.urgent.write=due:today or +next\n'
context_line = "context.urgent.write=due:today or +next\n"
self.assertNotIn(context_line, self.t.taskrc_content)
# Assert that the write context was not set at all
self.assertNotIn('context.urgent.write=', self.t.taskrc_content)
self.assertNotIn("context.urgent.write=", self.t.taskrc_content)
# Assert that legacy style was not used
# Assert the config contains read context definition
context_line = 'context.urgent=due:today or +next\n'
context_line = "context.urgent=due:today or +next\n"
self.assertNotIn(context_line, self.t.taskrc_content)
def test_context_define_invalid_for_write_due_to_tag_exclusion(self):
"""Test definition of a context that is not a valid write context because it contains a tag exclusion."""
self.t.config("confirmation", "off")
code, out, err = self.t('context define nowork due:today -work')
code, out, err = self.t("context define nowork due:today -work")
self.assertIn("Context 'nowork' defined", out)
# Assert the config contains read context definition
context_line = 'context.nowork.read=due:today -work\n'
context_line = "context.nowork.read=due:today -work\n"
self.assertIn(context_line, self.t.taskrc_content)
# Assert that it contains the definition only once
self.assertEqual(self.t.taskrc_content.count(context_line), 1)
# Assert the config does not contain write context definition
context_line = 'context.nowork.write=due:today -work\n'
context_line = "context.nowork.write=due:today -work\n"
self.assertNotIn(context_line, self.t.taskrc_content)
# Assert that the write context was not set at all
self.assertNotIn('context.nowork.write=', self.t.taskrc_content)
self.assertNotIn("context.nowork.write=", self.t.taskrc_content)
# Assert that legacy style was not used
# Assert the config contains read context definition
context_line = 'context.nowork=due:today -work\n'
context_line = "context.nowork=due:today -work\n"
self.assertNotIn(context_line, self.t.taskrc_content)
def test_context_delete(self):
"""Test simple context deletion."""
self.t('context define work project:Work', input='y\ny\n')
code, out, err = self.t('context delete work', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
code, out, err = self.t("context delete work", input="y\ny\n")
self.assertIn("Context 'work' deleted.", out)
# Assert that taskrc does not countain context work definition
self.assertFalse(any('context.work' in line for line in self.t.taskrc_content))
self.assertFalse(any("context.work" in line for line in self.t.taskrc_content))
def test_context_delete_undefined(self):
"""Test deletion of undefined context."""
code, out, err = self.t.runError('context delete foo', input='y\n')
code, out, err = self.t.runError("context delete foo", input="y\n")
self.assertIn("Context 'foo' not found.", err)
# Assert that taskrc does not countain context work definition
self.assertFalse(any('context.foo.read=' in line for line in self.t.taskrc_content))
self.assertFalse(any('context.foo.write=' in line for line in self.t.taskrc_content))
self.assertFalse(
any("context.foo.read=" in line for line in self.t.taskrc_content)
)
self.assertFalse(
any("context.foo.write=" in line for line in self.t.taskrc_content)
)
def test_context_delete_unset_after_removal(self):
"""Test that context is unset if its definition has been removed."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context work')
code, out, err = self.t('context delete work', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context work")
code, out, err = self.t("context delete work", input="y\ny\n")
self.assertIn("Context 'work' deleted.", out)
# Assert that taskrc does not countain context work definition
self.assertFalse(any('context.work=' in line for line in self.t.taskrc_content))
self.assertFalse(any('context.work.read=' in line for line in self.t.taskrc_content))
self.assertFalse(any('context.work.write=' in line for line in self.t.taskrc_content))
self.assertFalse(any("context.work=" in line for line in self.t.taskrc_content))
self.assertFalse(
any("context.work.read=" in line for line in self.t.taskrc_content)
)
self.assertFalse(
any("context.work.write=" in line for line in self.t.taskrc_content)
)
# Aseert that the context is not set
code, out, err = self.t('context show')
self.assertIn('No context is currently applied.', out)
self.assertFalse(any(re.search(r"^context(\.(read|write))?=", line) for line in self.t.taskrc_content))
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
self.assertFalse(
any(
re.search(r"^context(\.(read|write))?=", line)
for line in self.t.taskrc_content
)
)
def test_context_list_active(self):
"""Test the 'context list' command."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t('context home')
code, out, err = self.t('context list')
contains_work = lambda line: 'work' in line and 'project:Work' in line and 'no' in line
contains_home = lambda line: 'home' in line and '+home' in line and 'yes' in line
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
self.t("context home")
code, out, err = self.t("context list")
contains_work = (
lambda line: "work" in line and "project:Work" in line and "no" in line
)
contains_home = (
lambda line: "home" in line and "+home" in line and "yes" in line
)
# Assert that output contains work and home context definitions exactly
# once
@@ -232,39 +251,41 @@ class ContextManagementTest(TestCase):
def test_context_list_legacy(self):
"""Test the determination of legacy context definition."""
self.t('config context.old project:Old', input='y\n')
self.t('context old')
code, out, err = self.t('context list')
self.t("config context.old project:Old", input="y\n")
self.t("context old")
code, out, err = self.t("context list")
# Assert that "old" context has only the read component defined
self.assertRegex(out, r'read\s+project:Old\s+yes')
self.assertRegex(out, r'write\s+yes')
self.assertRegex(out, r"read\s+project:Old\s+yes")
self.assertRegex(out, r"write\s+yes")
def test_context_initially_empty(self):
"""Test that no context is set initially."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
code, out, err = self.t('context show')
self.assertIn('No context is currently applied.', out)
self.assertFalse(any(re.search("^context=", line) for line in self.t.taskrc_content))
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
self.assertFalse(
any(re.search("^context=", line) for line in self.t.taskrc_content)
)
def test_context_setting(self):
"""Test simple context setting."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home home", input="y\ny\n")
code, out, err = self.t('context home')
code, out, err = self.t("context home")
self.assertIn("Context 'home' set.", out)
self.assertIn("context=home\n", self.t.taskrc_content)
def test_context_resetting(self):
"""Test resetting the same context."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
self.t('context home')
code, out, err = self.t('context home')
self.t("context home")
code, out, err = self.t("context home")
self.assertIn("Context 'home' set.", out)
context_line = "context=home\n"
@@ -272,92 +293,98 @@ class ContextManagementTest(TestCase):
def test_context_switching(self):
"""Test changing the context."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
# Switch to home context
code, out, err = self.t('context home')
code, out, err = self.t("context home")
self.assertIn("Context 'home' set.", out)
self.assertEqual(self.t.taskrc_content.count("context=home\n"), 1)
# Switch to work context
code, out, err = self.t('context work')
code, out, err = self.t("context work")
self.assertIn("Context 'work' set.", out)
self.assertNotIn("context=home\n", self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count("context=work\n"), 1)
# Switch back to home context
code, out, err = self.t('context home')
code, out, err = self.t("context home")
self.assertIn("Context 'home' set.", out)
self.assertNotIn("context=work\n", self.t.taskrc_content)
self.assertEqual(self.t.taskrc_content.count("context=home\n"), 1)
def test_context_unsetting(self):
"""Test removing the context."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
self.t('context home')
code, out, err = self.t('context none')
self.t("context home")
code, out, err = self.t("context none")
# Assert expected output.
self.assertIn("Context unset.", out)
# Assert no context definition in the taskrc
contains_any_context = lambda line: re.match('^context=', line)
self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content))
contains_any_context = lambda line: re.match("^context=", line)
self.assertFalse(
any(contains_any_context(line) for line in self.t.taskrc_content)
)
# Assert no context showing up using show subcommand
code, out, err = self.t('context show')
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
def test_context_unsetting_after_switching(self):
"""Test unsetting the context after changing the context around."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
# Switch to contexts around
self.t('context home')
self.t('context work')
self.t('context home')
self.t("context home")
self.t("context work")
self.t("context home")
# Unset the context
code, out, err = self.t('context none')
code, out, err = self.t("context none")
# Assert expected output.
self.assertIn("Context unset.", out)
# Assert no context definition in the taskrc
contains_any_context = lambda line: re.match('^context=', line)
self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content))
contains_any_context = lambda line: re.match("^context=", line)
self.assertFalse(
any(contains_any_context(line) for line in self.t.taskrc_content)
)
# Assert no context showing up using show subcommand
code, out, err = self.t('context show')
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
def test_context_unsetting_with_no_context_set(self):
"""Test removing the context when no context is set."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
code, out, err = self.t.runError('context none')
code, out, err = self.t.runError("context none")
# Assert expected output.
self.assertIn("Context not unset.", err)
# Assert no context definition in the taskrc
contains_any_context = lambda line: re.match('^context=', line)
self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content))
contains_any_context = lambda line: re.match("^context=", line)
self.assertFalse(
any(contains_any_context(line) for line in self.t.taskrc_content)
)
# Assert no context showing up using show subcommand
code, out, err = self.t('context show')
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
def test_context(self):
"""Test the _context command."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
code, out, err = self.t('_context')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
code, out, err = self.t("_context")
# Assert expected output.
self.assertIn("work", out.splitlines())
@@ -366,12 +393,12 @@ class ContextManagementTest(TestCase):
def test_context_completion(self):
"""Test the _context command with some context set."""
self.t('context define work project:Work', input='y\ny\n')
self.t('context define home +home', input='y\ny\n')
self.t("context define work project:Work", input="y\ny\n")
self.t("context define home +home", input="y\ny\n")
# Activate some context
self.t('context work')
code, out, err = self.t('_context')
self.t("context work")
code, out, err = self.t("_context")
# Assert expected output.
self.assertIn("work", out.splitlines())
@@ -386,9 +413,9 @@ class ContextEvaluationTest(TestCase):
self.t.config("confirmation", "off")
# Setup contexts
self.t('context define work project:Work')
self.t('context define home +home')
self.t('context define today due:today')
self.t("context define work project:Work")
self.t("context define home +home")
self.t("context define today due:today")
# Setup tasks
self.t('add project:Work "work task"')
@@ -398,7 +425,7 @@ class ContextEvaluationTest(TestCase):
def test_context_evaluation(self):
"""Test the context applied with report list command."""
code, out, err = self.t('list')
code, out, err = self.t("list")
# Assert all the tasks are present in the output
self.assertIn("work task", out)
@@ -407,8 +434,8 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the home context and rerun the report
self.t('context home')
code, out, err = self.t('list')
self.t("context home")
code, out, err = self.t("list")
# Assert all the tasks with the home tag are present in the output
self.assertNotIn("work task", out)
@@ -418,7 +445,7 @@ class ContextEvaluationTest(TestCase):
def test_context_evaluation_switching(self):
"""Test swtiching context using the list report."""
code, out, err = self.t('list')
code, out, err = self.t("list")
# Assert all the tasks are present in the output
self.assertIn("work task", out)
@@ -427,8 +454,8 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the home context and rerun the report
self.t('context home')
code, out, err = self.t('list')
self.t("context home")
code, out, err = self.t("list")
# Assert all the tasks with the home tag are present in the output
self.assertNotIn("work task", out)
@@ -437,8 +464,8 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the work context and rerun the report
self.t('context work')
code, out, err = self.t('list')
self.t("context work")
code, out, err = self.t("list")
# Assert all the tasks with the home tag are present in the output
self.assertIn("work task", out)
@@ -447,8 +474,8 @@ class ContextEvaluationTest(TestCase):
self.assertNotIn("home today task", out)
# Set the today context and rerun the report
self.t('context today')
code, out, err = self.t('list')
self.t("context today")
code, out, err = self.t("list")
# Assert all the tasks with the home tag are present in the output
self.assertNotIn("work task", out)
@@ -458,8 +485,8 @@ class ContextEvaluationTest(TestCase):
def test_context_evaluation_unset(self):
"""Test unsetting context with report list command."""
self.t('context home')
code, out, err = self.t('list')
self.t("context home")
code, out, err = self.t("list")
# Assert all the tasks home tagged tasks are present
self.assertNotIn("work task", out)
@@ -468,8 +495,8 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the context to none
self.t('context none')
code, out, err = self.t('list')
self.t("context none")
code, out, err = self.t("list")
# Assert all the tasks are present in the output
self.assertIn("work task", out)
@@ -481,8 +508,8 @@ class ContextEvaluationTest(TestCase):
"""Test the context applied with report list command combined with user filters."""
# Set the home context
self.t('context home')
code, out, err = self.t('list due:today')
self.t("context home")
code, out, err = self.t("list due:today")
# Assert all the tasks are present in the output
self.assertNotIn("work task", out)
@@ -491,8 +518,8 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the work context and rerun the report
self.t('context work')
code, out, err = self.t('list due:today')
self.t("context work")
code, out, err = self.t("list due:today")
# Assert all the tasks are present in the output
self.assertNotIn("work task", out)
@@ -506,10 +533,10 @@ class ContextEvaluationTest(TestCase):
filters are used.
"""
self.t('context home')
self.t("context home")
# Try task not included in context
output = self.t('1 list')[1]
output = self.t("1 list")[1]
# Assert that ID filter works even if it does not match the context
self.assertIn("work task", output)
@@ -518,7 +545,7 @@ class ContextEvaluationTest(TestCase):
self.assertNotIn("home today task", output)
# Try task included in context
output = self.t('2 list')[1]
output = self.t("2 list")[1]
# Assert that ID filter works if it does match
# the context (sanity check)
@@ -528,7 +555,7 @@ class ContextEvaluationTest(TestCase):
self.assertNotIn("home today task", output)
# Test for combination of IDs
output = self.t('1 2 list')[1]
output = self.t("1 2 list")[1]
# Assert that ID filter works if it partly matches
# and partly does not match the context
@@ -543,12 +570,12 @@ class ContextEvaluationTest(TestCase):
filters are used.
"""
self.t('context home')
first_uuid = self.t('_get 1.uuid')[1]
second_uuid = self.t('_get 2.uuid')[1]
self.t("context home")
first_uuid = self.t("_get 1.uuid")[1]
second_uuid = self.t("_get 2.uuid")[1]
# Try task not included in context
output = self.t('%s list' % first_uuid)[1]
output = self.t("%s list" % first_uuid)[1]
# Assert that UUID filter works even if it does not match
# the context
@@ -558,7 +585,7 @@ class ContextEvaluationTest(TestCase):
self.assertNotIn("home today task", output)
# Try task included in context
output = self.t('%s list' % second_uuid)[1]
output = self.t("%s list" % second_uuid)[1]
# Assert that UUID filter works if it does match
# the context (sanity check)
@@ -568,7 +595,7 @@ class ContextEvaluationTest(TestCase):
self.assertNotIn("home today task", output)
# Test for combination of UUIDs
output = self.t('%s %s list' % (first_uuid, second_uuid))[1]
output = self.t("%s %s list" % (first_uuid, second_uuid))[1]
# Assert that UUID filter works if it partly matches
# and partly does not match the context
@@ -585,7 +612,7 @@ class ContextEvaluationTest(TestCase):
self.t.config("report.list.context", "0")
# Get the tasks
code, out, err = self.t('list')
code, out, err = self.t("list")
# Assert all the tasks are present in the output
self.assertIn("work task", out)
@@ -594,9 +621,9 @@ class ContextEvaluationTest(TestCase):
self.assertIn("home today task", out)
# Set the home context and rerun the report
self.t('context home')
self.t("context home")
code, out, err = self.t('list')
code, out, err = self.t("list")
# Assert nothing changed - all the tasks are present in the output
self.assertIn("work task", out)
@@ -643,7 +670,10 @@ class ContextErrorHandling(TestCase):
"""Verify 'task context show' with contexts works"""
self.t.config("confirmation", "off")
code, out, err = self.t("context define work +work")
self.assertIn("Context 'work' defined (read, write). Use 'task context work' to activate.", out)
self.assertIn(
"Context 'work' defined (read, write). Use 'task context work' to activate.",
out,
)
code, out, err = self.t("context work")
self.assertIn("Context 'work' set. Use 'task context none' to remove.", out)
@@ -660,6 +690,7 @@ class ContextErrorHandling(TestCase):
code, out, err = self.t("context show")
self.assertIn("No context is currently applied.", out)
class TestBug1734(TestCase):
def setUp(self):
self.t = Task()
@@ -679,6 +710,7 @@ class TestBug1734(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python syntax=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -56,6 +57,7 @@ class TestCount(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -41,10 +42,12 @@ class TestCustomConfig(TestCase):
self.t.config("alias.xyzzyx", "status:waiting")
self.t.config("imnotrecognized", "kai")
self.DIFFER_MSG = ("Some of your .taskrc variables differ from the "
"default values.")
self.NOT_RECOG_MSG = ("Your .taskrc file contains these unrecognized "
"variables:")
self.DIFFER_MSG = (
"Some of your .taskrc variables differ from the " "default values."
)
self.NOT_RECOG_MSG = (
"Your .taskrc file contains these unrecognized " "variables:"
)
def test_show_alias(self):
"""task show <filter> - warns when non-default values are matched
@@ -89,6 +92,7 @@ class TestCustomConfig(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -41,26 +42,27 @@ class TestCustomRecurIndicator(TestCase):
def test_recurrence_indicator(self):
"""Add a recurring and non-recurring task, look for the indicator."""
self.t.config("report.foo.columns", "id,recur.indicator")
self.t.config("report.foo.labels", "ID,R")
self.t.config("report.foo.sort", "id+")
self.t.config("verbose", "nothing")
self.t.config("report.foo.columns", "id,recur.indicator")
self.t.config("report.foo.labels", "ID,R")
self.t.config("report.foo.sort", "id+")
self.t.config("verbose", "nothing")
self.t("add foo due:tomorrow recur:weekly")
self.t("add bar")
code, out, err = self.t("foo")
self.assertIn(" 1 R", out)
self.assertIn(" 2", out)
self.assertIn(" 2", out)
self.assertIn(" 3 R", out)
code, out, err = self.t("foo rc.recurrence.indicator=RE")
self.assertIn(" 1 RE", out)
self.assertIn(" 2", out)
self.assertIn(" 2", out)
self.assertIn(" 3 RE", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -40,9 +41,9 @@ class TestCustomTagIndicator(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.foo.description", "DESC")
cls.t.config("report.foo.columns", "id,tags.indicator")
cls.t.config("report.foo.labels", "ID,T")
cls.t.config("report.foo.sort", "id+")
cls.t.config("report.foo.columns", "id,tags.indicator")
cls.t.config("report.foo.labels", "ID,T")
cls.t.config("report.foo.sort", "id+")
cls.t("add foo +tag")
cls.t("add bar")
@@ -61,6 +62,7 @@ class TestCustomTagIndicator(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -39,10 +40,10 @@ class TestCustomReports(TestCase):
"""Executed before each test in the class"""
self.t = Task()
self.t.config("report.foo.description", "DESC")
self.t.config("report.foo.labels", "ID,DESCRIPTION")
self.t.config("report.foo.columns", "id,description")
self.t.config("report.foo.sort", "id+")
self.t.config("report.foo.filter", "project:A")
self.t.config("report.foo.labels", "ID,DESCRIPTION")
self.t.config("report.foo.columns", "id,description")
self.t.config("report.foo.sort", "id+")
self.t.config("report.foo.filter", "project:A")
def test_custom_report_help(self):
"""Verify custom report description is shown in help"""
@@ -72,19 +73,23 @@ class TestCustomReports(TestCase):
code, out, err = self.t("foo rc._forcecolor:on rc.report.foo.filter:")
self.assertIn("[44m", out)
class TestCustomErrorHandling(TestCase):
def setUp(self):
self.t = Task()
def test_size_mismatch(self):
self.t.config("report.foo.columns", "id,description")
self.t.config("report.foo.labels", "id")
self.t.config("report.foo.labels", "id")
code, out, err = self.t.runError("foo")
self.assertIn("There are different numbers of columns and labels for report 'foo'.", err)
self.assertIn(
"There are different numbers of columns and labels for report 'foo'.", err
)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -60,6 +61,7 @@ class TestDateISOAndEpoch(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -40,8 +41,8 @@ class TestDateformat(TestCase):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.xxx.columns", "id,due")
cls.t.config("report.xxx.labels", "ID,DUE")
cls.t.config("report.xxx.sort", "id")
cls.t.config("report.xxx.labels", "ID,DUE")
cls.t.config("report.xxx.sort", "id")
def setUp(self):
"""Executed before each test in the class"""
@@ -55,6 +56,7 @@ class TestDateformat(TestCase):
code, out, err = self.t("xxx rc.dateformat:YMDTHNS")
self.assertEqual(out.count("20150704T000000"), 3)
class TestBug886(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -63,12 +65,12 @@ class TestBug886(TestCase):
def test_invalid_day(self):
"""886: Test invalid day synonym
Bug 886: tw doesn't warn the user if, e.g., a weekday cannot be resolved properly
Bug 886: tw doesn't warn the user if, e.g., a weekday cannot be resolved properly
"""
code, out, err =self.t("add one due:sun")
code, out, err = self.t("add one due:sun")
self.assertIn("Created task 1.", out)
code, out, err =self.t.runError("add two due:donkey")
code, out, err = self.t.runError("add two due:donkey")
self.assertIn("'donkey' is not a valid date", err)
@@ -79,33 +81,36 @@ class TestBug986(TestCase):
def test_dateformat_precedence(self):
"""986: Verify rc.dateformat.info takes precedence over rc.dateformat"""
self.t('add test')
self.t('1 start')
self.t("add test")
self.t("1 start")
code, out, err = self.t('1 info rc.dateformat:XX rc.dateformat.info:__')
self.assertIn('__', out)
self.assertNotIn('XX', out)
code, out, err = self.t("1 info rc.dateformat:XX rc.dateformat.info:__")
self.assertIn("__", out)
self.assertNotIn("XX", out)
code, out, err = self.t('1 info rc.dateformat:__ rc.dateformat.info:')
self.assertIn('__', out)
code, out, err = self.t("1 info rc.dateformat:__ rc.dateformat.info:")
self.assertIn("__", out)
class TestBug1620(TestCase):
def setUp(self):
"""Executed before each test in the class"""
self.t = Task()
self.t.config('dateformat', 'YMD-HN')
self.t.config("dateformat", "YMD-HN")
def test_dateformat_overrides_iso(self):
"""1620: Verify that a defined dateformat overrides the ISO interpretation"""
code, out, err = self.t ('add pro:vorhaben due:20150601-1415 tatusmeeting vorbereiten')
code, out, err = self.t(
"add pro:vorhaben due:20150601-1415 tatusmeeting vorbereiten"
)
code, out, err = self.t ('_get 1.due')
code, out, err = self.t("_get 1.due")
self.assertEqual(out, "2015-06-01T14:15:00\n")
code, out, err = self.t ('long')
code, out, err = self.t("long")
self.assertIn("20150601-1415", out)
class TestCapitalizedDays(TestCase):
"""Make sure capitalized names such as 'Friday' work.
@@ -124,28 +129,30 @@ class TestCapitalizedDays(TestCase):
def test_dateformat_capitalized(self):
"""Verify upper case days and months work"""
# Lower case:
code, out, err = self.t('add sometask due:mon')
code, out, err = self.t('add sometask due:monday')
code, out, err = self.t('add sometask due:jan')
code, out, err = self.t('add sometask due:january')
code, out, err = self.t("add sometask due:mon")
code, out, err = self.t("add sometask due:monday")
code, out, err = self.t("add sometask due:jan")
code, out, err = self.t("add sometask due:january")
# Upper case days of the week
code, out, err = self.t('add sometask due:Tue')
code, out, err = self.t('add sometask due:Tuesday')
code, out, err = self.t('add sometask due:Thu')
code, out, err = self.t('add sometask due:Thursday')
code, out, err = self.t("add sometask due:Tue")
code, out, err = self.t("add sometask due:Tuesday")
code, out, err = self.t("add sometask due:Thu")
code, out, err = self.t("add sometask due:Thursday")
# Upper case months:
code, out, err = self.t('add sometask due:Jan')
code, out, err = self.t('add sometask due:January')
code, out, err = self.t('add sometask due:Jun')
code, out, err = self.t('add sometask due:June')
code, out, err = self.t('add sometask due:May')
code, out, err = self.t("add sometask due:Jan")
code, out, err = self.t("add sometask due:January")
code, out, err = self.t("add sometask due:Jun")
code, out, err = self.t("add sometask due:June")
code, out, err = self.t("add sometask due:May")
# Incorrect:
code, out, err = self.t.runError('add sometask due:Yo')
code, out, err = self.t.runError('add sometask due:TU')
code, out, err = self.t.runError("add sometask due:Yo")
code, out, err = self.t.runError("add sometask due:TU")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -41,13 +42,13 @@ class TestDateSort(TestCase):
def test_datesort(self):
"""Verify dates sort properly with a report date format that hides date details"""
self.t.config("verbose", "nothing")
self.t.config("dateformat", "YMD")
self.t.config("report.small_list.columns", "due,description")
self.t.config("report.small_list.labels", "Due,Description")
self.t.config("report.small_list.sort", "due+")
self.t.config("report.small_list.filter", "status:pending")
self.t.config("report.small_list.dateformat", "D")
self.t.config("verbose", "nothing")
self.t.config("dateformat", "YMD")
self.t.config("report.small_list.columns", "due,description")
self.t.config("report.small_list.labels", "Due,Description")
self.t.config("report.small_list.sort", "due+")
self.t.config("report.small_list.filter", "status:pending")
self.t.config("report.small_list.dateformat", "D")
self.t("add one due:20150101")
self.t("add two due:20150201")
@@ -65,6 +66,7 @@ class TestDateSort(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -44,10 +44,10 @@ class BaseDateTimeNegativeTest(TestCase):
self.t = Task()
def assertInvalidDatetimeFormat(self, value):
self.t.runError('add due:{0} test1'.format(value))
self.t.runError('add scheduled:{0} test2'.format(value))
self.t.runError('add wait:{0} test3'.format(value))
self.t.runError('add until:{0} test4'.format(value))
self.t.runError("add due:{0} test1".format(value))
self.t.runError("add scheduled:{0} test2".format(value))
self.t.runError("add wait:{0} test3".format(value))
self.t.runError("add until:{0} test4".format(value))
class TestIncorrectDate(BaseDateTimeNegativeTest):
@@ -58,60 +58,60 @@ class TestIncorrectDate(BaseDateTimeNegativeTest):
"""
def test_set_incorrect_datetime_randomstring(self):
self.assertInvalidDatetimeFormat('random')
self.assertInvalidDatetimeFormat("random")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_in_YYYY_MM_DD(self):
self.assertInvalidDatetimeFormat('-2014-07-07')
self.assertInvalidDatetimeFormat("-2014-07-07")
def test_set_incorrect_datetime_missing_day_in_YYYY_MM_DD(self):
self.assertInvalidDatetimeFormat('2014-07-')
self.assertInvalidDatetimeFormat("2014-07-")
def test_set_incorrect_datetime_month_zero_in_YYYY_MM_DD(self):
self.assertInvalidDatetimeFormat('2014-0-12')
self.assertInvalidDatetimeFormat("2014-0-12")
def test_set_incorrect_datetime_invalid_characters_in_YYYY_MM_DD(self):
self.assertInvalidDatetimeFormat('abcd-ab-ab')
self.assertInvalidDatetimeFormat("abcd-ab-ab")
def test_set_incorrect_datetime_day_as_zeros_in_YYYY_DDD(self):
self.assertInvalidDatetimeFormat('2014-000')
self.assertInvalidDatetimeFormat("2014-000")
def test_set_incorrect_datetime_overlap_day_in_nonoverlap_year_in_YYYY_DDD(self):
self.assertInvalidDatetimeFormat('2014-366')
self.assertInvalidDatetimeFormat("2014-366")
def test_set_incorrect_datetime_medium_overlap_day_in_YYYY_DDD(self):
self.assertInvalidDatetimeFormat('2014-999')
self.assertInvalidDatetimeFormat("2014-999")
def test_set_incorrect_datetime_huge_overlap_day_in_YYYY_DDD(self):
self.assertInvalidDatetimeFormat('2014-999999999')
self.assertInvalidDatetimeFormat("2014-999999999")
def test_set_incorrect_datetime_week_with_the_number_zero_in_YYYY_Www(self):
self.assertInvalidDatetimeFormat('2014-W00')
self.assertInvalidDatetimeFormat("2014-W00")
def test_set_incorrect_datetime_overflow_in_week_in_YYYY_Www(self):
self.assertInvalidDatetimeFormat('2014-W54')
self.assertInvalidDatetimeFormat("2014-W54")
# Unsupported non-extended form.
def test_set_incorrect_datetime_day_zero_in_YYYY_WwwD(self):
self.assertInvalidDatetimeFormat('2014-W240')
self.assertInvalidDatetimeFormat("2014-W240")
# Unsupported non-extended form.
def test_set_incorrect_datetime_day_eight_in_YYYY_WwwD(self):
self.assertInvalidDatetimeFormat('2014-W248')
self.assertInvalidDatetimeFormat("2014-W248")
# Unsupported non-extended form.
def test_set_incorrect_datetime_day_two_hundred_in_YYYY_WwwD(self):
self.assertInvalidDatetimeFormat('2014-W24200')
self.assertInvalidDatetimeFormat("2014-W24200")
# Disabled: Looks like 'hhmm-hh'
#def test_set_incorrect_datetime_month_zero_in_YYYY_MM(self):
# def test_set_incorrect_datetime_month_zero_in_YYYY_MM(self):
# self.assertInvalidDatetimeFormat('2014-00')
def test_set_incorrect_datetime_overflow_month_in_YYYY_MM(self):
self.assertInvalidDatetimeFormat('2014-13')
self.assertInvalidDatetimeFormat("2014-13")
def test_set_incorrect_datetime_huge_overflow_month_in_YYYY_MM(self):
self.assertInvalidDatetimeFormat('2014-99')
self.assertInvalidDatetimeFormat("2014-99")
class TestIncorrectTime(BaseDateTimeNegativeTest):
@@ -121,276 +121,276 @@ class TestIncorrectTime(BaseDateTimeNegativeTest):
"""
def test_set_incorrect_datetime_hour_overflow_in_hh_mm(self):
self.assertInvalidDatetimeFormat('25:00')
self.assertInvalidDatetimeFormat("25:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm(self):
self.assertInvalidDatetimeFormat('99:00')
self.assertInvalidDatetimeFormat("99:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm(self):
self.assertInvalidDatetimeFormat('12:60')
self.assertInvalidDatetimeFormat("12:60")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm(self):
self.assertInvalidDatetimeFormat('12:99')
self.assertInvalidDatetimeFormat("12:99")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm(self):
self.assertInvalidDatetimeFormat('12:ab')
self.assertInvalidDatetimeFormat("12:ab")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:12')
self.assertInvalidDatetimeFormat("ab:12")
def test_set_incorrect_datetime_invalid_time_in_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:cd')
self.assertInvalidDatetimeFormat("ab:cd")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm(self):
self.assertInvalidDatetimeFormat('-12:12')
self.assertInvalidDatetimeFormat("-12:12")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm(self):
self.assertInvalidDatetimeFormat('12:-12')
self.assertInvalidDatetimeFormat("12:-12")
def test_set_incorrect_datetime_hour_overflow_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('25:00Z')
self.assertInvalidDatetimeFormat("25:00Z")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('99:00Z')
self.assertInvalidDatetimeFormat("99:00Z")
def test_set_incorrect_datetime_minute_overflow_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('12:60Z')
self.assertInvalidDatetimeFormat("12:60Z")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('12:99Z')
self.assertInvalidDatetimeFormat("12:99Z")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('12:abZ')
self.assertInvalidDatetimeFormat("12:abZ")
def test_set_incorrect_datetime_invalid_hours_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('ab:12Z')
self.assertInvalidDatetimeFormat("ab:12Z")
def test_set_incorrect_datetime_invalid_time_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('ab:cdZ')
self.assertInvalidDatetimeFormat("ab:cdZ")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('-12:12Z')
self.assertInvalidDatetimeFormat("-12:12Z")
def test_set_incorrect_datetime_negative_minutes_in_hh_mmZ(self):
self.assertInvalidDatetimeFormat('12:-12Z')
self.assertInvalidDatetimeFormat("12:-12Z")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('25:00+01:00')
self.assertInvalidDatetimeFormat("25:00+01:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('99:00+01:00')
self.assertInvalidDatetimeFormat("99:00+01:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:60+01:00')
self.assertInvalidDatetimeFormat("12:60+01:00")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:99+01:00')
self.assertInvalidDatetimeFormat("12:99+01:00")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:ab+01:00')
self.assertInvalidDatetimeFormat("12:ab+01:00")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:12+01:00')
self.assertInvalidDatetimeFormat("ab:12+01:00")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:cd+01:00')
self.assertInvalidDatetimeFormat("ab:cd+01:00")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('-12:12+01:00')
self.assertInvalidDatetimeFormat("-12:12+01:00")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:-12+01:00')
self.assertInvalidDatetimeFormat("12:-12+01:00")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('25:00-01:00')
self.assertInvalidDatetimeFormat("25:00-01:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('99:00-01:00')
self.assertInvalidDatetimeFormat("99:00-01:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:60-01:00')
self.assertInvalidDatetimeFormat("12:60-01:00")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:99-01:00')
self.assertInvalidDatetimeFormat("12:99-01:00")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:ab-01:00')
self.assertInvalidDatetimeFormat("12:ab-01:00")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:12-01:00')
self.assertInvalidDatetimeFormat("ab:12-01:00")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:cd-01:00')
self.assertInvalidDatetimeFormat("ab:cd-01:00")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('-12:12-01:00')
self.assertInvalidDatetimeFormat("-12:12-01:00")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:-12-01:00')
self.assertInvalidDatetimeFormat("12:-12-01:00")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('25:00:00')
self.assertInvalidDatetimeFormat("25:00:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('99:00:00')
self.assertInvalidDatetimeFormat("99:00:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:60:00')
self.assertInvalidDatetimeFormat("12:60:00")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:99:00')
self.assertInvalidDatetimeFormat("12:99:00")
def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:12:60')
self.assertInvalidDatetimeFormat("12:12:60")
def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:12:99')
self.assertInvalidDatetimeFormat("12:12:99")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:ab:00')
self.assertInvalidDatetimeFormat("12:ab:00")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('ab:12:00')
self.assertInvalidDatetimeFormat("ab:12:00")
def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:12:ab')
self.assertInvalidDatetimeFormat("12:12:ab")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('ab:cd:ef')
self.assertInvalidDatetimeFormat("ab:cd:ef")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('-12:12:12')
self.assertInvalidDatetimeFormat("-12:12:12")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:-12:12')
self.assertInvalidDatetimeFormat("12:-12:12")
def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss(self):
self.assertInvalidDatetimeFormat('12:12:-12')
self.assertInvalidDatetimeFormat("12:12:-12")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('25:00:00Z')
self.assertInvalidDatetimeFormat("25:00:00Z")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('99:00:00Z')
self.assertInvalidDatetimeFormat("99:00:00Z")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:60:00Z')
self.assertInvalidDatetimeFormat("12:60:00Z")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:99:00Z')
self.assertInvalidDatetimeFormat("12:99:00Z")
def test_set_incorrect_datetime_second_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:12:60Z')
self.assertInvalidDatetimeFormat("12:12:60Z")
def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:12:99Z')
self.assertInvalidDatetimeFormat("12:12:99Z")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:ab:00Z')
self.assertInvalidDatetimeFormat("12:ab:00Z")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('ab:12:00Z')
self.assertInvalidDatetimeFormat("ab:12:00Z")
def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:12:abZ')
self.assertInvalidDatetimeFormat("12:12:abZ")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('ab:cd:efZ')
self.assertInvalidDatetimeFormat("ab:cd:efZ")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('-12:12:12Z')
self.assertInvalidDatetimeFormat("-12:12:12Z")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:-12:12Z')
self.assertInvalidDatetimeFormat("12:-12:12Z")
def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ssZ(self):
self.assertInvalidDatetimeFormat('12:12:-12Z')
self.assertInvalidDatetimeFormat("12:12:-12Z")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('25:00:00+01:00')
self.assertInvalidDatetimeFormat("25:00:00+01:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('95:00:00+01:00')
self.assertInvalidDatetimeFormat("95:00:00+01:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:60:00+01:00')
self.assertInvalidDatetimeFormat("12:60:00+01:00")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:99:00+01:00')
self.assertInvalidDatetimeFormat("12:99:00+01:00")
def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:60+01:00')
self.assertInvalidDatetimeFormat("12:12:60+01:00")
def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:99+01:00')
self.assertInvalidDatetimeFormat("12:12:99+01:00")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:ab:00+01:00')
self.assertInvalidDatetimeFormat("12:ab:00+01:00")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:12:00+01:00')
self.assertInvalidDatetimeFormat("ab:12:00+01:00")
def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:ab+01:00')
self.assertInvalidDatetimeFormat("12:12:ab+01:00")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:cd:ef+01:00')
self.assertInvalidDatetimeFormat("ab:cd:ef+01:00")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('-12:12:12+01:00')
self.assertInvalidDatetimeFormat("-12:12:12+01:00")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:-12:12+01:00')
self.assertInvalidDatetimeFormat("12:-12:12+01:00")
def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss_plus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:-12+01:00')
self.assertInvalidDatetimeFormat("12:12:-12+01:00")
def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('25:00:00-01:00')
self.assertInvalidDatetimeFormat("25:00:00-01:00")
def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('95:00:00-01:00')
self.assertInvalidDatetimeFormat("95:00:00-01:00")
def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:60:00-01:00')
self.assertInvalidDatetimeFormat("12:60:00-01:00")
def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:99:00-01:00')
self.assertInvalidDatetimeFormat("12:99:00-01:00")
def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:60-01:00')
self.assertInvalidDatetimeFormat("12:12:60-01:00")
def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:99-01:00')
self.assertInvalidDatetimeFormat("12:12:99-01:00")
def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:ab:00-01:00')
self.assertInvalidDatetimeFormat("12:ab:00-01:00")
def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:12:00-01:00')
self.assertInvalidDatetimeFormat("ab:12:00-01:00")
def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:ab-01:00')
self.assertInvalidDatetimeFormat("12:12:ab-01:00")
def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('ab:cd:ef-01:00')
self.assertInvalidDatetimeFormat("ab:cd:ef-01:00")
@unittest.skip # see #2996
def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('-12:12:12-01:00')
self.assertInvalidDatetimeFormat("-12:12:12-01:00")
def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:-12:12-01:00')
self.assertInvalidDatetimeFormat("12:-12:12-01:00")
def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss_minus_hh_mm(self):
self.assertInvalidDatetimeFormat('12:12:-12-01:00')
self.assertInvalidDatetimeFormat("12:12:-12-01:00")
# There were a group of tests that failed for the wrong reason, and these
# have been removed.
@@ -434,8 +434,10 @@ class TestIncorrectTime(BaseDateTimeNegativeTest):
# 12:12+03:2
# 12:12+3:2
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -87,6 +88,7 @@ class TestDebugMode(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -40,8 +41,8 @@ class TestCMD(TestCase):
cls.t = Task()
cls.t.config("default.command", "list")
cls.t('add one')
cls.t('add two')
cls.t("add one")
cls.t("add two")
def test_default_command(self):
"""default command"""
@@ -51,8 +52,8 @@ class TestCMD(TestCase):
def test_info_command(self):
"""info command"""
code, out, err = self.t('1')
self.assertRegex(out, r'Description\s+one')
code, out, err = self.t("1")
self.assertRegex(out, r"Description\s+one")
class TestDefaults(TestCase):
@@ -60,11 +61,11 @@ class TestDefaults(TestCase):
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("default.command", "list")
cls.t.config("default.project", "PROJECT")
cls.t.config("default.command", "list")
cls.t.config("default.project", "PROJECT")
cls.t.config("uda.priority.default", "M")
cls.t.config("default.due", "eom")
cls.t.config("default.scheduled", "eom")
cls.t.config("default.due", "eom")
cls.t.config("default.scheduled", "eom")
def test_all_defaults(self):
"""Verify all defaults are employed"""
@@ -125,6 +126,7 @@ class TestBug1377(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -46,7 +47,7 @@ class TestDelete(TestCase):
uuid = out.strip()
self.t("1 delete", input="y\n")
self.t.runError("list") # GC/handleRecurrence
self.t.runError("list") # GC/handleRecurrence
code, out, err = self.t("_get 1.status")
self.assertEqual("\n", out)
@@ -77,7 +78,7 @@ class TestDelete(TestCase):
code, out, err = self.t("1 done")
self.assertIn("Completed 1 task.", out)
self.t("all") # GC/handleRecurrence
self.t("all") # GC/handleRecurrence
code, out, err = self.t("%s delete" % uuid, input="y\n")
self.assertIn("Deleted 1 task.", out)
@@ -141,6 +142,7 @@ class TestDelete(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -68,7 +69,9 @@ class TestDenotate(TestCase):
# Failed partial match, one annotation
code, out, err = self.t.runError("rc.search.case.sensitive=yes 2 denotate AL")
self.assertIn("Did not find any matching annotation to be deleted for 'AL'.", out)
self.assertIn(
"Did not find any matching annotation to be deleted for 'AL'.", out
)
# Exact match, two annotations
code, out, err = self.t("1 denotate beta")
@@ -91,6 +94,7 @@ class TestDenotate(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import string
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -81,9 +82,9 @@ class TestDependencies(TestCase):
def test_circular_5(self):
"""Check circular dependencies are caught, using 5 tasks"""
self.t("add three")
self.t("add four")
self.t("add five")
self.t("add three")
self.t("add four")
self.t("add five")
self.t("5 modify dep:4")
self.t("4 modify dep:3")
self.t("3 modify dep:2")
@@ -116,9 +117,9 @@ class TestDependencies(TestCase):
def test_modify_multiple(self):
"""Check circular dependencies are caught, using 5 tasks"""
self.t("add three")
self.t("add four")
self.t("add five")
self.t("add three")
self.t("add four")
self.t("add five")
code, out, err = self.t("1 modify dep:2,3,4")
self.assertIn("Modified 1 task.", out)
@@ -235,18 +236,18 @@ class TestBug697(TestCase):
def test_blocking_to_recurring(self):
"""697: Verify that making a blocking task into a recurring task breaks dependencies
Bug 697: Making a blocking task recur breaks dependency.
1. Create 2 tasks: "foo" and "bar".
2. Give "bar" a due date.
3. Make "foo" depend on "bar".
4. Make "bar" recur yearly.
Bug 697: Making a blocking task recur breaks dependency.
1. Create 2 tasks: "foo" and "bar".
2. Give "bar" a due date.
3. Make "foo" depend on "bar".
4. Make "bar" recur yearly.
"""
self.t("add one")
self.t("add two")
self.t("2 modify due:eom")
self.t("1 modify depends:2")
self.t("2 modify recur:yearly")
self.t("list") # GC/handleRecurrence
self.t("list") # GC/handleRecurrence
# The problem is that although 1 --> 2, 2 is now a recurring parent, and as 1
# depends on the parent UUID, it is not something transferred to the child on
@@ -332,21 +333,21 @@ class TestFeature725(TestCase):
class Test1481(TestCase):
def setUp(self):
self.t = Task()
self.t('add parent')
self.t('add child')
self.t('add child2')
self.child1_uuid = self.t.export_one(2)['uuid']
self.child2_uuid = self.t.export_one(3)['uuid']
self.t("add parent")
self.t("add child")
self.t("add child2")
self.child1_uuid = self.t.export_one(2)["uuid"]
self.child2_uuid = self.t.export_one(3)["uuid"]
def test_set_dependency_on_first_completed_task(self):
"""1481: Sets dependency on task which has been just completed."""
self.t('2 done')
self.t("2 done")
# Trigger the GC to clear up IDs
self.t('next')
self.t("next")
# Set the dependency
self.t('1 modify depends:%s' % self.child1_uuid)
self.t("1 modify depends:%s" % self.child1_uuid)
def test_set_dependency_on_second_completed_task(self):
"""
@@ -354,26 +355,25 @@ class Test1481(TestCase):
before most recently completed task.
"""
self.t('2 done')
self.t('3 done')
self.t("2 done")
self.t("3 done")
# Trigger the GC to clear up IDs
self.t('next')
self.t("next")
# Set the dependencies
self.t('1 modify depends:%s' % self.child2_uuid)
self.t("1 modify depends:%s" % self.child2_uuid)
def test_set_dependency_on_two_completed_tasks(self):
""" 1481: Sets dependency on two most recent completed tasks. """
self.t('2 done')
self.t('3 done')
"""1481: Sets dependency on two most recent completed tasks."""
self.t("2 done")
self.t("3 done")
# Trigger the GC to clear up IDs
self.t('next')
self.t("next")
# Set the dependencies
self.t('1 modify depends:%s,%s' % (self.child1_uuid,
self.child2_uuid))
self.t("1 modify depends:%s,%s" % (self.child1_uuid, self.child2_uuid))
# TODO - test dependency.confirmation config variable
@@ -385,6 +385,7 @@ class Test1481(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import platform
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -38,11 +39,11 @@ from basetest import Task, TestCase
class TestDiagnostics(TestCase):
def setUp(self):
self.t = Task()
self.t.config("editor", "edlin")
self.t.config("editor", "edlin")
@unittest.skipIf(
getattr(platform, 'dist', None) == None or 'xenial' == platform.dist()[-1],
'Skipping diagnostics test on Ubuntu 16.04, as it lacks full C++17 support'
getattr(platform, "dist", None) == None or "xenial" == platform.dist()[-1],
"Skipping diagnostics test on Ubuntu 16.04, as it lacks full C++17 support",
)
def test_diagnostics(self):
"""Task diag output, so we can monitor platforms"""
@@ -60,6 +61,7 @@ class TestDiagnostics(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -69,6 +70,7 @@ class TestDiagColor(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -27,31 +27,23 @@
#include <cmake.h>
// cmake.h include header must come first
#include <test.h>
#include <DOM.h>
#include <Variant.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
bool providerString (const std::string& path, Variant& var)
{
if (path == "name")
{
var = Variant ("value");
bool providerString(const std::string& path, Variant& var) {
if (path == "name") {
var = Variant("value");
return true;
}
else if (path == "name.next")
{
var = Variant ("value.next");
} else if (path == "name.next") {
var = Variant("value.next");
return true;
}
else if (path == "foo")
{
var = Variant ("bar");
} else if (path == "foo") {
var = Variant("bar");
return true;
}
else if (path == "name.size")
{
var = Variant (6);
} else if (path == "name.size") {
var = Variant(6);
return true;
}
@@ -59,40 +51,39 @@ bool providerString (const std::string& path, Variant& var)
}
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest t (12);
int main(int, char**) {
UnitTest t(12);
DOM dom;
t.is (dom.count (), 0, "DOM empty count is zero");
t.is(dom.count(), 0, "DOM empty count is zero");
dom.addSource ("name", &providerString);
dom.addSource ("name.next", &providerString);
dom.addSource ("name.size", &providerString);
dom.addSource ("foo", &providerString);
t.diag (dom.dump ());
t.is (dom.count (), 4, "DOM now contains 4 nodes");
dom.addSource("name", &providerString);
dom.addSource("name.next", &providerString);
dom.addSource("name.size", &providerString);
dom.addSource("foo", &providerString);
t.diag(dom.dump());
t.is(dom.count(), 4, "DOM now contains 4 nodes");
t.ok (dom.valid ("name"), "DOM 'name' valid");
t.ok (dom.valid ("name.next"), "DOM 'name.next' valid");
t.ok (dom.valid ("name.size"), "DOM 'name.size' valid");
t.ok (dom.valid ("foo"), "DOM 'foo' valid");
t.notok (dom.valid ("missing"), "DOM 'missing' not valid");
t.ok(dom.valid("name"), "DOM 'name' valid");
t.ok(dom.valid("name.next"), "DOM 'name.next' valid");
t.ok(dom.valid("name.size"), "DOM 'name.size' valid");
t.ok(dom.valid("foo"), "DOM 'foo' valid");
t.notok(dom.valid("missing"), "DOM 'missing' not valid");
auto v = dom.get ("name");
t.is (v.get_string (), "value", "DOM get 'name' --> 'value'");
auto v = dom.get("name");
t.is(v.get_string(), "value", "DOM get 'name' --> 'value'");
v = dom.get ("name.next");
t.is (v.get_string (), "value.next", "DOM get 'name.next' --> 'value.next'");
v = dom.get("name.next");
t.is(v.get_string(), "value.next", "DOM get 'name.next' --> 'value.next'");
v = dom.get ("name.size");
t.is (v.get_integer (), 6, "DOM get 'name.size' --> 6");
v = dom.get("name.size");
t.is(v.get_integer(), 6, "DOM get 'name.size' --> 6");
v = dom.get ("foo");
t.is (v.get_string (), "bar", "DOM get 'name.size' --> 6");
v = dom.get("foo");
t.is(v.get_string(), "bar", "DOM get 'name.size' --> 6");
v = dom.get ("missing");
t.is (v.get_string (), "", "DOM get 'missing' --> ''");
v = dom.get("missing");
t.is(v.get_string(), "", "DOM get 'missing' --> ''");
return 0;
}

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -52,199 +53,201 @@ class TestDOM(TestCase):
cls.t("3 annotate note")
# Add task containing UDA attributes
cls.t("add ticket task "
"ticketdate:2015-09-04 "
"ticketest:hour "
"ticketnote:comment "
"ticketnum:47")
cls.t(
"add ticket task "
"ticketdate:2015-09-04 "
"ticketest:hour "
"ticketnote:comment "
"ticketnum:47"
)
def test_dom_no_ref(self):
""" DOM missing reference """
"""DOM missing reference"""
code, out, err = self.t.runError("_get")
self.assertEqual("No DOM reference specified.\n", err)
def test_dom_bad_ref(self):
""" DOM bad reference """
"""DOM bad reference"""
code, out, err = self.t.runError("_get donkey")
self.assertEqual("'donkey' is not a DOM reference.\n", err)
def test_dom_task_ref(self):
""" DOM reference to other task """
"""DOM reference to other task"""
code, out, err = self.t("_get 2.due")
self.assertIn("2011-09-01T00:00:00", out)
def test_dom_cli_ref(self):
""" DOM reference to current command line """
"""DOM reference to current command line"""
code, out, err = self.t("_get 3.wait")
self.assertIn("2011-09-01T00:00:00", out)
def test_dom_id_uuid_roundtrip(self):
""" DOM id/uuid roundtrip """
"""DOM id/uuid roundtrip"""
code, out, err = self.t("_get 1.uuid")
uuid = out.strip()
code, out, err = self.t("_get {0}.id".format(uuid))
self.assertEqual("1\n", out)
def test_dom_fail(self):
""" DOM lookup of missing item """
"""DOM lookup of missing item"""
code, out, err = self.t("_get 5.description")
self.assertEqual("\n", out)
def test_dom_tags(self):
""" DOM 3.tags """
"""DOM 3.tags"""
code, out, err = self.t("_get 3.tags")
self.assertEqual("tag1,tag2\n", out)
def test_dom_tags_tag1(self):
""" DOM 3.tags.tag1 """
"""DOM 3.tags.tag1"""
code, out, err = self.t("_get 3.tags.tag1")
self.assertEqual("tag1\n", out)
def test_dom_tags_OVERDUE(self):
""" DOM 3.tags.OVERDUE """
"""DOM 3.tags.OVERDUE"""
code, out, err = self.t("_get 3.tags.OVERDUE")
self.assertEqual("OVERDUE\n", out)
def test_dom_due_year(self):
""" DOM 3.due.year """
"""DOM 3.due.year"""
code, out, err = self.t("_get 3.due.year")
self.assertEqual("2011\n", out)
def test_dom_due_month(self):
""" DOM 3.due.month """
"""DOM 3.due.month"""
code, out, err = self.t("_get 3.due.month")
self.assertEqual("9\n", out)
def test_dom_due_day(self):
""" DOM 3.due.day """
"""DOM 3.due.day"""
code, out, err = self.t("_get 3.due.day")
self.assertEqual("1\n", out)
def test_dom_due_week(self):
""" DOM 3.due.week """
"""DOM 3.due.week"""
code, out, err = self.t("_get 3.due.week")
self.assertEqual("35\n", out)
def test_dom_due_weekday(self):
""" DOM 3.due.weekday """
"""DOM 3.due.weekday"""
code, out, err = self.t("_get 3.due.weekday")
self.assertEqual("4\n", out)
def test_dom_due_hour(self):
""" DOM 3.due.hour """
"""DOM 3.due.hour"""
code, out, err = self.t("_get 3.due.hour")
self.assertEqual("0\n", out)
def test_dom_due_minute(self):
""" DOM 3.due.minute """
"""DOM 3.due.minute"""
code, out, err = self.t("_get 3.due.minute")
self.assertEqual("0\n", out)
def test_dom_due_second(self):
""" DOM 3.due.second """
"""DOM 3.due.second"""
code, out, err = self.t("_get 3.due.second")
self.assertEqual("0\n", out)
def test_dom_annotation_count_1(self):
""" DOM 1.annotation.count """
"""DOM 1.annotation.count"""
code, out, err = self.t("_get 1.annotations.count")
self.assertEqual("0\n", out)
def test_dom_annotation_count_3(self):
""" DOM 3.annotation.count """
"""DOM 3.annotation.count"""
code, out, err = self.t("_get 3.annotations.count")
self.assertEqual("1\n", out)
def test_dom_annotation_entry(self):
""" DOM 3.annotations.1.entry """
"""DOM 3.annotations.1.entry"""
code, out, err = self.t("_get 3.annotations.1.entry")
self.assertRegex(out, r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}")
def test_dom_annotation_entry_second(self):
""" DOM 3.annotations.1.entry """
"""DOM 3.annotations.1.entry"""
code, out, err = self.t("_get 3.annotations.1.entry.second")
self.assertRegex(out, r"\d{1,2}")
def test_dom_annotation_description(self):
""" DOM 3.annotations.1.description """
"""DOM 3.annotations.1.description"""
code, out, err = self.t("_get 3.annotations.1.description")
self.assertIn("note\n", out)
def test_dom_system_version(self):
""" DOM system.version """
"""DOM system.version"""
code, out, err = self.t("_get system.version")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d\.\d+\.\d+")
def test_dom_system_os(self):
""" DOM system.os """
"""DOM system.os"""
code, out, err = self.t("_get system.os")
self.assertEqual(code, 0)
self.assertEqual(len(out) > 4, True)
self.assertNotIn("<unknown>", out)
def test_dom_tw_program(self):
""" DOM tw.program """
"""DOM tw.program"""
code, out, err = self.t("_get tw.program")
self.assertEqual(code, 0)
self.assertIn("task", out)
def test_dom_tw_args(self):
""" DOM tw.args """
"""DOM tw.args"""
code, out, err = self.t("_get tw.args")
self.assertEqual(code, 0)
self.assertIn("task _get tw.args", out)
def test_dom_tw_width(self):
""" DOM tw.width """
"""DOM tw.width"""
code, out, err = self.t("_get tw.width")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d+")
def test_dom_tw_height(self):
""" DOM tw.height """
"""DOM tw.height"""
code, out, err = self.t("_get tw.height")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d+")
def test_dom_tw_version(self):
""" DOM tw.version """
"""DOM tw.version"""
code, out, err = self.t("_get tw.version")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d\.\d+\.\d+")
def test_dom_context_program(self):
""" DOM context.program """
"""DOM context.program"""
code, out, err = self.t("_get context.program")
self.assertEqual(code, 0)
self.assertIn("task", out)
def test_dom_context_args(self):
""" DOM context.args """
"""DOM context.args"""
code, out, err = self.t("_get context.args")
self.assertEqual(code, 0)
self.assertIn("task _get context.args", out)
def test_dom_context_width(self):
""" DOM context.width """
"""DOM context.width"""
code, out, err = self.t("_get context.width")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d+")
def test_dom_context_height(self):
""" DOM context.height """
"""DOM context.height"""
code, out, err = self.t("_get context.height")
self.assertEqual(code, 0)
self.assertRegex(out, r"\d+")
def test_dom_rc_name(self):
""" DOM rc.dateformat """
"""DOM rc.dateformat"""
code, out, err = self.t("_get rc.dateformat")
self.assertEqual(code, 0)
self.assertIn("YMD", out)
def test_dom_rc_missing(self):
""" DOM rc.missing """
"""DOM rc.missing"""
code, out, err = self.t("_get rc.missing")
self.assertEqual("\n", out)
@@ -274,10 +277,11 @@ class TestDOM(TestCase):
self.assertIn("2015-09-04T00:00:00", out)
def test_dom_uda_date_year(self):
""" DOM 3.due.year """
"""DOM 3.due.year"""
code, out, err = self.t("_get 4.ticketdate.year")
self.assertEqual("2015\n", out)
class TestDOMSync(TestCase):
"""
This class verifies that the 'tw.syncneeded' DOM reference properly
@@ -288,14 +292,14 @@ class TestDOMSync(TestCase):
self.t = Task()
def test_dom_tw_syncneeded_false(self):
""" DOM tw.syncneeded --> false """
"""DOM tw.syncneeded --> false"""
code, out, err = self.t("_get tw.syncneeded")
self.assertEqual(code, 0)
self.assertIn("0", out)
self.assertNotIn("1k", out)
def test_dom_tw_syncneeded_true(self):
""" DOM tw.syncneeded --> true """
"""DOM tw.syncneeded --> true"""
self.t("add foo")
code, out, err = self.t("_get tw.syncneeded")
self.assertEqual(code, 0)
@@ -339,83 +343,83 @@ class TestDOMDirectReferencesOnAddition(TestCase):
cls.t("1 annotate Second annotation")
def test_dom_reference_due(self):
""" DOM reference on due in add command """
"""DOM reference on due in add command"""
self.t("add test_due due:1.due")
latest = self.t.latest
self.assertEqual("test_due", latest['description'])
self.assertEqual("20150901T080000Z", latest['due'])
self.assertEqual("test_due", latest["description"])
self.assertEqual("20150901T080000Z", latest["due"])
def test_dom_reference_project(self):
""" DOM reference on project in add command """
"""DOM reference on project in add command"""
self.t("add test_project project:1.project")
latest = self.t.latest
self.assertEqual("test_project", latest['description'])
self.assertEqual("baseproject", latest['project'])
self.assertEqual("test_project", latest["description"])
self.assertEqual("baseproject", latest["project"])
def test_dom_reference_tags_all(self):
""" DOM reference on tags in add command """
"""DOM reference on tags in add command"""
self.t("add test_tags_all tags:1.tags")
latest = self.t.latest
self.assertEqual("test_tags_all", latest['description'])
self.assertEqual(["tag1","tag2"], latest['tags'])
self.assertEqual("test_tags_all", latest["description"])
self.assertEqual(["tag1", "tag2"], latest["tags"])
def test_dom_reference_tags_single(self):
""" DOM reference on specific tag in add command """
"""DOM reference on specific tag in add command"""
self.t("add test_tags_single tags:1.tags.tag1")
latest = self.t.latest
self.assertEqual("test_tags_single", latest['description'])
self.assertEqual(["tag1"], latest['tags'])
self.assertEqual("test_tags_single", latest["description"])
self.assertEqual(["tag1"], latest["tags"])
def test_dom_reference_annotation(self):
""" DOM reference on annotation description in add command """
"""DOM reference on annotation description in add command"""
self.t("add description:1.annotations.2.description")
latest = self.t.latest
self.assertEqual("Second annotation", latest['description'])
self.assertEqual("Second annotation", latest["description"])
def test_dom_reference_numeric_uda(self):
""" DOM reference on numeric UDA in add command """
"""DOM reference on numeric UDA in add command"""
self.t("add test_numeric_uda ticketnum:1.ticketnum")
latest = self.t.latest
self.assertEqual("test_numeric_uda", latest['description'])
self.assertEqual(42, latest['ticketnum'])
self.assertEqual("test_numeric_uda", latest["description"])
self.assertEqual(42, latest["ticketnum"])
def test_dom_reference_date_uda(self):
""" DOM reference on date UDA in add command """
"""DOM reference on date UDA in add command"""
self.t("add test_date_uda ticketdate:1.ticketdate")
latest = self.t.latest
self.assertEqual("test_date_uda", latest['description'])
self.assertEqual("20150903T080000Z", latest['ticketdate'])
self.assertEqual("test_date_uda", latest["description"])
self.assertEqual("20150903T080000Z", latest["ticketdate"])
def test_dom_reference_string_uda(self):
""" DOM reference on string UDA in add command """
"""DOM reference on string UDA in add command"""
self.t("add test_string_uda ticketnote:1.ticketnote")
latest = self.t.latest
self.assertEqual("test_string_uda", latest['description'])
self.assertEqual("This is awesome", latest['ticketnote'])
self.assertEqual("test_string_uda", latest["description"])
self.assertEqual("This is awesome", latest["ticketnote"])
def test_dom_reference_string_value_uda(self):
""" DOM reference on string with limited values UDA in add command """
"""DOM reference on string with limited values UDA in add command"""
self.t("add test_string_value_uda ticketflag:1.ticketflag")
latest = self.t.latest
self.assertEqual("test_string_value_uda", latest['description'])
self.assertEqual("B", latest['ticketflag'])
self.assertEqual("test_string_value_uda", latest["description"])
self.assertEqual("B", latest["ticketflag"])
def test_dom_reference_duration_uda(self):
""" DOM reference on duration UDA in add command """
"""DOM reference on duration UDA in add command"""
self.t("add test_duration_uda ticketest:1.ticketest")
latest = self.t.latest
self.assertEqual("test_duration_uda", latest['description'])
self.assertEqual("PT1H", latest['ticketest'])
self.assertEqual("test_duration_uda", latest["description"])
self.assertEqual("PT1H", latest["ticketest"])
class TestDOMDirectReferencesFiltering(TestCase):
@@ -455,44 +459,44 @@ class TestDOMDirectReferencesFiltering(TestCase):
cls.t("add non matching task")
def test_dom_filter_reference_due(self):
""" DOM reference on due in filter """
"""DOM reference on due in filter"""
result = self.t.export_one("due:1.due")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_project(self):
""" DOM reference on project in filter """
"""DOM reference on project in filter"""
result = self.t.export_one("project:1.project")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_tags_all(self):
""" DOM reference on tags in filter """
"""DOM reference on tags in filter"""
result = self.t.export_one("tags:1.tags")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_numeric_uda(self):
""" DOM reference on numeric UDA in filter """
"""DOM reference on numeric UDA in filter"""
result = self.t.export_one("ticketnum:1.ticketnum")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_date_uda(self):
""" DOM reference on date UDA in filter """
"""DOM reference on date UDA in filter"""
result = self.t.export_one("ticketdate:1.ticketdate")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_string_uda(self):
""" DOM reference on string UDA in filter """
"""DOM reference on string UDA in filter"""
result = self.t.export_one("ticketnote:1.ticketnote")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_string_value_uda(self):
""" DOM reference on string with limited values UDA in filter """
"""DOM reference on string with limited values UDA in filter"""
result = self.t.export_one("ticketflag:1.ticketflag")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
def test_dom_filter_reference_duration_uda(self):
""" DOM reference on duration UDA in filter """
"""DOM reference on duration UDA in filter"""
result = self.t.export_one("ticketest:1.ticketest")
self.assertEqual("matching task", result['description'])
self.assertEqual("matching task", result["description"])
class TestBug1300(TestCase):
@@ -501,18 +505,17 @@ class TestBug1300(TestCase):
cls.t = Task()
def test_dom_exit_status_good(self):
"""1300: If the DOM recognizes a reference, it should return '0'
"""
"""1300: If the DOM recognizes a reference, it should return '0'"""
self.t("_get context.program")
def test_dom_exit_status_bad(self):
"""1300: If the DOM does not recognize a reference, it should return '1'
"""
"""1300: If the DOM does not recognize a reference, it should return '1'"""
self.t.runError("_get XYZ")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
from datetime import datetime, timedelta
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -138,6 +139,7 @@ class TestBug2519(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -64,7 +65,10 @@ class TestDuplication(TestCase):
def test_duplication_showing_uuid(self):
"""Verify duplicate can show uuid"""
code, out, err = self.t("1 duplicate rc.verbose:new-uuid")
self.assertRegex(out, "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}")
self.assertRegex(
out,
"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
)
class TestDuplication2(TestCase):
@@ -75,7 +79,7 @@ class TestDuplication2(TestCase):
def test_duplication_recurrence(self):
"""Verify that recurring tasks are properly duplicated"""
self.t("add R due:tomorrow recur:weekly")
self.t("list") # To force handleRecurrence().
self.t("list") # To force handleRecurrence().
code, out, err = self.t("1 duplicate")
self.assertIn("The duplicated task is too", out)
@@ -83,7 +87,7 @@ class TestDuplication2(TestCase):
code, out, err = self.t("2 duplicate")
self.assertIn("The duplicated task is not", out)
self.t("list") # To force handleRecurrence().
self.t("list") # To force handleRecurrence().
code, out, err = self.t("1 export")
self.assertIn('"status":"recurring"', out)
@@ -105,6 +109,7 @@ class TestDuplication2(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -86,7 +87,9 @@ class TestTaskEdit(TestCase):
self.t.config("uda.uorphan.type", "string")
self.t.config("uda.uorphan.label", "uorphan")
self.t("add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy udate:now uduration:1day ustring:Hi unumeric:42 uorphan:Annie")
self.t(
"add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy udate:now uduration:1day ustring:Hi unumeric:42 uorphan:Annie"
)
self.t("1 annotate bar", input="n\n")
# Make the orphan.
@@ -99,6 +102,7 @@ class TestTaskEdit(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import re
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -77,6 +78,7 @@ class TestUtf8(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -54,19 +55,23 @@ class TestEnpassantMultiple(BaseTestEnpassant):
code, out, err = self.t((id, "info"))
self.assertRegex(
out, "Status +Completed",
out,
"Status +Completed",
msg="enpassant {0} status change".format(id),
)
self.assertRegex(
out, "Priority +H",
out,
"Priority +H",
msg="enpassant {0} priority change".format(id),
)
self.assertRegex(
out, "Tags +tag",
out,
"Tags +tag",
msg="enpassant {0} tag change".format(id),
)
self.assertRegex(
out, "Description +{0}".format(desc),
out,
"Description +{0}".format(desc),
msg="enpassant {0} description change".format(id),
)
@@ -94,28 +99,33 @@ class TestEnpassant(BaseTestEnpassant):
def perform_action(self, action):
self.t(("1", action, "oneanno"))
code, out, err = self.t("1 info")
self.assertRegex(out, "Description +one\n[0-9: -]+ oneanno",
msg="{0} enpassant annotation".format(action))
self.assertRegex(
out,
"Description +one\n[0-9: -]+ oneanno",
msg="{0} enpassant annotation".format(action),
)
self.t(("2", action, "/two/TWO/"))
code, out, err = self.t("2 info")
self.assertRegex(out, "Description +TWO",
msg="{0} enpassant modify".format(action))
self.assertRegex(
out, "Description +TWO", msg="{0} enpassant modify".format(action)
)
self.t(("3", action, "+threetag"))
code, out, err = self.t("3 info")
self.assertRegex(out, "Tags +threetag",
msg="{0} enpassant tag".format(action))
self.assertRegex(out, "Tags +threetag", msg="{0} enpassant tag".format(action))
self.t(("4", action, "pri:H"))
code, out, err = self.t("4 info")
self.assertRegex(out, "Priority +H",
msg="{0} enpassant priority".format(action))
self.assertRegex(
out, "Priority +H", msg="{0} enpassant priority".format(action)
)
self.t(("5", action, "pro:PROJ"))
code, out, err = self.t("5 info")
self.assertRegex(out, "Project +PROJ",
msg="{0} enpassant project".format(action))
self.assertRegex(
out, "Project +PROJ", msg="{0} enpassant project".format(action)
)
def test_done(self):
"""Test 'done' with en-passant changes"""
@@ -138,6 +148,7 @@ class TestEnpassant(BaseTestEnpassant):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -27,16 +27,15 @@
#include <cmake.h>
// cmake.h include header must come first
#include <test.h>
#include <Context.h>
#include <Eval.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
// A few hard-coded symbols.
bool get (const std::string& name, Variant& value)
{
bool get(const std::string& name, Variant& value) {
if (name == "x")
value = Variant (true);
value = Variant(true);
else
return false;
@@ -44,126 +43,125 @@ bool get (const std::string& name, Variant& value)
}
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest t (52);
int main(int, char**) {
UnitTest t(52);
Context context;
Context::setContext(&context);
// Test the source independently.
Variant v;
t.notok (get ("-", v), "true <-- get(-)");
t.notok(get("-", v), "true <-- get(-)");
t.ok (get ("x", v), "true <-- get(x)");
t.is (v.type (), Variant::type_boolean, "get(x) --> boolean");
t.is (v.get_bool (), true, "get(x) --> true");
t.ok(get("x", v), "true <-- get(x)");
t.is(v.type(), Variant::type_boolean, "get(x) --> boolean");
t.is(v.get_bool(), true, "get(x) --> true");
Eval e;
e.addSource (get);
e.addSource(get);
Variant result;
e.evaluatePostfixExpression ("x", result);
t.is (result.type (), Variant::type_boolean, "postfix 'x' --> boolean");
t.is (result.get_bool (), true, "postfix 'x' --> true");
e.evaluatePostfixExpression("x", result);
t.is(result.type(), Variant::type_boolean, "postfix 'x' --> boolean");
t.is(result.get_bool(), true, "postfix 'x' --> true");
e.evaluatePostfixExpression ("pi", result);
t.is (result.type (), Variant::type_real, "postfix 'pi' --> real");
t.is (result.get_real (), 3.141592, 0.00001, "postfix 'pi' --> 3.14159265");
e.evaluatePostfixExpression("pi", result);
t.is(result.type(), Variant::type_real, "postfix 'pi' --> real");
t.is(result.get_real(), 3.141592, 0.00001, "postfix 'pi' --> 3.14159265");
e.evaluatePostfixExpression ("foo", result);
t.is (result.type (), Variant::type_string, "postfix 'foo' --> string");
t.is (result.get_string (), "foo", "postfix 'foo' --> 'foo'");
e.evaluatePostfixExpression("foo", result);
t.is(result.type(), Variant::type_string, "postfix 'foo' --> string");
t.is(result.get_string(), "foo", "postfix 'foo' --> 'foo'");
// Simple infix arithmetic.
e.evaluateInfixExpression ("1+2", result);
t.is (result.type (), Variant::type_integer, "infix '1 + 2' --> integer");
t.is (result.get_integer (), 3, "infix '1 + 2' --> 3");
e.evaluateInfixExpression("1+2", result);
t.is(result.type(), Variant::type_integer, "infix '1 + 2' --> integer");
t.is(result.get_integer(), 3, "infix '1 + 2' --> 3");
// Simple postfix arithmetic.
e.evaluatePostfixExpression ("1 2 +", result);
t.is (result.type (), Variant::type_integer, "postfix '1 2 +' --> integer");
t.is (result.get_integer (), 3, "postfix '1 2 +' --> 3");
e.evaluatePostfixExpression("1 2 +", result);
t.is(result.type(), Variant::type_integer, "postfix '1 2 +' --> integer");
t.is(result.get_integer(), 3, "postfix '1 2 +' --> 3");
e.evaluatePostfixExpression ("1 2 -", result);
t.is (result.type (), Variant::type_integer, "postfix '1 2 -' --> integer");
t.is (result.get_integer (), -1, "postfix '1 2 -' --> -1");
e.evaluatePostfixExpression("1 2 -", result);
t.is(result.type(), Variant::type_integer, "postfix '1 2 -' --> integer");
t.is(result.get_integer(), -1, "postfix '1 2 -' --> -1");
e.evaluatePostfixExpression ("2 3 *", result);
t.is (result.type (), Variant::type_integer, "postfix '2 3 *' --> integer");
t.is (result.get_integer (), 6, "postfix '2 3 *' --> 6");
e.evaluatePostfixExpression("2 3 *", result);
t.is(result.type(), Variant::type_integer, "postfix '2 3 *' --> integer");
t.is(result.get_integer(), 6, "postfix '2 3 *' --> 6");
e.evaluatePostfixExpression ("5 2 /", result);
t.is (result.type (), Variant::type_integer, "postfix '5 2 /' --> integer");
t.is (result.get_integer (), 2, "postfix '5 2 /' --> 2");
e.evaluatePostfixExpression("5 2 /", result);
t.is(result.type(), Variant::type_integer, "postfix '5 2 /' --> integer");
t.is(result.get_integer(), 2, "postfix '5 2 /' --> 2");
e.evaluatePostfixExpression ("5 2 /", result);
t.is (result.type (), Variant::type_integer, "postfix '5 2 *' --> integer");
t.is (result.get_integer (), 2, "postfix '5 2 *' --> 2");
e.evaluatePostfixExpression("5 2 /", result);
t.is(result.type(), Variant::type_integer, "postfix '5 2 *' --> integer");
t.is(result.get_integer(), 2, "postfix '5 2 *' --> 2");
// Simple postfix unary operator.
e.evaluatePostfixExpression ("0 !", result);
t.is (result.type (), Variant::type_boolean, "postfix '0 !' --> boolean");
t.is (result.get_bool (), true, "postfix '0 !' --> true");
e.evaluatePostfixExpression("0 !", result);
t.is(result.type(), Variant::type_boolean, "postfix '0 !' --> boolean");
t.is(result.get_bool(), true, "postfix '0 !' --> true");
e.evaluatePostfixExpression ("1 !", result);
t.is (result.type (), Variant::type_boolean, "postfix '1 !' --> boolean");
t.is (result.get_bool (), false, "postfix '1 !' --> false");
e.evaluatePostfixExpression("1 !", result);
t.is(result.type(), Variant::type_boolean, "postfix '1 !' --> boolean");
t.is(result.get_bool(), false, "postfix '1 !' --> false");
// Type promotion simple postfix arithmetic.
e.evaluatePostfixExpression ("1 2.3 +", result);
t.is (result.type (), Variant::type_real, "postfix '1 2.3 +' --> real");
t.is (result.get_real (), 3.3, "postfix '1 2.3 +' --> 3.3");
e.evaluatePostfixExpression("1 2.3 +", result);
t.is(result.type(), Variant::type_real, "postfix '1 2.3 +' --> real");
t.is(result.get_real(), 3.3, "postfix '1 2.3 +' --> 3.3");
e.evaluatePostfixExpression ("5 2.0 /", result);
t.is (result.type (), Variant::type_real, "postfix '5 2.0 /' --> integer");
t.is (result.get_real (), 2.5, "postfix '5 2.0 /' --> 2.5");
e.evaluatePostfixExpression("5 2.0 /", result);
t.is(result.type(), Variant::type_real, "postfix '5 2.0 /' --> integer");
t.is(result.get_real(), 2.5, "postfix '5 2.0 /' --> 2.5");
// Simple logic.
e.evaluatePostfixExpression ("0 0 ||", result);
t.is (result.type (), Variant::type_boolean, "postfix '0 0 ||' --> boolean");
t.is (result.get_bool (), false, "postfix '0 0 ||' --> false");
e.evaluatePostfixExpression("0 0 ||", result);
t.is(result.type(), Variant::type_boolean, "postfix '0 0 ||' --> boolean");
t.is(result.get_bool(), false, "postfix '0 0 ||' --> false");
e.evaluatePostfixExpression ("0 1 ||", result);
t.is (result.type (), Variant::type_boolean, "postfix '0 1 ||' --> boolean");
t.is (result.get_bool (), true, "postfix '0 1 ||' --> true");
e.evaluatePostfixExpression("0 1 ||", result);
t.is(result.type(), Variant::type_boolean, "postfix '0 1 ||' --> boolean");
t.is(result.get_bool(), true, "postfix '0 1 ||' --> true");
e.evaluatePostfixExpression ("1 0 ||", result);
t.is (result.type (), Variant::type_boolean, "postfix '1 0 ||' --> boolean");
t.is (result.get_bool (), true, "postfix '1 0 ||' --> true");
e.evaluatePostfixExpression("1 0 ||", result);
t.is(result.type(), Variant::type_boolean, "postfix '1 0 ||' --> boolean");
t.is(result.get_bool(), true, "postfix '1 0 ||' --> true");
e.evaluatePostfixExpression ("1 1 ||", result);
t.is (result.type (), Variant::type_boolean, "postfix '1 1 ||' --> boolean");
t.is (result.get_bool (), true, "postfix '1 1 ||' --> true");
e.evaluatePostfixExpression("1 1 ||", result);
t.is(result.type(), Variant::type_boolean, "postfix '1 1 ||' --> boolean");
t.is(result.get_bool(), true, "postfix '1 1 ||' --> true");
e.evaluateInfixExpression ("2*3+1", result);
t.is (result.type (), Variant::type_integer, "infix '2*3+1' --> integer");
t.is (result.get_integer (), 7, "infix '2*3+1' --> 7");
e.evaluateInfixExpression("2*3+1", result);
t.is(result.type(), Variant::type_integer, "infix '2*3+1' --> integer");
t.is(result.get_integer(), 7, "infix '2*3+1' --> 7");
// TW-1254 - Unary minus support.
e.evaluateInfixExpression ("2- -3", result);
t.is (result.type (), Variant::type_integer, "infix '2- -3' --> integer");
t.is (result.get_integer (), 5, "infix '2- -3' --> 5");
e.evaluateInfixExpression("2- -3", result);
t.is(result.type(), Variant::type_integer, "infix '2- -3' --> integer");
t.is(result.get_integer(), 5, "infix '2- -3' --> 5");
//e.debug ();
e.evaluateInfixExpression ("!false", result);
t.is (result.type (), Variant::type_boolean, "infix '!false' --> boolean");
t.is (result.get_bool (), true, "infix '!false' --> true");
// e.debug ();
e.evaluateInfixExpression("!false", result);
t.is(result.type(), Variant::type_boolean, "infix '!false' --> boolean");
t.is(result.get_bool(), true, "infix '!false' --> true");
e.evaluateInfixExpression ("!true", result);
t.is (result.type (), Variant::type_boolean, "infix '!true' --> boolean");
t.is (result.get_bool (), false, "infix '!true' --> false");
e.evaluateInfixExpression("!true", result);
t.is(result.type(), Variant::type_boolean, "infix '!true' --> boolean");
t.is(result.get_bool(), false, "infix '!true' --> false");
// _neg_
e.evaluateInfixExpression ("- 1", result);
t.is (result.type (), Variant::type_integer, "infix '- 1' --> integer");
t.is (result.get_integer (), -1, "infix '- 1' --> -1");
e.evaluateInfixExpression("- 1", result);
t.is(result.type(), Variant::type_integer, "infix '- 1' --> integer");
t.is(result.get_integer(), -1, "infix '- 1' --> -1");
e.evaluateInfixExpression ("- 1.2", result);
t.is (result.type (), Variant::type_real, "infix '- 1.2' --> real");
t.is (result.get_real (), -1.2, "infix '- 1.2' --> -1.2");
e.evaluateInfixExpression("- 1.2", result);
t.is(result.type(), Variant::type_real, "infix '- 1.2' --> real");
t.is(result.get_real(), -1.2, "infix '- 1.2' --> -1.2");
e.evaluateInfixExpression ("- 2days", result);
t.is (result.type (), Variant::type_duration, "infix '- 2days' --> duration");
t.is (result.get_duration (), -86400*2, "infix '- 2days' --> -86400 * 2");
e.evaluateInfixExpression("- 2days", result);
t.is(result.type(), Variant::type_duration, "infix '- 2days' --> duration");
t.is(result.get_duration(), -86400 * 2, "infix '- 2days' --> -86400 * 2");
return 0;
}

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
@@ -63,8 +64,10 @@ class TestBug1414(TestCase):
code, out, err = self.t()
self.assertIn("hello", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -45,7 +45,7 @@ DATETIME_FORMAT = "%Y%m%dT%H%M%SZ"
class TestExportCommand(TestCase):
def setUp(self):
self.t = Task()
self.t('add test')
self.t("add test")
def export(self, id):
code, out, err = self.t(("{0}".format(id), "rc.json.array=off", "export"))
@@ -91,62 +91,62 @@ class TestExportCommand(TestCase):
self.assertEqual(value, expected_value)
def test_export_status(self):
self.assertString(self.export(1)['status'], "pending")
self.assertString(self.export(1)["status"], "pending")
def test_export_uuid(self):
self.assertString(self.export(1)['uuid'], UUID_REGEXP, regexp=True)
self.assertString(self.export(1)["uuid"], UUID_REGEXP, regexp=True)
def test_export_entry(self):
self.assertTimestamp(self.export(1)['entry'])
self.assertTimestamp(self.export(1)["entry"])
def test_export_description(self):
self.assertString(self.export(1)['description'], "test")
self.assertString(self.export(1)["description"], "test")
def test_export_start(self):
self.t('1 start')
self.assertTimestamp(self.export(1)['start'])
self.t("1 start")
self.assertTimestamp(self.export(1)["start"])
def test_export_end(self):
self.t('1 start')
self.t("1 start")
self.t.faketime("+5s")
# After a task is "done" or "deleted", it does not have an ID by which
# to filter it anymore. Add a tag to work around this.
self.t('1 done +workaround')
self.assertTimestamp(self.export('+workaround')['end'])
self.t("1 done +workaround")
self.assertTimestamp(self.export("+workaround")["end"])
def test_export_due(self):
self.t('1 modify due:today')
self.assertTimestamp(self.export(1)['due'])
self.t("1 modify due:today")
self.assertTimestamp(self.export(1)["due"])
def test_export_wait(self):
self.t('1 modify wait:tomorrow')
self.assertTimestamp(self.export(1)['wait'])
self.t("1 modify wait:tomorrow")
self.assertTimestamp(self.export(1)["wait"])
def test_export_modified(self):
self.assertTimestamp(self.export(1)['modified'])
self.assertTimestamp(self.export(1)["modified"])
def test_export_scheduled(self):
self.t('1 modify schedule:tomorrow')
self.assertTimestamp(self.export(1)['scheduled'])
self.t("1 modify schedule:tomorrow")
self.assertTimestamp(self.export(1)["scheduled"])
def test_export_recur(self):
self.t('1 modify recur:daily due:today')
self.assertString(self.export(1)['recur'], "daily")
self.t("1 modify recur:daily due:today")
self.assertString(self.export(1)["recur"], "daily")
def test_export_project(self):
self.t('1 modify project:Home')
self.assertString(self.export(1)['project'], "Home")
self.t("1 modify project:Home")
self.assertString(self.export(1)["project"], "Home")
def test_export_priority(self):
self.t('1 modify priority:H')
self.assertString(self.export(1)['priority'], "H")
self.t("1 modify priority:H")
self.assertString(self.export(1)["priority"], "H")
def test_export_depends(self):
self.t(('add', 'everything depends on me task'))
self.t(('add', 'wrong, everything depends on me task'))
self.t('1 modify depends:2,3')
self.t(("add", "everything depends on me task"))
self.t(("add", "wrong, everything depends on me task"))
self.t("1 modify depends:2,3")
deps = self.export(1)['depends']
deps = self.export(1)["depends"]
self.assertType(deps, list)
self.assertEqual(len(deps), 2)
@@ -154,30 +154,30 @@ class TestExportCommand(TestCase):
self.assertString(uuid, UUID_REGEXP, regexp=True)
def test_export_urgency(self):
self.t('add urgent task +urgent')
self.t("add urgent task +urgent")
# Urgency can be either integer or float
self.assertNumeric(self.export(1)['urgency'])
self.assertNumeric(self.export(1)["urgency"])
def test_export_numeric_uda(self):
self.t.config('uda.estimate.type', 'numeric')
self.t('add estimate:42 test numeric uda')
self.assertNumeric(self.export('2')['estimate'], 42)
self.t.config("uda.estimate.type", "numeric")
self.t("add estimate:42 test numeric uda")
self.assertNumeric(self.export("2")["estimate"], 42)
def test_export_string_uda(self):
self.t.config('uda.estimate.type', 'string')
self.t('add estimate:big test string uda')
self.assertString(self.export('2')['estimate'], 'big')
self.t.config("uda.estimate.type", "string")
self.t("add estimate:big test string uda")
self.assertString(self.export("2")["estimate"], "big")
def test_export_datetime_uda(self):
self.t.config('uda.estimate.type', 'date')
self.t('add estimate:eom test date uda')
self.assertTimestamp(self.export('2')['estimate'])
self.t.config("uda.estimate.type", "date")
self.t("add estimate:eom test date uda")
self.assertTimestamp(self.export("2")["estimate"])
def test_export_duration_uda(self):
self.t.config('uda.estimate.type', 'duration')
self.t('add estimate:month test duration uda')
self.assertString(self.export('2')['estimate'], 'P30D')
self.t.config("uda.estimate.type", "duration")
self.t("add estimate:month test duration uda")
self.assertString(self.export("2")["estimate"], "P30D")
class TestExportCommandLimit(TestCase):
@@ -186,8 +186,8 @@ class TestExportCommandLimit(TestCase):
def test_export_obeys_limit(self):
"""Verify that 'task export limit:1' is obeyed"""
self.t('add one')
self.t('add two')
self.t("add one")
self.t("add two")
code, out, err = self.t("/o/ limit:1 export")
self.assertIn("one", out)
@@ -196,6 +196,7 @@ class TestExportCommandLimit(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import re
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -67,11 +68,14 @@ class TestFeature559(TestCase):
code, out, err = self.t.runError("rc.data.location=locationdoesnotexist list")
self.assertNotIn("footask", out)
self.assertNotIn("Error", out)
self.assertRegex(err, re.compile("Could not.+unable to open database file", re.DOTALL))
self.assertRegex(
err, re.compile("Could not.+unable to open database file", re.DOTALL)
)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -35,8 +36,8 @@ from basetest import Task, TestCase
class TestDefaultProject(TestCase):
"""Bug 1023: rc.default.project gets applied during modify, and should not
"""
"""Bug 1023: rc.default.project gets applied during modify, and should not"""
def setUp(self):
self.t = Task()
@@ -45,8 +46,7 @@ class TestDefaultProject(TestCase):
self.t.config("default.project", self.default_project)
def test_with_project(self):
"""default.project not applied when specified nor on attribute removal
"""
"""default.project not applied when specified nor on attribute removal"""
self.set_default_project()
self.t("add foobar project:garden")
@@ -152,7 +152,7 @@ class TestDefaultProject(TestCase):
self.set_default_project()
DESC = "foobar"
self.t(('add', 'recur:daily', 'due:today', DESC))
self.t(("add", "recur:daily", "due:today", DESC))
self.t() # Ensure creation of recurring children
code, out, err = self.t("1 info")
@@ -172,8 +172,10 @@ class TestDefaultProject(TestCase):
try:
id = int(id)
except ValueError:
raise ValueError("Unexpected output when running 'task count', "
"expected int, got '{0}'".format(id))
raise ValueError(
"Unexpected output when running 'task count', "
"expected int, got '{0}'".format(id)
)
else:
# parent task is not considered when counting
id = str(id + 1)
@@ -188,7 +190,7 @@ class TestDefaultProject(TestCase):
"""no project is applied on recurring tasks"""
# NOTE - reported on TW-1279
DESC = "foobar"
self.t(('add', 'recur:daily', 'due:today', DESC))
self.t(("add", "recur:daily", "due:today", DESC))
code, out, err = self.t()
self.assertIn(DESC, out)
@@ -204,13 +206,12 @@ class TestDefaultProject(TestCase):
self.assertNotIn("Project", out)
def test_recurring_with_project_and_default_project(self):
"""default.project is not applied to children if parent has a project
"""
"""default.project is not applied to children if parent has a project"""
# NOTE - reported on TW-1279
self.set_default_project()
DESC = "foobar"
self.t(('add', 'recur:daily', 'due:today', 'project:HELLO', DESC))
self.t(("add", "recur:daily", "due:today", "project:HELLO", DESC))
code, out, err = self.t()
self.assertIn(DESC, out)
@@ -227,6 +228,7 @@ class TestDefaultProject(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -39,7 +40,6 @@ class TestPrintEmptyColumns(TestCase):
"""Executed before each test in the class"""
self.t = Task()
def test_empty_columns_feature(self):
"""Verify rc.print.empty.columns:yes shows more nothing than rc.print.empty.columns:no"""
self.t("add one")
@@ -64,6 +64,7 @@ class TestPrintEmptyColumns(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
@@ -67,6 +68,7 @@ class TestRecurrenceProblems(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -69,6 +70,7 @@ class TestFeature1013(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import datetime
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -353,7 +354,7 @@ class TestFilterDue(TestCase):
def setUp(self):
self.t = Task()
self.t.config("due", "4")
self.t.config("due", "4")
self.t.config("dateformat", "m/d/Y")
just = datetime.datetime.now() + datetime.timedelta(days=3)
@@ -441,7 +442,9 @@ class TestEmptyFilter(TestCase):
self.t("add foo")
self.t("add bar")
code, out, err = self.t.runError("modify rc.allow.empty.filter=yes rc.confirmation=no priority:H")
code, out, err = self.t.runError(
"modify rc.allow.empty.filter=yes rc.confirmation=no priority:H"
)
self.assertIn("Command prevented from running.", err)
def test_empty_filter_error(self):
@@ -451,7 +454,10 @@ class TestEmptyFilter(TestCase):
self.t("add bar")
code, out, err = self.t.runError("modify rc.allow.empty.filter=no priority:H")
self.assertIn("You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken.", err)
self.assertIn(
"You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken.",
err,
)
class TestFilterPrefix(TestCase):
@@ -461,86 +467,86 @@ class TestFilterPrefix(TestCase):
cls.t = Task()
cls.t.config("verbose", "nothing")
cls.t('add project:foo.uno priority:H +tag "one foo"' )
cls.t('add project:foo.dos priority:H "two"' )
cls.t('add project:foo.tres "three"' )
cls.t('add project:bar.uno priority:H "four"' )
cls.t('add project:bar.dos +tag "five"' )
cls.t('add project:bar.tres "six foo"' )
cls.t('add project:foo.uno priority:H +tag "one foo"')
cls.t('add project:foo.dos priority:H "two"')
cls.t('add project:foo.tres "three"')
cls.t('add project:bar.uno priority:H "four"')
cls.t('add project:bar.dos +tag "five"')
cls.t('add project:bar.tres "six foo"')
cls.t('add project:bazuno "seven bar foo"')
cls.t('add project:bazdos "eight bar foo"')
def test_list_all(self):
"""No filter shows all tasks."""
code, out, err = self.t('list')
self.assertIn('one', out)
self.assertIn('two', out)
self.assertIn('three', out)
self.assertIn('four', out)
self.assertIn('five', out)
self.assertIn('six', out)
self.assertIn('seven', out)
self.assertIn('eight', out)
code, out, err = self.t("list")
self.assertIn("one", out)
self.assertIn("two", out)
self.assertIn("three", out)
self.assertIn("four", out)
self.assertIn("five", out)
self.assertIn("six", out)
self.assertIn("seven", out)
self.assertIn("eight", out)
def test_list_project_foo(self):
"""Filter on project name."""
code, out, err = self.t('list project:foo')
self.assertIn('one', out)
self.assertIn('two', out)
self.assertIn('three', out)
self.assertNotIn('four', out)
self.assertNotIn('five', out)
self.assertNotIn('six', out)
self.assertNotIn('seven', out)
self.assertNotIn('eight', out)
code, out, err = self.t("list project:foo")
self.assertIn("one", out)
self.assertIn("two", out)
self.assertIn("three", out)
self.assertNotIn("four", out)
self.assertNotIn("five", out)
self.assertNotIn("six", out)
self.assertNotIn("seven", out)
self.assertNotIn("eight", out)
def test_list_project_not_foo(self):
"""Filter on not project name."""
code, out, err = self.t('list project.not:foo')
self.assertNotIn('one', out)
self.assertNotIn('two', out)
self.assertNotIn('three', out)
self.assertIn('four', out)
self.assertIn('five', out)
self.assertIn('six', out)
self.assertIn('seven', out)
self.assertIn('eight', out)
code, out, err = self.t("list project.not:foo")
self.assertNotIn("one", out)
self.assertNotIn("two", out)
self.assertNotIn("three", out)
self.assertIn("four", out)
self.assertIn("five", out)
self.assertIn("six", out)
self.assertIn("seven", out)
self.assertIn("eight", out)
def test_list_project_startswith_bar(self):
"""Filter on project name start."""
code, out, err = self.t('list project.startswith:bar')
self.assertNotIn('one', out)
self.assertNotIn('two', out)
self.assertNotIn('three', out)
self.assertIn('four', out)
self.assertIn('five', out)
self.assertIn('six', out)
self.assertNotIn('seven', out)
self.assertNotIn('eight', out)
code, out, err = self.t("list project.startswith:bar")
self.assertNotIn("one", out)
self.assertNotIn("two", out)
self.assertNotIn("three", out)
self.assertIn("four", out)
self.assertIn("five", out)
self.assertIn("six", out)
self.assertNotIn("seven", out)
self.assertNotIn("eight", out)
def test_list_project_ba(self):
"""Filter on project partial match."""
code, out, err = self.t('list project:ba')
self.assertNotIn('one', out)
self.assertNotIn('two', out)
self.assertNotIn('three', out)
self.assertIn('four', out)
self.assertIn('five', out)
self.assertIn('six', out)
self.assertIn('seven', out)
self.assertIn('eight', out)
code, out, err = self.t("list project:ba")
self.assertNotIn("one", out)
self.assertNotIn("two", out)
self.assertNotIn("three", out)
self.assertIn("four", out)
self.assertIn("five", out)
self.assertIn("six", out)
self.assertIn("seven", out)
self.assertIn("eight", out)
def test_list_description_has_foo(self):
"""Filter on description pattern."""
code, out, err = self.t('list description.has:foo')
self.assertIn('one', out)
self.assertNotIn('two', out)
self.assertNotIn('three', out)
self.assertNotIn('four', out)
self.assertNotIn('five', out)
self.assertIn('six', out)
self.assertIn('seven', out)
self.assertIn('eight', out)
code, out, err = self.t("list description.has:foo")
self.assertIn("one", out)
self.assertNotIn("two", out)
self.assertNotIn("three", out)
self.assertNotIn("four", out)
self.assertNotIn("five", out)
self.assertIn("six", out)
self.assertIn("seven", out)
self.assertIn("eight", out)
class TestBug480B(TestCase):
@@ -675,7 +681,7 @@ class TestBug1600(TestCase):
self.assertNotIn("foobar2", out)
def test_filter_question_in_descriptions(self):
"""filter - description contains ? """
"""filter - description contains ?"""
self.t("add foobar1")
self.t("add foo?bar")
@@ -688,7 +694,7 @@ class TestBug1600(TestCase):
self.assertNotIn("foobar1", out)
def test_filter_brackets_in_descriptions(self):
"""filter - description contains [] """
"""filter - description contains []"""
self.t("add [foobar1]")
self.t("add [foobar2]")
@@ -707,9 +713,9 @@ class TestBug1656(TestCase):
def test_report_filter_parenthesized(self):
"""default report filter parenthesized"""
self.t('add task1 +work')
self.t('add task2 +work')
self.t('1 done')
self.t("add task1 +work")
self.t("add task2 +work")
self.t("1 done")
# Sanity check, next does not display completed tasks
code, out, err = self.t("next")
@@ -747,19 +753,19 @@ class TestHasHasnt(TestCase):
def test_has_hasnt(self):
"""Verify the 'has' and 'hasnt' attribute modifiers"""
self.t("add foo") # 1
self.t("add foo") # 2
self.t("add foo") # 1
self.t("add foo") # 2
self.t("2 annotate bar")
self.t("add foo") # 3
self.t("add foo") # 3
self.t("3 annotate bar")
self.t("3 annotate baz")
self.t("add bar") # 4
self.t("add bar") # 5
self.t("add bar") # 4
self.t("add bar") # 5
self.t("5 annotate foo")
self.t("add bar") # 6
self.t("add bar") # 6
self.t("6 annotate foo")
self.t("6 annotate baz")
self.t("add one") # 7
self.t("add one") # 7
self.t("7 annotate two")
self.t("7 annotate three")
@@ -787,8 +793,8 @@ class TestBefore(TestCase):
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t('add foo entry:2008-12-22 start:2008-12-22')
cls.t('add bar entry:2009-04-17 start:2009-04-17')
cls.t("add foo entry:2008-12-22 start:2008-12-22")
cls.t("add bar entry:2009-04-17 start:2009-04-17")
def test_correctly_recorded_start(self):
"""Verify start dates properly recorded"""
@@ -840,14 +846,14 @@ class TestBy(TestCase):
self.t = Task()
def test_by_eoy_includes_eoy(self):
""" Verify by-end-of-year includes task due *at* end-of-year """
"""Verify by-end-of-year includes task due *at* end-of-year"""
self.t("add zero due:eoy")
code, out, err = self.t("due.by:eoy")
self.assertIn("zero", out)
def test_by_tomorrow_includes_tomorrow(self):
""" Verify that by-tomorrow also includes tomorrow itself """
"""Verify that by-tomorrow also includes tomorrow itself"""
self.t.faketime("2021-07-16 21:00:00")
self.t("add zero due:2021-07-17")
@@ -855,7 +861,7 @@ class TestBy(TestCase):
self.assertIn("zero", out)
def test_by_yesterday_does_not_include_today(self):
""" Verify that by-yesterday does not include today """
"""Verify that by-yesterday does not include today"""
self.t("add zero")
code, out, err = self.t.runError("entry.by:yesterday")
@@ -869,8 +875,8 @@ class Test1424(TestCase):
def test_1824_days(self):
"""1424: Check that due:1824d works"""
self.t('add foo due:1824d')
code, out, err = self.t('_get 1.due.year')
self.t("add foo due:1824d")
code, out, err = self.t("_get 1.due.year")
# NOTE This test has a possible race condition when run "during" EOY.
# If Taskwarrior is executed at 23:59:59 on new year's eve and the
# python code below runs at 00:00:00 on new year's day, the two will
@@ -881,8 +887,8 @@ class Test1424(TestCase):
def test_3648_days(self):
"""1424: Check that due:3648d works"""
self.t('add foo due:3648d')
code, out, err = self.t('_get 1.due.year')
self.t("add foo due:3648d")
code, out, err = self.t("_get 1.due.year")
# NOTE This test has a possible race condition when run "during" EOY.
# If Taskwarrior is executed at 23:59:59 on new year's eve and the
# python code below runs at 00:00:00 on new year's day, the two will
@@ -897,22 +903,22 @@ class Test1424(TestCase):
class Test1452(TestCase):
def setUp(self):
self.t = Task()
self.t('add task')
self.task_uuid = self.t.export_one()['uuid']
self.t("add task")
self.task_uuid = self.t.export_one()["uuid"]
def test_get_task_by_uuid_with_prefix(self):
"""1452: Tries to filter task simply by its uuid, using uuid: prefix."""
output = self.t.export_one('uuid:%s' % self.task_uuid)
output = self.t.export_one("uuid:%s" % self.task_uuid)
# Sanity check it is the correct one
self.assertEqual(output['uuid'], self.task_uuid)
self.assertEqual(output["uuid"], self.task_uuid)
def test_get_task_by_uuid_without_prefix(self):
"""1452: Tries to filter task simply by its uuid, without using uuid: prefix."""
output = self.t.export_one(self.task_uuid)
# Sanity check it is the correct one
self.assertEqual(output['uuid'], self.task_uuid)
self.assertEqual(output["uuid"], self.task_uuid)
class TestBug1456(TestCase):
@@ -935,22 +941,22 @@ class TestBug1456(TestCase):
class Test1468(TestCase):
def setUp(self):
self.t = Task()
self.t('add project:home buy milk')
self.t('add project:home mow the lawn')
self.t("add project:home buy milk")
self.t("add project:home mow the lawn")
def test_single_attribute_filter(self):
"""1468: Single attribute filter (project:home)"""
code, out, err = self.t('list project:home')
code, out, err = self.t("list project:home")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('buy milk', out)
self.assertIn('mow the lawn', out)
self.assertIn("buy milk", out)
self.assertIn("mow the lawn", out)
def test_attribute_and_search_filter(self):
"""1468: Attribute and implicit search filter (project:home /lawn/)"""
code, out, err = self.t('list project:home /lawn/')
code, out, err = self.t("list project:home /lawn/")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertNotIn('buy milk', out)
self.assertIn('mow the lawn', out)
self.assertNotIn("buy milk", out)
self.assertIn("mow the lawn", out)
class TestBug1521(TestCase):
@@ -1021,19 +1027,19 @@ class Test1634(TestCase):
self.t = Task()
# Setup some tasks due on 2015-07-07
self.t('add due:2015-07-07T00:00:00 ON1')
self.t('add due:2015-07-07T14:34:56 ON2')
self.t('add due:2015-07-07T23:59:59 ON3')
self.t("add due:2015-07-07T00:00:00 ON1")
self.t("add due:2015-07-07T14:34:56 ON2")
self.t("add due:2015-07-07T23:59:59 ON3")
# Setup some tasks not due on 2015-07-07
self.t('add due:2015-07-06T23:59:59 OFF4')
self.t('add due:2015-07-08T00:00:00 OFF5')
self.t('add due:2015-07-08T00:00:01 OFF6')
self.t('add due:2015-07-06T00:00:00 OFF7')
self.t("add due:2015-07-06T23:59:59 OFF4")
self.t("add due:2015-07-08T00:00:00 OFF5")
self.t("add due:2015-07-08T00:00:01 OFF6")
self.t("add due:2015-07-06T00:00:00 OFF7")
def test_due_match_not_exact(self):
"""1634: Test that due:<date> matches any task that date."""
code, out, err = self.t('due:2015-07-07 minimal')
code, out, err = self.t("due:2015-07-07 minimal")
# Asswer that only tasks ON the date are listed.
self.assertIn("ON1", out)
@@ -1048,7 +1054,7 @@ class Test1634(TestCase):
def test_due_not_match_not_exact(self):
"""1634: Test that due.not:<date> does not match any task that date."""
code, out, err = self.t('due.not:2015-07-07 minimal')
code, out, err = self.t("due.not:2015-07-07 minimal")
# Assert that task ON the date are not listed.
self.assertNotIn("ON1", out)
@@ -1072,14 +1078,18 @@ class TestBug1915(TestCase):
def test_complex_and_or_query_variant_one(self):
"""1915: Make sure parser handles complex and-or queries correctly (1)"""
code, out, err = self.t("rc.verbose:nothing '(project:A or project:B) and status:pending' all")
code, out, err = self.t(
"rc.verbose:nothing '(project:A or project:B) and status:pending' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
def test_complex_and_or_query_variant_two(self):
"""1915: Make sure parser handles complex and-or queries correctly (2)"""
code, out, err = self.t("rc.verbose:nothing '( project:A or project:B ) and status:pending' all")
code, out, err = self.t(
"rc.verbose:nothing '( project:A or project:B ) and status:pending' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
@@ -1087,7 +1097,9 @@ class TestBug1915(TestCase):
@unittest.expectedFailure
def test_complex_and_or_query_variant_three(self):
"""1915: Make sure parser handles complex and-or queries correctly (3)"""
code, out, err = self.t("rc.verbose:nothing 'status:pending and (project:A or project:B)' all")
code, out, err = self.t(
"rc.verbose:nothing 'status:pending and (project:A or project:B)' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
@@ -1095,28 +1107,36 @@ class TestBug1915(TestCase):
@unittest.expectedFailure
def test_complex_and_or_query_variant_four(self):
"""1915: Make sure parser handles complex and-or queries correctly (4)"""
code, out, err = self.t("rc.verbose:nothing 'status:pending and ( project:A or project:B )' all")
code, out, err = self.t(
"rc.verbose:nothing 'status:pending and ( project:A or project:B )' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
def test_complex_and_or_query_variant_five(self):
"""1915: Make sure parser handles complex and-or queries correctly (5)"""
code, out, err = self.t("rc.verbose:nothing status:pending and '(project:A or project:B)' all")
code, out, err = self.t(
"rc.verbose:nothing status:pending and '(project:A or project:B)' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
def test_complex_and_or_query_variant_six(self):
"""1915: Make sure parser handles complex and-or queries correctly (6)"""
code, out, err = self.t("rc.verbose:nothing status:pending and '( project:A or project:B )' all")
code, out, err = self.t(
"rc.verbose:nothing status:pending and '( project:A or project:B )' all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
def test_complex_and_or_query_variant_seven(self):
"""1915: Make sure parser handles complex and-or queries correctly (7)"""
code, out, err = self.t("rc.verbose:nothing status:pending and \\( project:A or project:B \\) all")
code, out, err = self.t(
"rc.verbose:nothing status:pending and \\( project:A or project:B \\) all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
@@ -1124,7 +1144,9 @@ class TestBug1915(TestCase):
@unittest.expectedFailure
def test_complex_and_or_query_variant_eight(self):
"""1915: Make sure parser handles complex and-or queries correctly (8)"""
code, out, err = self.t("rc.verbose:nothing status:pending and \\(project:A or project:B\\) all")
code, out, err = self.t(
"rc.verbose:nothing status:pending and \\(project:A or project:B\\) all"
)
self.assertIn("thingA", out)
self.assertIn("thingB", out)
self.assertNotIn("thingC", out)
@@ -1136,11 +1158,11 @@ class Test2577(TestCase):
def test_filtering_for_datetime_like(self):
"""2577: Check that filtering for datetime-like project names works"""
self.t('add one pro:sat') # looks like "saturday"
self.t('add two pro:whatever')
self.t("add one pro:sat") # looks like "saturday"
self.t("add two pro:whatever")
# This should not fail (fails on 2.5.3)
code, out, err = self.t('pro:sat')
code, out, err = self.t("pro:sat")
# Assert expected output, but the crucial part of this test is success
# of the call above
@@ -1149,6 +1171,7 @@ class Test2577(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -57,40 +58,57 @@ class TestUnderline(TestCase):
# * When isatty (fileno (stdout)) is false, color is automatically disabled.
def test_nocolor_noforce_nounderline(self):
code, out, err = self.t("1 info rc.color:off rc._forcecolor:off rc.fontunderline:off")
code, out, err = self.t(
"1 info rc.color:off rc._forcecolor:off rc.fontunderline:off"
)
self.assertIn("--------", out)
def test_nocolor_noforce_underline(self):
code, out, err = self.t("1 info rc.color:off rc._forcecolor:off rc.fontunderline:on")
code, out, err = self.t(
"1 info rc.color:off rc._forcecolor:off rc.fontunderline:on"
)
self.assertIn("--------", out)
def test_nocolor_force_nounderline(self):
code, out, err = self.t("1 info rc.color:off rc._forcecolor:on rc.fontunderline:off")
code, out, err = self.t(
"1 info rc.color:off rc._forcecolor:on rc.fontunderline:off"
)
self.assertIn("--------", out)
def test_nocolor_force_underline(self):
code, out, err = self.t("1 info rc.color:off rc._forcecolor:on rc.fontunderline:on")
code, out, err = self.t(
"1 info rc.color:off rc._forcecolor:on rc.fontunderline:on"
)
self.assertNotIn("--------", out)
def test_color_noforce_nounderline(self):
code, out, err = self.t("1 info rc.color:on rc._forcecolor:off rc.fontunderline:off")
code, out, err = self.t(
"1 info rc.color:on rc._forcecolor:off rc.fontunderline:off"
)
self.assertIn("--------", out)
def test_color_noforce_underline(self):
code, out, err = self.t("1 info rc.color:on rc._forcecolor:off rc.fontunderline:on")
code, out, err = self.t(
"1 info rc.color:on rc._forcecolor:off rc.fontunderline:on"
)
self.assertIn("--------", out)
def test_color_force_nounderline(self):
code, out, err = self.t("1 info rc.color:on rc._forcecolor:on rc.fontunderline:off")
code, out, err = self.t(
"1 info rc.color:on rc._forcecolor:on rc.fontunderline:off"
)
self.assertIn("--------", out)
def test_color_force_underline(self):
code, out, err = self.t("1 info rc.color:on rc._forcecolor:on rc.fontunderline:on")
code, out, err = self.t(
"1 info rc.color:on rc._forcecolor:on rc.fontunderline:on"
)
self.assertNotIn("--------", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import math
# Ensure python finds the local simpletap and basetest modules
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -61,11 +62,11 @@ class TestCountdown(TestCase):
def test_countdown_up(self):
"""Verify countdown sorting: ascending"""
self.t.config("report.up.description", "countdown+ report")
self.t.config("report.up.columns", "id,due.countdown,description")
self.t.config("report.up.labels", "ID,Countdown,Description")
self.t.config("report.up.filter", "status:pending")
self.t.config("report.up.sort", "due+")
self.t.config("report.up.description", "countdown+ report")
self.t.config("report.up.columns", "id,due.countdown,description")
self.t.config("report.up.labels", "ID,Countdown,Description")
self.t.config("report.up.filter", "status:pending")
self.t.config("report.up.sort", "due+")
code, out, err = self.t("up")
self.assertRegex(out, " one\n.+ two\n")
@@ -85,11 +86,11 @@ class TestCountdown(TestCase):
def test_countdown_down(self):
"""Verify countdown sorting: descending"""
self.t.config("report.down.description", "countdown- report")
self.t.config("report.down.columns", "id,due.countdown,description")
self.t.config("report.down.labels", "ID,Countdown,Description")
self.t.config("report.down.filter", "status:pending")
self.t.config("report.down.sort", "due-")
self.t.config("report.down.description", "countdown- report")
self.t.config("report.down.columns", "id,due.countdown,description")
self.t.config("report.down.labels", "ID,Countdown,Description")
self.t.config("report.down.filter", "status:pending")
self.t.config("report.down.sort", "due-")
code, out, err = self.t("down")
self.assertRegex(out, " fifteen\n.+ fourteen\n")
@@ -143,7 +144,9 @@ class TestBug101(TestCase):
self.short_description = "A_task_description_"
# Generate long string
self.long_description = self.short_description * int(math.ceil(float(self.width)/len(self.short_description)))
self.long_description = self.short_description * int(
math.ceil(float(self.width) / len(self.short_description))
)
def test_short_no_count(self):
"""101: Check short description with no annotations"""
@@ -164,7 +167,7 @@ class TestBug101(TestCase):
"""101: Check long description with no annotations"""
self.t(("add", self.long_description))
code, out, err = self.t("bug101")
expected = self.long_description[:(self.width - 3)] + "..."
expected = self.long_description[: (self.width - 3)] + "..."
self.assertIn(expected, out)
def test_long_with_count(self):
@@ -172,7 +175,7 @@ class TestBug101(TestCase):
self.t(("add", self.long_description))
self.t("1 annotate 'A task annotation'")
code, out, err = self.t("bug101")
expected = self.long_description[:(self.width - 7)] + "... [1]"
expected = self.long_description[: (self.width - 7)] + "... [1]"
self.assertIn(expected, out)
def test_long_with_double_digit_count(self):
@@ -181,12 +184,13 @@ class TestBug101(TestCase):
for i in range(10):
self.t("1 annotate 'A task annotation'")
code, out, err = self.t("bug101")
expected = self.long_description[:(self.width - 8)] + "... [10]"
expected = self.long_description[: (self.width - 8)] + "... [10]"
self.assertIn(expected, out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -72,6 +73,7 @@ class TestGC(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,10 +43,10 @@ class TestZshAttributes(TestCase):
def test_zsh_attributes_helper(self):
"""Ensure the _zshattributes command returns the expected format"""
code, out, err = self.t("_zshattributes")
for line in out.split('\n'):
if line != '':
fields = line.split(':')
self.assertEqual(fields[0], fields[1])
for line in out.split("\n"):
if line != "":
fields = line.split(":")
self.assertEqual(fields[0], fields[1])
class TestZshCompletion(TestCase):
@@ -69,6 +70,7 @@ class TestAliasesCompletion(TestCase):
"""Aliases should be listed by '_aliases' not '_commands' or '_zshcommands'
reported as bug 1043
"""
def setUp(self):
self.t = Task()
self.t.config("alias.samplealias", "long")
@@ -131,6 +133,7 @@ class TestBug956(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,11 +28,13 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
class TestHistoryDaily(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -66,6 +68,7 @@ class TestHistoryDaily(TestCase):
self.assertRegex(out, r"2015\s+January\s+2\s+\++X+\s")
self.assertRegex(out, r"\s+February\s+2\s+\++X+\-+")
class TestHistoryWeekly(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -171,8 +174,10 @@ class TestHistoryAnnual(TestCase):
self.assertRegex(out, r"2014\s+\++X+\s")
self.assertRegex(out, r"2015\s+\++X+\-+")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,28 +43,30 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_env(self):
"""on-launch-env - a well-behaved, successful, on-launch hook that echoes its env."""
hookname = 'on-launch-good-env'
hookname = "on-launch-good-env"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("version") # Arbitrary command that generates output.
code, out, err = self.t("version") # Arbitrary command that generates output.
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
hook.assertExitcode(0)
logs = hook.get_logs()
taskenv = {k:v for k, v in (line.split(":", 1) for line in logs["output"]["msgs"])}
taskenv = {
k: v for k, v in (line.split(":", 1) for line in logs["output"]["msgs"])
}
self.assertEqual('api' in taskenv, True, 'api:...')
self.assertEqual('args' in taskenv, True, 'args:...')
self.assertEqual('command' in taskenv, True, 'command:...')
self.assertEqual('rc' in taskenv, True, 'rc:...')
self.assertEqual('data' in taskenv, True, 'data:...')
self.assertEqual('version' in taskenv, True, 'version:...')
self.assertEqual("api" in taskenv, True, "api:...")
self.assertEqual("args" in taskenv, True, "args:...")
self.assertEqual("command" in taskenv, True, "command:...")
self.assertEqual("rc" in taskenv, True, "rc:...")
self.assertEqual("data" in taskenv, True, "data:...")
self.assertEqual("version" in taskenv, True, "version:...")
def test_onlaunch_builtin_env_diag(self):
"""Verify that 'diagnostics' can see hook details"""
hookname = 'on-launch-good-env'
hookname = "on-launch-good-env"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("diagnostics")
@@ -71,7 +74,7 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_env_debug(self):
"""Verify that 'debug.hooks' shows hook details"""
hookname = 'on-launch-good-env'
hookname = "on-launch-good-env"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("version rc.debug.hooks:2")
@@ -84,6 +87,7 @@ class TestHooksOnLaunch(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,7 +43,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_accept(self):
"""on-add-accept - a well-behaved, successful, on-add hook."""
hookname = 'on-add-accept'
hookname = "on-add-accept"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -59,7 +60,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_accept_modify(self):
"""on-add-accept-modify - a well-behaved, successful, on-add hook, that modifies the added task."""
hookname = 'on-add-modify'
hookname = "on-add-modify"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add teh foo")
@@ -76,7 +77,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_reject(self):
"""on-add-reject - a well-behaved, failing, on-add hook."""
hookname = 'on-add-reject'
hookname = "on-add-reject"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
@@ -94,7 +95,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave1(self):
"""on-add-misbehave1 - does not consume input."""
hookname = 'on-add-misbehave1'
hookname = "on-add-misbehave1"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
@@ -108,7 +109,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave2(self):
"""on-add-misbehave2 - does not emit JSON."""
hookname = 'on-add-misbehave2'
hookname = "on-add-misbehave2"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
@@ -120,7 +121,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave3(self):
"""on-add-misbehave3 - emits additional JSON."""
hookname = 'on-add-misbehave3'
hookname = "on-add-misbehave3"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
@@ -132,7 +133,7 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave4(self):
"""on-add-misbehave4 - emits different task JSON."""
hookname = 'on-add-misbehave4'
hookname = "on-add-misbehave4"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
@@ -147,11 +148,11 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave5(self):
"""on-add-misbehave5 - emits syntactically wrong JSON."""
hookname = 'on-add-misbehave5'
hookname = "on-add-misbehave5"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
self.assertIn("Hook Error: JSON syntax error in: {\"}", err)
self.assertIn('Hook Error: JSON syntax error in: {"}', err)
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
@@ -163,11 +164,14 @@ class TestHooksOnAdd(TestCase):
def test_onadd_builtin_misbehave6(self):
"""on-add-misbehave6 - emits incomplete JSON."""
hookname = 'on-add-misbehave6'
hookname = "on-add-misbehave6"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t.runError("add foo")
self.assertIn("Hook Error: JSON Object missing 'uuid' attribute from hook script: on-add-misbehave6", err)
self.assertIn(
"Hook Error: JSON Object missing 'uuid' attribute from hook script: on-add-misbehave6",
err,
)
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
@@ -176,8 +180,10 @@ class TestHooksOnAdd(TestCase):
logs = hook.get_logs()
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,7 +43,7 @@ class TestHooksOnExit(TestCase):
def test_onexit_builtin_good(self):
"""on-exit-good - a well-behaved, successful, on-exit hook."""
hookname = 'on-exit-good'
hookname = "on-exit-good"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("version")
@@ -57,7 +58,7 @@ class TestHooksOnExit(TestCase):
def test_onexit_builtin_good_gets_changed_tasks(self):
"""on-exit-good - a well-behaved, successful, on-exit hook."""
hookname = 'on-exit-good'
hookname = "on-exit-good"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -73,7 +74,7 @@ class TestHooksOnExit(TestCase):
def test_onexit_builtin_bad(self):
"""on-exit-bad - a well-behaved, failing, on-exit hook."""
hookname = 'on-exit-bad'
hookname = "on-exit-bad"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -89,7 +90,7 @@ class TestHooksOnExit(TestCase):
def test_onexit_builtin_misbehave1(self):
"""on-exit-misbehave1 - Does not consume input."""
hookname = 'on-exit-misbehave1'
hookname = "on-exit-misbehave1"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -105,7 +106,7 @@ class TestHooksOnExit(TestCase):
def test_onexit_builtin_misbehave2(self):
"""on-exit-misbehave2 - Emits unexpected JSON."""
hookname = 'on-exit-misbehave2'
hookname = "on-exit-misbehave2"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -119,8 +120,10 @@ class TestHooksOnExit(TestCase):
logs = hook.get_logs()
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,7 +43,7 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_good(self):
"""on-launch-good - a well-behaved, successful, on-launch hook."""
hookname = 'on-launch-good'
hookname = "on-launch-good"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("version")
@@ -57,7 +58,7 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_bad(self):
"""on-launch-bad - a well-behaved, failing, on-launch hook."""
hookname = 'on-launch-bad'
hookname = "on-launch-bad"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -73,7 +74,7 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_misbehave1(self):
"""on-launch-misbehave1 - Hook kills itself."""
hookname = 'on-launch-misbehave1'
hookname = "on-launch-misbehave1"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -89,7 +90,7 @@ class TestHooksOnLaunch(TestCase):
def test_onlaunch_builtin_misbehave2(self):
"""on-launch-misbehave2 - Hook emits unexpected JSON."""
hookname = 'on-launch-misbehave2'
hookname = "on-launch-misbehave2"
self.t.hooks.add_default(hookname, log=True)
# Failing hook should prevent processing.
@@ -103,8 +104,10 @@ class TestHooksOnLaunch(TestCase):
logs = hook.get_logs()
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,7 +43,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_accept(self):
"""on-modify-accept - a well-behaved, successful, on-modify hook."""
hookname = 'on-modify-accept'
hookname = "on-modify-accept"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -61,7 +62,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_reject(self):
"""on-modify-reject - a well-behaved, failing, on-modify hook."""
hookname = 'on-modify-reject'
hookname = "on-modify-reject"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -76,7 +77,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_misbehave2(self):
"""on-modify-misbehave2 - does not emit JSON."""
hookname = 'on-modify-misbehave2'
hookname = "on-modify-misbehave2"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -92,7 +93,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_misbehave3(self):
"""on-modify-misbehave3 - emits additional JSON."""
hookname = 'on-modify-misbehave3'
hookname = "on-modify-misbehave3"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -108,7 +109,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_misbehave4(self):
"""on-modify-misbehave4 - emits different task JSON."""
hookname = 'on-modify-misbehave4'
hookname = "on-modify-misbehave4"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -124,12 +125,12 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_misbehave5(self):
"""on-modify-misbehave5 - emits syntactically wrong JSON."""
hookname = 'on-modify-misbehave5'
hookname = "on-modify-misbehave5"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
code, out, err = self.t.runError("1 modify +tag")
self.assertIn("Hook Error: JSON syntax error in: {\"}", err)
self.assertIn('Hook Error: JSON syntax error in: {"}', err)
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
@@ -140,12 +141,15 @@ class TestHooksOnModify(TestCase):
def test_onmodify_builtin_misbehave6(self):
"""on-modify-misbehave6 - emits incomplete JSON."""
hookname = 'on-modify-misbehave6'
hookname = "on-modify-misbehave6"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
code, out, err = self.t.runError("1 modify +tag")
self.assertIn("Hook Error: JSON Object missing 'uuid' attribute from hook script: on-modify-misbehave6", err)
self.assertIn(
"Hook Error: JSON Object missing 'uuid' attribute from hook script: on-modify-misbehave6",
err,
)
hook = self.t.hooks[hookname]
hook.assertTriggeredCount(1)
@@ -156,7 +160,7 @@ class TestHooksOnModify(TestCase):
def test_onmodify_revert_changes(self):
"""on-modify-revert - revert all user modifications."""
hookname = 'on-modify-revert'
hookname = "on-modify-revert"
self.t.hooks.add_default(hookname, log=True)
code, out, err = self.t("add foo")
@@ -172,8 +176,10 @@ class TestHooksOnModify(TestCase):
hook.assertTriggeredCount(1)
hook.assertExitcode(0)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -39,8 +40,8 @@ class TestHyphenation(TestCase):
"""Executed before each test in the class"""
self.t = Task()
self.t.config("defaultwidth", "20")
self.t.config("detection", "0")
self.t.config("verbose", "nothing")
self.t.config("detection", "0")
self.t.config("verbose", "nothing")
def test_hyphenation_on_space(self):
"""Split on space instead of hyphenating"""
@@ -54,6 +55,7 @@ class TestHyphenation(TestCase):
code, out, err = self.t("ls")
self.assertIn(" 1 AAAAAAAAAABBBBBB-\n", out)
class TestBug804(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -61,10 +63,10 @@ class TestBug804(TestCase):
def test_hyphenation(self):
"""Verify hyphenation is controllable"""
self.t.config("print.empty.columns", "1")
self.t.config("report.unittest.labels", "ID,Project,Pri,Description")
self.t.config("print.empty.columns", "1")
self.t.config("report.unittest.labels", "ID,Project,Pri,Description")
self.t.config("report.unittest.columns", "id,project,priority,description")
self.t.config("report.unittest.filter", "status:pending")
self.t.config("report.unittest.filter", "status:pending")
# Setup: Add a tasks, annotate with long word.
self.t("add one")
@@ -83,6 +85,7 @@ class TestBug804(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import tempfile
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -42,9 +43,9 @@ class TestIDs(TestCase):
self.t = Task()
self.t("add one +A +B")
self.t("add two +A" )
self.t("add two +A")
self.t("add three +A +B")
self.t("add four" )
self.t("add four")
self.t("add five +A +B")
def test_ids_count_A(self):
@@ -86,7 +87,8 @@ class TestIDs(TestCase):
"""_zshuuids +A"""
code, out, err = self.t("_zshuuids +A")
self.assertRegex(
out, "{0}:one\n{0}:two\n{0}:three\n{0}:five".format(UUID_REGEXP))
out, "{0}:one\n{0}:two\n{0}:three\n{0}:five".format(UUID_REGEXP)
)
def test_ids_ranges(self):
"""Verify consecutive IDs are compressed into a range"""
@@ -107,8 +109,8 @@ class TestIDMisParse(TestCase):
def test_parse_numbers_as_ids_not_patterns(self):
"""Verify that numbers are parsed as IDs"""
self.t("add 2 two") # ID 1
self.t("add 1 one") # ID 2
self.t("add 2 two") # ID 1
self.t("add 1 one") # ID 2
self.t("add 3 three") # ID 3
code, out, err = self.t("2 ls rc.verbose:nothing")
@@ -124,11 +126,13 @@ class TestIDRangeParsing(TestCase):
def generate_tasks(self, n):
"""Generates n tasks for testing purposes"""
with tempfile.NamedTemporaryFile(mode='w') as f:
f.write('\n'.join([f'{{"description": "test task {i+1}"}}' for i in range(n)]))
with tempfile.NamedTemporaryFile(mode="w") as f:
f.write(
"\n".join([f'{{"description": "test task {i+1}"}}' for i in range(n)])
)
f.flush()
# use a long timeout here, because import is quite slow
code, out, err = self.t(f'import {f.name}', timeout=100)
code, out, err = self.t(f"import {f.name}", timeout=100)
def test_single_digit_range(self):
"""Test that parsing single digit ID range works"""
@@ -167,6 +171,7 @@ class TestIDRangeParsing(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import json
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -179,7 +180,7 @@ class TestImport(TestCase):
def test_import_newlines_whitespace(self):
"""JSON array with whitespace before and after names and values"""
_data = """[
{ "uuid":"a0000000-a000-a000-a000-a00000000000" , "description" : "zero" ,"project":"A", "status":"pending","entry":"1234567889" } ,
{ "uuid":"a0000000-a000-a000-a000-a00000000000" , "description" : "zero" ,"project":"A", "status":"pending","entry":"1234567889" } ,
{ "uuid":"a1111111-a111-a111-a111-a11111111111","description":"one","project":"B","status":"pending","entry":"1234567889"}, {"uuid":"a2222222-a222-a222-a222-a22222222222","description":"two","status":"completed","entry":"1234524689","end":"1234524690" }
]"""
code, out, err = self.t("import", input=_data)
@@ -210,15 +211,20 @@ class TestImport(TestCase):
self.t("import", input=_data)
_t = self.t.export("a0000000-a000-a000-a000-a00000000000")[0]
for _uuid in ["a1111111-a111-a111-a111-a11111111111","a2222222-a222-a222-a222-a22222222222"]:
for _uuid in [
"a1111111-a111-a111-a111-a11111111111",
"a2222222-a222-a222-a222-a22222222222",
]:
self.assertTrue((_t["depends"][0] == _uuid) or (_t["depends"][1] == _uuid))
def test_import_same_task_twice(self):
"""Test import same task twice"""
_data = """{"uuid":"a1111111-a222-a333-a444-a55555555555","description":"data4"}"""
_data = (
"""{"uuid":"a1111111-a222-a333-a444-a55555555555","description":"data4"}"""
)
self.t("import", input=_data)
code, out1, err = self.t("export")
self.t.faketime('+1s')
self.t.faketime("+1s")
self.t("import", input=_data)
code, out2, err = self.t("export")
self.assertEqual(out1, out2)
@@ -230,7 +236,9 @@ class TestImport(TestCase):
{"uuid":"a0000000-a000-a000-a000-a00000000000","description":"second description"}
]"""
_, _, err = self.t("import", input=_data)
self.assertIn("Input contains UUID 'a0000000-a000-a000-a000-a00000000000' 2 times", err)
self.assertIn(
"Input contains UUID 'a0000000-a000-a000-a000-a00000000000' 2 times", err
)
class TestImportExportRoundtrip(TestCase):
@@ -239,8 +247,8 @@ class TestImportExportRoundtrip(TestCase):
self.t2 = Task()
for client in (self.t1, self.t2):
client.config("dateformat", "m/d/Y")
client.config("verbose", "0")
client.config("dateformat", "m/d/Y")
client.config("verbose", "0")
client.config("defaultwidth", "100")
def _validate_data(self, client):
@@ -277,7 +285,7 @@ class TestImportValidate(TestCase):
def test_import_empty_json(self):
"""Verify empty JSON is caught"""
j = '{}'
j = "{}"
code, out, err = self.t.runError("import", input=j)
self.assertIn("A task must have a description.", err)
@@ -343,6 +351,7 @@ class TestBug1441(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -59,7 +60,9 @@ class TestInfoCommand(TestCase):
self.t.config("urgency.user.keyword.foo.coefficient", "1.0")
self.t.config("urgency.uda.u_one.coefficient", "1.0")
self.t("add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy u_one:now u_two:1day")
self.t(
"add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy u_one:now u_two:1day"
)
self.t("1 annotate bar", input="n\n")
code, out, err = self.t("1 info")
@@ -88,7 +91,10 @@ class TestInfoCommand(TestCase):
self.assertIn("YEAR", out)
self.assertIn("UDA", out)
self.assertRegex(out, r"UUID\s+[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}")
self.assertRegex(
out,
r"UUID\s+[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
)
self.assertRegex(out, r"Urgency\s+\d+(\.\d+)?")
self.assertRegex(out, r"Priority\s+H")
@@ -105,6 +111,7 @@ class TestInfoCommand(TestCase):
self.assertRegex(out, r"U_ONE\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}")
self.assertRegex(out, r"U_TWO\s+P1D")
class TestBug425(TestCase):
def setUp(self):
self.t = Task()
@@ -120,6 +127,7 @@ class TestBug425(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -101,6 +102,7 @@ class TestLimit(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,11 +28,13 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
class TestListAllProjects(TestCase):
@classmethod
def setUpClass(cls):
@@ -56,6 +58,7 @@ class TestListAllProjects(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -64,7 +65,7 @@ class TestBug1575(TestCase):
def test_spurious_whitespace_in_url(self):
"""1575: ensure that extra whitespace does not get inserted into a URL.
tw-1575: `task log` mangles URLs when quoted
tw-1575: `task log` mangles URLs when quoted
"""
self.t("log testing123 https://foo.example.com")
@@ -74,6 +75,7 @@ class TestBug1575(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -52,6 +53,7 @@ class TestLogoCommand(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
from datetime import datetime
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -51,64 +52,66 @@ class TestMath(TestCase):
cls.t("add three 'due:eoy-10days'")
cls.t("add four due:'eoy - 10days'")
cls.t("add five 'due:eoy - 10days'")
cls.t("add six 'due:{}-12-31T23:59:59 - 10days'".format (datetime.now().year))
cls.t("add six 'due:{}-12-31T23:59:59 - 10days'".format(datetime.now().year))
def test_compact_unquoted(self):
"""compact unquoted"""
code, out, err = self.t('_get 1.due')
code, out, err = self.t("_get 1.due")
self.assertEqual(out, self.when)
def test_compact_value_quoted(self):
"""compact value quoted"""
code, out, err = self.t('_get 2.due')
code, out, err = self.t("_get 2.due")
self.assertEqual(out, self.when)
def test_compact_arg_quoted(self):
"""compact arg quoted"""
code, out, err = self.t('_get 3.due')
code, out, err = self.t("_get 3.due")
self.assertEqual(out, self.when)
def test_sparse_value_quoted(self):
"""sparse value quoted"""
code, out, err = self.t('_get 4.due')
code, out, err = self.t("_get 4.due")
self.assertEqual(out, self.when)
def test_sparse_arg_quoted(self):
"""sparse arg quoted"""
code, out, err = self.t('_get 5.due')
code, out, err = self.t("_get 5.due")
self.assertEqual(out, self.when)
def test_sparse_arg_quoted_literal(self):
"""sparse arg quoted literal"""
code, out, err = self.t('_get 6.due')
code, out, err = self.t("_get 6.due")
self.assertEqual(out, self.when)
class TestBug851(TestCase):
@classmethod
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t('add past due:-2days')
cls.t('add future due:2days')
cls.t("add past due:-2days")
cls.t("add future due:2days")
def setUp(self):
"""Executed before each test in the class"""
def test_attribute_before_with_math(self):
"""851: Test due.before:now+1d"""
code, out, err = self.t('due.before:now+1day ls')
code, out, err = self.t("due.before:now+1day ls")
self.assertIn("past", out)
self.assertNotIn("future", out)
def test_attribute_after_with_math(self):
"""851: Test due.after:now+1d"""
code, out, err = self.t('due.after:now+1day ls')
code, out, err = self.t("due.after:now+1day ls")
self.assertNotIn("past", out)
self.assertIn("future", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,10 +28,12 @@
import sys
import os
import unittest
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
class TestBug1306(TestCase):
def setUp(self):
self.t = Task()
@@ -42,6 +44,7 @@ class TestBug1306(TestCase):
code, out, err = self.t("1 info")
self.assertIn("PROJ", out)
class TestBug1763(TestCase):
def setUp(self):
self.t = Task()
@@ -52,8 +55,10 @@ class TestBug1763(TestCase):
code, out, err = self.t("1 modify due:")
self.assertIn("Modified 0 tasks.", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -76,16 +77,16 @@ class TestNagging(TestCase):
def test_nagging_ready(self):
"""Verify that nagging occurs when there are READY tasks of higher urgency"""
self.t("add one") # low urgency
self.t("add two due:10days scheduled:yesterday") # medium urgency, ready
self.t("add one") # low urgency
self.t("add two due:10days scheduled:yesterday") # medium urgency, ready
code, out, err = self.t("1 done")
self.assertIn("NAG", err)
def test_nagging_not_ready(self):
"""Verify that nagging does not occur when there are unREADY tasks of higher urgency"""
self.t("add one") # low urgency
self.t("add two due:10days scheduled:10days") # medium urgency, not ready
self.t("add one") # low urgency
self.t("add two due:10days scheduled:10days") # medium urgency, not ready
code, out, err = self.t("1 done")
self.assertNotIn("NAG", err)
@@ -156,6 +157,7 @@ class TestNagging(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -63,6 +63,7 @@ class TestNewsNag(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -74,6 +75,7 @@ class TestObfuscation(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -117,6 +118,7 @@ class TestOldestAndNewest(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -441,6 +442,7 @@ class TestOperatorsQuantity(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -55,6 +56,7 @@ class TestOverdue(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -41,17 +42,18 @@ class TestPartialMatch(TestCase):
def test_partial_date_match_spaced(self):
"""Partial match for dates: today = now --> true"""
code, out, err = self.t('calc today = now')
self.assertIn('true', out)
code, out, err = self.t("calc today = now")
self.assertIn("true", out)
def test_exact_date_match_spaced(self):
"""Exact match for dates: today == now --> false"""
code, out, err = self.t('calc today == now')
self.assertIn('false', out)
code, out, err = self.t("calc today == now")
self.assertIn("false", out)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -62,6 +63,7 @@ class TestPrepend(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -110,6 +111,7 @@ class TestPrioritySorting(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -38,8 +39,10 @@ class TestProjects(TestCase):
def setUp(self):
self.t = Task()
self.STATUS = (r"The project '{0}' has changed\. "
r"Project '{0}' is {1} complete \({2} remaining\)\.")
self.STATUS = (
r"The project '{0}' has changed\. "
r"Project '{0}' is {1} complete \({2} remaining\)\."
)
def test_project_summary_count(self):
"""'task projects' shouldn't consider deleted tasks in summary.
@@ -58,46 +61,37 @@ class TestProjects(TestCase):
"""project status/progress is shown and is up-to-date"""
code, out, err = self.t("add one pro:foo")
self.assertRegex(err, self.STATUS.format("foo", "0%",
"1 task"))
self.assertRegex(err, self.STATUS.format("foo", "0%", "1 task"))
code, out, err = self.t("add two pro:foo")
self.assertRegex(err, self.STATUS.format("foo", "0%",
"2 of 2 tasks"))
self.assertRegex(err, self.STATUS.format("foo", "0%", "2 of 2 tasks"))
code, out, err = self.t("add three pro:foo")
self.assertRegex(err, self.STATUS.format("foo", "0%",
"3 of 3 tasks"))
self.assertRegex(err, self.STATUS.format("foo", "0%", "3 of 3 tasks"))
code, out, err = self.t("add four pro:foo")
self.assertRegex(err, self.STATUS.format("foo", "0%",
"4 of 4 tasks"))
self.assertRegex(err, self.STATUS.format("foo", "0%", "4 of 4 tasks"))
code, out, err = self.t("1 done")
self.assertRegex(err, self.STATUS.format("foo", "25%",
"3 of 4 tasks"))
self.assertRegex(err, self.STATUS.format("foo", "25%", "3 of 4 tasks"))
code, out, err = self.t("2 delete", input="y\n")
self.assertRegex(err, self.STATUS.format("foo", "33%",
"2 of 3 tasks"))
self.assertRegex(err, self.STATUS.format("foo", "33%", "2 of 3 tasks"))
code, out, err = self.t("3 modify pro:bar")
self.assertRegex(err, self.STATUS.format("foo", "50%",
"1 of 2 tasks"))
self.assertRegex(err, self.STATUS.format("bar", "0%",
"1 task"))
self.assertRegex(err, self.STATUS.format("foo", "50%", "1 of 2 tasks"))
self.assertRegex(err, self.STATUS.format("bar", "0%", "1 task"))
def test_project_spaces(self):
"""projects with spaces are handled correctly"""
self.t("add hello pro:bob")
code, out, err = self.t('1 mod pro:"foo bar"')
self.assertRegex(err, self.STATUS.format("foo bar", "0%",
"1 task"))
self.assertRegex(err, self.STATUS.format("foo bar", "0%", "1 task"))
# Ensure filtering for project with spaces works
code, out, err = self.t('pro:"foo bar" count')
self.assertEqual(out.strip(), '1')
self.assertEqual(out.strip(), "1")
def test_project_spaces(self):
"""TW #2386: Filter for project:someday"""
@@ -105,8 +99,8 @@ class TestProjects(TestCase):
self.t("add hello pro:someday")
# Ensure filtering for project with numeric date works
code, out, err = self.t('pro:someday count')
self.assertEqual(out.strip(), '1')
code, out, err = self.t("pro:someday count")
self.assertEqual(out.strip(), "1")
def add_tasks(self):
self.t("add testing project:existingParent")
@@ -120,7 +114,7 @@ class TestProjects(TestCase):
order = (
".myProject ",
".myProject. ",
"abstractParent", # No space at EOL because this line in the summary ends here.
"abstractParent", # No space at EOL because this line in the summary ends here.
" kid ",
"existingParent ",
" child ",
@@ -136,8 +130,10 @@ class TestProjects(TestCase):
self.assertTrue(
lines[pos].startswith(proj),
msg=("Project '{0}' is not in line #{1} or has an unexpected "
"indentation.{2}".format(proj, pos, out))
msg=(
"Project '{0}' is not in line #{1} or has an unexpected "
"indentation.{2}".format(proj, pos, out)
),
)
def test_project_indentation(self):
@@ -321,7 +317,7 @@ class TestBug906(TestCase):
def test_project_hierarchy_filter(self):
"""906: Test project hierarchy filters
Bug 906
Bug 906
"""
self.t("add zero")
self.t("add one pro:a.b")
@@ -355,7 +351,7 @@ class TestBug856(TestCase):
def test_project_hierarchy_filter(self):
"""856: Test project.none: works
Bug 856: "task list project.none:" does not work.
Bug 856: "task list project.none:" does not work.
"""
self.t("add assigned project:X")
self.t("add floating")
@@ -364,7 +360,7 @@ class TestBug856(TestCase):
self.assertIn("floating", out)
self.assertNotIn("assigned", out)
code, out, err = self.t("project:\'\' ls")
code, out, err = self.t("project:'' ls")
self.assertIn("floating", out)
self.assertNotIn("assigned", out)
@@ -380,7 +376,7 @@ class TestBug1511(TestCase):
def test_project_hierarchy_filter(self):
"""1511: Test project:one-two can be added and queried
Bug 1511: Project titles not properly parsed if they contain hyphens
Bug 1511: Project titles not properly parsed if they contain hyphens
"""
self.t("add zero")
self.t("add one project:two-three")
@@ -396,7 +392,7 @@ class TestBug1455(TestCase):
def test_project_hierarchy_filter(self):
"""1455: Test project:school)
Bug 1455: Filter parser does not properly handle parentheses in attributes
Bug 1455: Filter parser does not properly handle parentheses in attributes
"""
self.t("add zero")
self.t("add one project:two)")
@@ -431,16 +427,14 @@ class TestBug1267(TestCase):
self.t = Task()
def test_add_task_no_project_with_default(self):
"""1267: Add a task without a project using direct rc change
"""
"""1267: Add a task without a project using direct rc change"""
project = "MakePudding"
self.t("rc.default.project={0} add proj: 'Add cream'".format(project))
code, out, err = self.t("ls")
self.assertNotIn(project, out)
def test_add_task_no_project_with_default_rcfile(self):
"""1267: Add a task without a project writing to rc file
"""
"""1267: Add a task without a project writing to rc file"""
project = "MakePudding"
self.t.config("default.project", project)
self.t("add proj: 'Add cream'")
@@ -514,9 +508,7 @@ class TestBug1904(TestCase):
self.t("add pro:a.b test2")
def validate_order(self, out):
order = ("a",
" b",
"a-b")
order = ("a", " b", "a-b")
lines = out.splitlines(True)
# position where project names start on the lines list
@@ -527,8 +519,10 @@ class TestBug1904(TestCase):
self.assertTrue(
lines[pos].startswith(proj),
msg=("Project '{0}' is not in line #{1} or has an unexpected "
"indentation.{2}".format(proj, pos, out))
msg=(
"Project '{0}' is not in line #{1} or has an unexpected "
"indentation.{2}".format(proj, pos, out)
),
)
def test_project_eval(self):
@@ -540,6 +534,7 @@ class TestBug1904(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import time
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -133,7 +134,7 @@ class TestDelete(TestCase):
self.assertIn("Purged 4 tasks.", out)
code, out, err = self.t("uuids")
self.assertEqual('\n', out)
self.assertEqual("\n", out)
def test_purge_children_fail_pending(self):
"""Purge aborts if task has pending children"""
@@ -154,7 +155,7 @@ class TestDelete(TestCase):
# Check that nothing was purged
code, out, err = self.t("count")
self.assertEqual('4\n', out)
self.assertEqual("4\n", out)
def test_purge_children_fail_confirm(self):
"""Purge aborts if user does not agree with it affecting child tasks"""
@@ -173,7 +174,7 @@ class TestDelete(TestCase):
# Check that nothing was purged
code, out, err = self.t("count")
self.assertEqual('4\n', out)
self.assertEqual("4\n", out)
def test_purge_children(self):
"""Purge command removes dependencies on indirectly purged tasks"""
@@ -202,8 +203,10 @@ class TestDelete(TestCase):
dependencies = self.t("_get 1.depends")[1].strip()
self.assertEqual("", dependencies)
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -124,34 +125,35 @@ class TestBug1436(TestCase):
def test_backslashes(self):
"""1436: Prove to the reader that backslashes are eaten twice (which means
two backslashes to one) once by Python, and once more by some mystery process
launch thing.
two backslashes to one) once by Python, and once more by some mystery process
launch thing.
This problem is entirely testing artifact, and not Taskwarrior.
This problem is entirely testing artifact, and not Taskwarrior.
"""
self.echo = Task(taskw=utils.binary_location("echo", USE_PATH=True))
# One level of backshashes gets eaten by bash
# Verify with: $ echo xxx \\\\yyy zzz
code, out, err = self.echo(r"xxx \\\\yyy zzz") # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r"xxx \\yyy zzz") # Shows as 'xxx \yyy zzz'
code, out, err = self.echo(r"xxx \yyy zzz") # Shows as 'xxx yyy zzz'
code, out, err = self.echo(r"xxx \\\\yyy zzz") # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r"xxx \\yyy zzz") # Shows as 'xxx \yyy zzz'
code, out, err = self.echo(r"xxx \yyy zzz") # Shows as 'xxx yyy zzz'
# If single quotes are used, the backslashes are not eaten
# Verify with: $ echo xxx '\\\\yyy' zzz
code, out, err = self.echo(r"xxx '\\\\yyy' zzz") # Shows as 'xxx \\\\yyy zzz'
code, out, err = self.echo(r"xxx '\\yyy' zzz") # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r"xxx '\yyy' zzz") # Shows as 'xxx \yyy zzz'
code, out, err = self.echo(r"xxx '\\\\yyy' zzz") # Shows as 'xxx \\\\yyy zzz'
code, out, err = self.echo(r"xxx '\\yyy' zzz") # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r"xxx '\yyy' zzz") # Shows as 'xxx \yyy zzz'
# If double quotes are used, the backslashes are eaten
# Verify with: $ echo xxx "\\\\yyy" zzz
code, out, err = self.echo(r'xxx "\\\\yyy" zzz') # Shows as 'xxx \\\\yyy zzz'
code, out, err = self.echo(r'xxx "\\yyy" zzz') # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r'xxx "\yyy" zzz') # Shows as 'xxx \yyy zzz'
code, out, err = self.echo(r'xxx "\\\\yyy" zzz') # Shows as 'xxx \\\\yyy zzz'
code, out, err = self.echo(r'xxx "\\yyy" zzz') # Shows as 'xxx \\yyy zzz'
code, out, err = self.echo(r'xxx "\yyy" zzz') # Shows as 'xxx \yyy zzz'
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -39,7 +40,7 @@ class TestOverride(TestCase):
def setUp(self):
"""Executed before each test in the class"""
self.t = Task()
self.t.config("regex", "0")
self.t.config("regex", "0")
self.t.config("verbose", "nothing")
def test_override(self):
@@ -71,6 +72,7 @@ class TestRCSegfault(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -30,6 +30,7 @@ import os
import re
import time
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -41,12 +42,12 @@ class TestRecurrenceSorting(TestCase):
def setUpClass(cls):
"""Executed once before any test in the class"""
cls.t = Task()
cls.t.config("report.asc.columns", "id,recur,description")
cls.t.config("report.asc.sort", "recur+")
cls.t.config("report.asc.filter", "status:pending")
cls.t.config("report.asc.columns", "id,recur,description")
cls.t.config("report.asc.sort", "recur+")
cls.t.config("report.asc.filter", "status:pending")
cls.t.config("report.desc.columns", "id,recur,description")
cls.t.config("report.desc.sort", "recur-")
cls.t.config("report.desc.filter", "status:pending")
cls.t.config("report.desc.sort", "recur-")
cls.t.config("report.desc.filter", "status:pending")
cls.t("add one due:tomorrow recur:daily")
cls.t("add two due:tomorrow recur:weekly")
@@ -205,6 +206,7 @@ class TestRecurrenceTasks(TestCase):
code, out, err = self.t("3 delete", input="y\n")
self.assertIn("Deleted 1 task.", out)
class TestBug972(TestCase):
def setUp(self):
"""972: Executed before each test in the class"""
@@ -212,7 +214,7 @@ class TestBug972(TestCase):
def test_interpretation_of_seven(self):
"""Bug 972: A recurrence period of "7" is interpreted as "7s", not "7d"
as intended.
as intended.
"""
code, out, err = self.t.runError("add one due:now recur:2")
self.assertIn("The duration value '2' is not supported.", err)
@@ -226,7 +228,7 @@ class TestDeletionRecurrence(TestCase):
def test_delete_parent(self):
"""Delete a parent with child tasks"""
self.t("add one due:eom recur:daily")
self.t("list") # GC/handleRecurrence
self.t("list") # GC/handleRecurrence
code, out, err = self.t("1 delete", input="y\ny\n")
self.assertIn("Deleted 2 tasks.", out)
@@ -237,7 +239,7 @@ class TestDeletionRecurrence(TestCase):
"""Delete a child with sibling tasks"""
self.t("add one due:eom recur:daily")
self.t("list rc.recurrence.limit:5")
code, out, err = self.t("list rc.verbose:nothing") # GC/handleRecurrence
code, out, err = self.t("list rc.verbose:nothing") # GC/handleRecurrence
self.assertEqual(out.count("one"), 5)
code, out, err = self.t("2 delete", input="y\ny\n")
@@ -252,7 +254,7 @@ class TestAppendPrependRecurrence(TestCase):
def test_append_propagate(self):
"""Append and propagate"""
self.t("add one due:eom recur:daily")
self.t("list rc.recurrence.limit:2") # GC/handleRecurrence
self.t("list rc.recurrence.limit:2") # GC/handleRecurrence
code, out, err = self.t("2 append APP", input="y\n")
self.assertIn("Appended 2 tasks.", out)
@@ -260,7 +262,7 @@ class TestAppendPrependRecurrence(TestCase):
def test_prepend_propagate(self):
"""Prepend and propagate"""
self.t("add one due:eom recur:daily")
self.t("list rc.recurrence.limit:2") # GC/handleRecurrence
self.t("list rc.recurrence.limit:2") # GC/handleRecurrence
code, out, err = self.t("2 prepend PRE", input="y\n")
self.assertIn("Prepended 2 tasks.", out)
@@ -359,11 +361,12 @@ class TestBug955(TestCase):
self.assertIn("Deleted 2 tasks", out)
code, out, err = self.t.runError("all status:recurring")
self.assertIn("No matches", err)
self.assertIn("No matches", err)
code, out, err = self.t.runError("ls")
self.assertIn("No matches", err)
class TestUpgradeToRecurring(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -383,6 +386,7 @@ class TestUpgradeToRecurring(TestCase):
code, out, err = self.t.runError("1 modify recur:weekly")
self.assertIn("You cannot specify a recurring task without a due date.", err)
class TestRecurrenceNotification(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -399,6 +403,7 @@ class TestRecurrenceNotification(TestCase):
code, out, err = self.t("list")
self.assertNotIn("Creating recurring task instance 'foo'", err)
class BaseTestBug360(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -407,10 +412,10 @@ class BaseTestBug360(TestCase):
# This command forces a handleRecurrence() call to generate synthetic tasks.
self.t("ls")
class TestBug360RemovalError(BaseTestBug360):
def test_modify_recursive_project(self):
"""360: Modifying a recursive task by adding project: also modifies parent
"""
"""360: Modifying a recursive task by adding project: also modifies parent"""
code, out, err = self.t("1 modify project:bar", input="y\n")
expected = "Modified 2 tasks."
@@ -419,8 +424,7 @@ class TestBug360RemovalError(BaseTestBug360):
self.assertNotIn(expected, err)
def test_cannot_remove_recurrence(self):
"""360: Cannot remove recurrence from recurring task
"""
"""360: Cannot remove recurrence from recurring task"""
# TODO Removing recur: from a recurring task should also remove imask
# and parent.
@@ -432,8 +436,7 @@ class TestBug360RemovalError(BaseTestBug360):
self.assertIn(expected, err)
def test_cannot_remove_due_date(self):
"""360: Cannot remove due date from recurring task
"""
"""360: Cannot remove due date from recurring task"""
# TODO Removing due: from a recurring task should also remove recur,
# imask and parent
code, out, err = self.t.runError("2 modify due:")
@@ -470,6 +473,7 @@ class TestBug360AllowedChanges(BaseTestBug360):
expected = "You cannot remove the due date from a recurring task."
self.assertNotIn(expected, err)
class TestBug649(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -482,6 +486,7 @@ class TestBug649(TestCase):
self.assertIn("is neither pending nor waiting", out)
self.assertNotIn("Completed 1", out)
class TestBugC001(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -492,6 +497,7 @@ class TestBugC001(TestCase):
code, out, err = self.t("add one due:tomorrow recur:daily")
code, out, err = self.t("add two due:tomorrow recur:daily")
class TestBug839(TestCase):
def setUp(self):
"""Executed before each test in the class"""
@@ -501,7 +507,10 @@ class TestBug839(TestCase):
"""839: Verify that importing a legacy recurrence value is ok"""
# use a recent timestamp to avoid slowly iterating over large number of tasks
justnow = int(time.time()) - 120
json = '{"description":"one","due":"%s","recur":"1m","status":"recurring","uuid":"ebeeab00-ccf8-464b-8b58-f7f2d606edfb"}' % justnow
json = (
'{"description":"one","due":"%s","recur":"1m","status":"recurring","uuid":"ebeeab00-ccf8-464b-8b58-f7f2d606edfb"}'
% justnow
)
self.t("import -", input=json)
code, out, err = self.t("list")
@@ -519,75 +528,76 @@ class TestPeriod(TestCase):
self.t = Task()
def test_recurrence_periods(self):
"""Verify recurrence period special-case support
"""Verify recurrence period special-case support
Date getNextRecurrence (Date& current, std::string& period)
Date getNextRecurrence (Date& current, std::string& period)
Confirmed:
getNextRecurrence convertDuration
----------------- ---------------
daily
day
weekly
sennight
biweekly
fortnight
monthly monthly
quarterly quarterly
semiannual semiannual
bimonthly bimonthly
biannual biannual
biyearly biyearly
annual
yearly
*m *m
*q *q
*d
*w
*y
"""
Confirmed:
getNextRecurrence convertDuration
----------------- ---------------
daily
day
weekly
sennight
biweekly
fortnight
monthly monthly
quarterly quarterly
semiannual semiannual
bimonthly bimonthly
biannual biannual
biyearly biyearly
annual
yearly
*m *m
*q *q
*d
*w
*y
"""
self.t("add daily due:tomorrow recur:daily")
self.t("add 1day due:tomorrow recur:1day")
self.t("add weekly due:tomorrow recur:weekly")
self.t("add 1sennight due:tomorrow recur:1sennight")
self.t("add biweekly due:tomorrow recur:biweekly")
self.t("add fortnight due:tomorrow recur:fortnight")
self.t("add monthly due:tomorrow recur:monthly")
self.t("add quarterly due:tomorrow recur:quarterly")
self.t("add semiannual due:tomorrow recur:semiannual")
self.t("add bimonthly due:tomorrow recur:bimonthly")
self.t("add biannual due:tomorrow recur:biannual")
self.t("add biyearly due:tomorrow recur:biyearly")
self.t("add annual due:tomorrow recur:annual")
self.t("add yearly due:tomorrow recur:yearly")
self.t("add 2d due:tomorrow recur:2d")
self.t("add 2w due:tomorrow recur:2w")
self.t("add 2mo due:tomorrow recur:2mo")
self.t("add 2q due:tomorrow recur:2q")
self.t("add 2y due:tomorrow recur:2y")
self.t("add daily due:tomorrow recur:daily")
self.t("add 1day due:tomorrow recur:1day")
self.t("add weekly due:tomorrow recur:weekly")
self.t("add 1sennight due:tomorrow recur:1sennight")
self.t("add biweekly due:tomorrow recur:biweekly")
self.t("add fortnight due:tomorrow recur:fortnight")
self.t("add monthly due:tomorrow recur:monthly")
self.t("add quarterly due:tomorrow recur:quarterly")
self.t("add semiannual due:tomorrow recur:semiannual")
self.t("add bimonthly due:tomorrow recur:bimonthly")
self.t("add biannual due:tomorrow recur:biannual")
self.t("add biyearly due:tomorrow recur:biyearly")
self.t("add annual due:tomorrow recur:annual")
self.t("add yearly due:tomorrow recur:yearly")
self.t("add 2d due:tomorrow recur:2d")
self.t("add 2w due:tomorrow recur:2w")
self.t("add 2mo due:tomorrow recur:2mo")
self.t("add 2q due:tomorrow recur:2q")
self.t("add 2y due:tomorrow recur:2y")
# Verify that the recurring task instances were created. One of each.
code, out, err = self.t("list")
self.assertIn(" daily ", out)
self.assertIn(" 1day ", out)
self.assertIn(" weekly ", out)
self.assertIn(" 1sennight ", out)
self.assertIn(" biweekly ", out)
self.assertIn(" fortnight ", out)
self.assertIn(" monthly ", out)
self.assertIn(" quarterly ", out)
self.assertIn(" semiannual ", out)
self.assertIn(" bimonthly ", out)
self.assertIn(" biannual ", out)
self.assertIn(" biyearly ", out)
self.assertIn(" annual ", out)
self.assertIn(" yearly ", out)
self.assertIn(" 2d ", out)
self.assertIn(" 2w ", out)
self.assertIn(" 2mo ", out)
self.assertIn(" 2q ", out)
self.assertIn(" 2y ", out)
# Verify that the recurring task instances were created. One of each.
code, out, err = self.t("list")
self.assertIn(" daily ", out);
self.assertIn(" 1day ", out);
self.assertIn(" weekly ", out);
self.assertIn(" 1sennight ", out);
self.assertIn(" biweekly ", out);
self.assertIn(" fortnight ", out);
self.assertIn(" monthly ", out);
self.assertIn(" quarterly ", out);
self.assertIn(" semiannual ", out);
self.assertIn(" bimonthly ", out);
self.assertIn(" biannual ", out);
self.assertIn(" biyearly ", out);
self.assertIn(" annual ", out);
self.assertIn(" yearly ", out);
self.assertIn(" 2d ", out);
self.assertIn(" 2w ", out);
self.assertIn(" 2mo ", out);
self.assertIn(" 2q ", out);
self.assertIn(" 2y ", out);
class TestBugAnnual(TestCase):
def setUp(self):
@@ -596,11 +606,11 @@ class TestBugAnnual(TestCase):
def test_annual_creep(self):
"""Verify 'annual' recurring tasks don't creep"""
self.t.config("dateformat", "YMD")
self.t.config("report.annual.labels", "ID,Due")
self.t.config("dateformat", "YMD")
self.t.config("report.annual.labels", "ID,Due")
self.t.config("report.annual.columns", "id,due")
self.t.config("report.annual.filter", "status:pending")
self.t.config("report.annual.sort", "due+")
self.t.config("report.annual.filter", "status:pending")
self.t.config("report.annual.sort", "due+")
# If a task is added with a due date ten years ago, with an annual recurrence,
# then the synthetic tasks in between then and now have a due date that creeps.
@@ -647,6 +657,7 @@ class TestBugAnnual(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -28,6 +28,7 @@
import sys
import os
import unittest
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -54,6 +55,7 @@ class TestReportCommand(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

View File

@@ -14,4 +14,4 @@ pushd test
make
./run_all -v
cat all.log | grep 'not ok'
./problems
./problems

View File

@@ -29,6 +29,7 @@ import sys
import os
import unittest
import platform
# Ensure python finds the local simpletap module
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -47,7 +48,7 @@ class TestSearch(TestCase):
def test_plain_arg(self):
"""Verify plain args are interpreted as search terms
tw-1635: Running "task anystringatall" does not filter anything
tw-1635: Running "task anystringatall" does not filter anything
"""
code, out, err = self.t("one list")
self.assertIn("one", out)
@@ -65,6 +66,7 @@ class TestSearch(TestCase):
self.assertIn("one", out)
self.assertNotIn("two", out)
class Test1418(TestCase):
def setUp(self):
self.t = Task()
@@ -140,6 +142,7 @@ class Test1418(TestCase):
code, out, err = self.t("/foo\\+/")
self.assertIn(description, out)
class TestBug1472(TestCase):
@classmethod
def setUpClass(cls):
@@ -180,67 +183,74 @@ class TestBug1472(TestCase):
class Test1469(TestCase):
def setUp(self):
self.t = Task()
self.t('add foo')
self.t("add foo")
self.t('add "neue Badmöbel kaufen"')
def test_implicit_search_sensitive_regex(self):
"""1469: Implicit search, case sensitive, regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=on')
"""1469: Implicit search, case sensitive, regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=yes rc.regex=on")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
def test_implicit_search_sensitive_noregex(self):
"""1469: Implicit search, case sensitive, no regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=off')
"""1469: Implicit search, case sensitive, no regex"""
code, out, err = self.t(
"list /möbel/ rc.search.case.sensitive=yes rc.regex=off"
)
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin')
@unittest.skipIf(
"CYGWIN" in platform.system(), "Skipping regex case-insensitive test for Cygwin"
)
def test_implicit_search_insensitive_regex(self):
"""1469: Implicit search, case insensitive, regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=on')
self.assertEqual(0, code,
"Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
"""1469: Implicit search, case insensitive, regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=on")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
def test_implicit_search_insensitive_noregex(self):
"""1469: Implicit search, case insensitive, no regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=off')
"""1469: Implicit search, case insensitive, no regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=off")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
def test_explicit_search_sensitive_regex(self):
"""1469: Explicit search, case sensitive, regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=on')
"""1469: Explicit search, case sensitive, regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=yes rc.regex=on")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
def test_explicit_search_sensitive_noregex(self):
"""1469: Explicit search, case sensitive, no regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=off')
"""1469: Explicit search, case sensitive, no regex"""
code, out, err = self.t(
"list /möbel/ rc.search.case.sensitive=yes rc.regex=off"
)
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin')
@unittest.skipIf(
"CYGWIN" in platform.system(), "Skipping regex case-insensitive test for Cygwin"
)
def test_explicit_search_insensitive_regex(self):
"""1469: Explicit search, case insensitive, regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=on')
"""1469: Explicit search, case insensitive, regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=on")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
def test_explicit_search_insensitive_noregex(self):
"""1469: Explicit search, case insensitive, no regex """
code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=off')
"""1469: Explicit search, case insensitive, no regex"""
code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=off")
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
self.assertIn('möbel', out)
self.assertNotIn('foo', out)
self.assertIn("möbel", out)
self.assertNotIn("foo", out)
class TestBug1479(TestCase):
@@ -272,6 +282,7 @@ class TestBug1479(TestCase):
if __name__ == "__main__":
from simpletap import TAPTestRunner
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4 ft=python

Some files were not shown because too many files have changed in this diff Show More