add initial bulk run from pre-commit over all files
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
1261
test/lexer.test.cpp
1261
test/lexer.test.cpp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,4 +14,4 @@ pushd test
|
||||
make
|
||||
./run_all -v
|
||||
cat all.log | grep 'not ok'
|
||||
./problems
|
||||
./problems
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user