Merge branch '2.4.5' of ssh://git.tasktools.org/tm/task into 2.4.5
This commit is contained in:
@@ -5,6 +5,7 @@ How to Build Taskwarrior
|
||||
will be utilizing C++11.
|
||||
- libuuid
|
||||
- gnutls (optional)
|
||||
- python 2.7 or 3 (optional, for running the test suite)
|
||||
|
||||
Obtain and build code:
|
||||
$ git clone https://git.tasktools.org/scm/tm/task.git task.git
|
||||
|
||||
@@ -40,40 +40,40 @@ class TestAbbreviation(TestCase):
|
||||
self.t = Task()
|
||||
self.t.config("abbreviation.minimum", "1")
|
||||
|
||||
self.t(("add", "project:home", "priority:H", "hasattributes"))
|
||||
self.t(("add", "noattributes"))
|
||||
self.t("add project:home priority:H hasattributes")
|
||||
self.t("add noattributes")
|
||||
|
||||
def verify_attibute(self, expr):
|
||||
code, out, err = self.t(("list", expr))
|
||||
def verify_attribute(self, expr):
|
||||
code, out, err = self.t("list {0}".format(expr))
|
||||
|
||||
self.assertIn("hasattributes", out, msg=expr + " hasattributes")
|
||||
self.assertNotIn("noattributes", out, msg=expr + " noattributes")
|
||||
self.assertIn("hasattributes", out)
|
||||
self.assertNotIn("noattributes", out)
|
||||
|
||||
def test_attribute_abbreviations(self):
|
||||
"Test project attribute abbrevations"
|
||||
|
||||
self.verify_attibute("project:home")
|
||||
self.verify_attibute("projec:home")
|
||||
self.verify_attibute("proje:home")
|
||||
self.verify_attibute("proj:home")
|
||||
self.verify_attibute("pro:home")
|
||||
self.verify_attribute("project:home")
|
||||
self.verify_attribute("projec:home")
|
||||
self.verify_attribute("proje:home")
|
||||
self.verify_attribute("proj:home")
|
||||
self.verify_attribute("pro:home")
|
||||
|
||||
def test_uda_abbreviations(self):
|
||||
"Test uda attribute abbrevations"
|
||||
# NOTE This will be an UDA when TW-1541 is closed, for now it's just
|
||||
# one more attribute
|
||||
|
||||
self.verify_attibute("priority:H")
|
||||
self.verify_attibute("priorit:H")
|
||||
self.verify_attibute("priori:H")
|
||||
self.verify_attibute("prior:H")
|
||||
self.verify_attibute("prio:H")
|
||||
self.verify_attibute("pri:H")
|
||||
self.verify_attribute("priority:H")
|
||||
self.verify_attribute("priorit:H")
|
||||
self.verify_attribute("priori:H")
|
||||
self.verify_attribute("prior:H")
|
||||
self.verify_attribute("prio:H")
|
||||
self.verify_attribute("pri:H")
|
||||
|
||||
def verify_command(self, cmd):
|
||||
code, out, err = self.t((cmd,))
|
||||
code, out, err = self.t(cmd)
|
||||
|
||||
self.assertIn("MIT license", out, msg=cmd)
|
||||
self.assertIn("MIT license", out)
|
||||
|
||||
def test_command_abbreviations(self):
|
||||
"Test version command abbrevations"
|
||||
|
||||
@@ -39,23 +39,23 @@ class TestAppend(TestCase):
|
||||
def setUp(self):
|
||||
"""Executed before each test in the class"""
|
||||
self.t = Task()
|
||||
self.t(("add", "foo"))
|
||||
self.t("add foo")
|
||||
|
||||
def test_append(self):
|
||||
"""Add a task and then append more description"""
|
||||
code, out, err = self.t(("1", "append", "bar"))
|
||||
code, out, err = self.t("1 append bar")
|
||||
|
||||
expected = "Appended 1 task."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
code, out, err = self.t(("info", "1"))
|
||||
code, out, err = self.t("info 1")
|
||||
|
||||
expected = "Description\s+foo\sbar\n"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
def test_append_error_on_empty(self):
|
||||
"""Should cause an error when nothing is appended"""
|
||||
code, out, err = self.t.runError(("1", "append"))
|
||||
code, out, err = self.t.runError("1 append")
|
||||
|
||||
expected = "Additional text must be provided."
|
||||
self.assertIn(expected, err)
|
||||
@@ -72,14 +72,14 @@ class TestBug440(TestCase):
|
||||
|
||||
def test_subst_and_append_at_once(self):
|
||||
"""Simultaneous substitution and append"""
|
||||
self.t(("add", "Foo"))
|
||||
self.t(("add", "Foo"))
|
||||
self.t("add Foo")
|
||||
self.t("add Foo")
|
||||
|
||||
self.t(("1", "append", "/Foo/Bar/", "Appendtext"))
|
||||
self.t(("2", "append", "Appendtext", "/Foo/Bar/"))
|
||||
self.t("1 append /Foo/Bar/ Appendtext")
|
||||
self.t("2 append Appendtext /Foo/Bar/")
|
||||
|
||||
code1, out1, err1 = self.t(("1", "ls"))
|
||||
code2, out2, err2 = self.t(("2", "ls"))
|
||||
code1, out1, err1 = self.t("1 ls")
|
||||
code2, out2, err2 = self.t("2 ls")
|
||||
|
||||
self.assertNotIn("Foo", out1)
|
||||
self.assertRegexpMatches(out1, "\w+ Appendtext")
|
||||
|
||||
@@ -41,22 +41,22 @@ class TestIDPosition(TestCase):
|
||||
"""Executed once before any test in the class"""
|
||||
cls.t = Task()
|
||||
|
||||
cls.t(("add", "one"))
|
||||
cls.t(("add", "two"))
|
||||
cls.t("add one")
|
||||
cls.t("add two")
|
||||
|
||||
def test_id_read_cmd(self):
|
||||
"""Test id before and after read command"""
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("one", out)
|
||||
self.assertNotIn("two", out)
|
||||
|
||||
code, out, err = self.t(("info", "1"))
|
||||
code, out, err = self.t("info 1")
|
||||
self.assertIn("one", out)
|
||||
self.assertNotIn("two", out)
|
||||
|
||||
def test_id_write_cmd(self):
|
||||
"""Test id before write command"""
|
||||
code, out, err = self.t(("2", "done"))
|
||||
code, out, err = self.t("2 done")
|
||||
self.assertIn("Completed task 2", out)
|
||||
|
||||
|
||||
|
||||
@@ -165,16 +165,17 @@ class Task(object):
|
||||
# Enable nicer-looking calls by allowing plain strings
|
||||
try:
|
||||
# Python 2.x
|
||||
if isinstance(args, basestring):
|
||||
args = shlex.split(args)
|
||||
type_check = basestring
|
||||
except NameError:
|
||||
# Python 3.x
|
||||
if isinstance(args, str):
|
||||
args = shlex.split(args)
|
||||
type_check = str
|
||||
|
||||
if isinstance(args, type_check):
|
||||
args = shlex.split(args)
|
||||
|
||||
return args
|
||||
|
||||
def runSuccess(self, args=(), input=None, merge_streams=False,
|
||||
def runSuccess(self, args="", input=None, merge_streams=False,
|
||||
timeout=5):
|
||||
"""Invoke task with given arguments and fail if exit code != 0
|
||||
|
||||
@@ -279,7 +280,7 @@ class Task(object):
|
||||
which should be the output of any previous process that failed.
|
||||
"""
|
||||
try:
|
||||
output = self.runSuccess(("diag",))
|
||||
output = self.runSuccess("diag")
|
||||
except CommandError as e:
|
||||
# If task diag failed add the error to stderr
|
||||
output = (e.code, None, str(e))
|
||||
|
||||
@@ -46,14 +46,14 @@ class TestBug1006(TestCase):
|
||||
self.t.config("verbose", "affected")
|
||||
|
||||
def initial_tasks(self):
|
||||
self.t(("add", "des"))
|
||||
self.t(("1", "annotate", "des"))
|
||||
self.t("add des")
|
||||
self.t("1 annotate des")
|
||||
|
||||
def test_completion_of_des_inactive(self):
|
||||
"Check that the completion is inactive in task descriptions"
|
||||
|
||||
self.initial_tasks()
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Description +des\n"
|
||||
errormsg = "Attribute not completed in description"
|
||||
@@ -66,7 +66,7 @@ class TestBug1006(TestCase):
|
||||
"Check that the completion works when needed"
|
||||
|
||||
self.initial_tasks()
|
||||
code, out, err = self.t(("des:des",))
|
||||
code, out, err = self.t("des:des")
|
||||
|
||||
errormsg = "Task found using its description"
|
||||
self.assertIn("1 task", out, msg=errormsg)
|
||||
@@ -74,8 +74,8 @@ class TestBug1006(TestCase):
|
||||
def test_accented_chars(self):
|
||||
"Check that é in entrée remains untouched"
|
||||
|
||||
self.t(("add", "entrée interdite"))
|
||||
code, out, err = self.t(("list", "interdite"))
|
||||
self.t("add entrée interdite")
|
||||
code, out, err = self.t("list interdite")
|
||||
|
||||
errormsg = "'entrée' left intact"
|
||||
self.assertIn("entrée interdite", out, msg=errormsg)
|
||||
|
||||
@@ -46,24 +46,24 @@ class TestBug1031(TestCase):
|
||||
|
||||
def test_alias_to(self):
|
||||
"""alias working as expected: 'from' -> 'to'"""
|
||||
self.t(("add", "from"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
self.t("add from")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Description\s+to"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
def test_alias_to_to(self):
|
||||
"""alias working as expected: 'from -- to' -> 'to to'"""
|
||||
self.t(("add", "from", "--", "to"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
self.t("add from -- to")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Description\s+to to"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
def test_alias_to_from(self):
|
||||
"""alias working as expected: 'to -- from' -> 'to from'"""
|
||||
self.t(("add", "to", "--", "from"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
self.t("add to -- from")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Description\s+to from"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
@@ -45,16 +45,16 @@ class TestBug1036(TestCase):
|
||||
|
||||
def test_until_may_modify(self):
|
||||
"""check that until attribute may be modified"""
|
||||
self.t(("add", "test"))
|
||||
code, out, err = self.t(("1", "mod", "until:1/1/2020"))
|
||||
self.t("add test")
|
||||
code, out, err = self.t("1 mod until:1/1/2020")
|
||||
|
||||
expected = "Modifying task 1 'test'."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def test_may_modify_on_until(self):
|
||||
"""check that task with until attribute set may be modified"""
|
||||
self.t(("add", "test", "until:1/1/2020"))
|
||||
code, out, err = self.t(("1", "mod", "/test/Hello/"))
|
||||
self.t("add test until:1/1/2020")
|
||||
code, out, err = self.t("1 mod /test/Hello/")
|
||||
|
||||
expected = "Modifying task 1 'Hello'."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
@@ -53,16 +53,16 @@ class TestBug1063(TestCase):
|
||||
Reported as bug 1063
|
||||
"""
|
||||
|
||||
self.t(("add", "four", "foo:4"))
|
||||
self.t(("add", "one", "foo:1"))
|
||||
self.t(("add", "three", "foo:3"))
|
||||
self.t(("add", "two", "foo:2"))
|
||||
self.t("add four foo:4")
|
||||
self.t("add one foo:1")
|
||||
self.t("add three foo:3")
|
||||
self.t("add two foo:2")
|
||||
|
||||
code, out, err = self.t(("bar",))
|
||||
code, out, err = self.t("bar")
|
||||
expected = re.compile("4.+3.+2.+1", re.DOTALL) # dot matches \n too
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
code, out, err = self.t(("bar", "rc.report.bar.sort=foo+"))
|
||||
code, out, err = self.t("bar rc.report.bar.sort=foo+")
|
||||
expected = re.compile("1.+2.+3.+4", re.DOTALL) # dot matches \n too
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
|
||||
@@ -43,15 +43,12 @@ class TestBug1254(TestCase):
|
||||
def test_no_segmentation_fault_calc_negative_multiplication(self):
|
||||
"""calc can multiply zero and negative numbers
|
||||
"""
|
||||
args = ("calc", "0*-1")
|
||||
self.run_command(args)
|
||||
self.run_command("calc 0*-1")
|
||||
|
||||
def test_calc_positive_multiplication(self):
|
||||
"""calc can multiply negative zero and positive
|
||||
"""
|
||||
|
||||
args = ("calc", "0*1")
|
||||
self.run_command(args)
|
||||
self.run_command("calc 0*1")
|
||||
|
||||
def run_command(self, args):
|
||||
code, out, err = self.t(args)
|
||||
|
||||
@@ -44,12 +44,9 @@ class TestBug1267(TestCase):
|
||||
"""
|
||||
project = "MakePudding"
|
||||
|
||||
args = ["rc.default.project={0}".format(project), "add",
|
||||
"proj:", "Add cream"]
|
||||
self.t(args)
|
||||
self.t("rc.default.project={0} add proj: 'Add cream'".format(project))
|
||||
|
||||
args = ("ls",)
|
||||
code, out, err = self.t(args, merge_streams=False)
|
||||
code, out, err = self.t("ls")
|
||||
|
||||
self.assertNotIn(project, out)
|
||||
|
||||
@@ -60,11 +57,9 @@ class TestBug1267(TestCase):
|
||||
|
||||
self.t.config("default.project", project)
|
||||
|
||||
args = ("add", "proj:", "Add cream")
|
||||
self.t(args)
|
||||
self.t("add proj: 'Add cream'")
|
||||
|
||||
args = ("ls",)
|
||||
code, out, err = self.t(args, merge_streams=False)
|
||||
code, out, err = self.t("ls")
|
||||
|
||||
self.assertNotIn(project, out)
|
||||
|
||||
|
||||
@@ -40,21 +40,16 @@ class BaseTestBug360(TestCase):
|
||||
def setUp(self):
|
||||
"""Executed before each test in the class"""
|
||||
self.t = Task()
|
||||
args = ("add", "foo", "due:tomorrow", "recur:daily")
|
||||
self.t(args)
|
||||
self.t("add foo due:tomorrow recur:daily")
|
||||
# TODO: Add explanation why this line is necessary
|
||||
args = ("ls",)
|
||||
self.t(args)
|
||||
self.t("ls")
|
||||
|
||||
|
||||
class TestBug360RemovalError(BaseTestBug360):
|
||||
def test_modify_recursive_project(self):
|
||||
"""Modifying a recursive task by adding project: also modifies parent
|
||||
"""
|
||||
commands = "y\n"
|
||||
args = ("1", "modify", "project:bar")
|
||||
|
||||
code, out, err = self.t(args, commands)
|
||||
code, out, err = self.t("1 modify project:bar", input="y\n")
|
||||
|
||||
expected = "Modified 2 tasks."
|
||||
self.assertIn(expected, out)
|
||||
@@ -66,9 +61,8 @@ class TestBug360RemovalError(BaseTestBug360):
|
||||
"""
|
||||
# TODO Removing recur: from a recurring task should also remove imask
|
||||
# and parent.
|
||||
args = ("2", "modify", "recur:")
|
||||
|
||||
code, out, err = self.t.runError(args)
|
||||
code, out, err = self.t.runError("2 modify recur:")
|
||||
# Expected non zero exit-code
|
||||
self.assertEqual(code, 2)
|
||||
|
||||
@@ -80,9 +74,7 @@ class TestBug360RemovalError(BaseTestBug360):
|
||||
"""
|
||||
# TODO Removing due: from a recurring task should also remove recur,
|
||||
# imask and parent
|
||||
args = ("2", "modify", "due:")
|
||||
|
||||
code, out, err = self.t.runError(args)
|
||||
code, out, err = self.t.runError("2 modify due:")
|
||||
# Expected non zero exit-code
|
||||
self.assertEqual(code, 2)
|
||||
|
||||
@@ -96,13 +88,12 @@ class TestBug360AllowedChanges(BaseTestBug360):
|
||||
# Also do setUp from BaseTestBug360
|
||||
super(TestBug360AllowedChanges, self).setUp()
|
||||
|
||||
self.t(("add", "nonrecurring", "due:today"))
|
||||
self.t("add nonrecurring due:today")
|
||||
|
||||
def test_allow_modify_due_in_nonrecurring(self):
|
||||
"""Allow modifying due date in non recurring task"""
|
||||
# Retrieve the id of the non recurring task
|
||||
args = ("ls",)
|
||||
code, out, err = self.t(args)
|
||||
code, out, err = self.t("ls")
|
||||
|
||||
expected = "2 tasks"
|
||||
self.assertIn(expected, out)
|
||||
@@ -110,8 +101,7 @@ class TestBug360AllowedChanges(BaseTestBug360):
|
||||
# NOTE: raw python string r"" avoids having to escape backslashes
|
||||
id = re.search(r"(\d+)\s.+\snonrecurring", out).group(1)
|
||||
|
||||
args = (id, "modify", "due:")
|
||||
code, out, err = self.t(args)
|
||||
code, out, err = self.t((id, "modify", "due:"))
|
||||
|
||||
expected = "Modified 1 task."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
@@ -41,10 +41,10 @@ class TestBug425(TestCase):
|
||||
|
||||
def test_bug425(self):
|
||||
"""parser interpret 'in' in description"""
|
||||
self.t(("add", "Foo"))
|
||||
self.t(("1", "modify", "Bar in Bar"))
|
||||
self.t("add Foo")
|
||||
self.t("1 modify Bar in Bar")
|
||||
|
||||
code, out, err = self.t(("1", "ls"))
|
||||
code, out, err = self.t("1 ls")
|
||||
self.assertRegexpMatches(out, "1\s+Bar in Bar")
|
||||
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ class TestBug441(TestCase):
|
||||
def test_bad_colon_replacement(self):
|
||||
"""Substitution containing a colon"""
|
||||
|
||||
self.t(("add", "one two three"))
|
||||
self.t(("1", "modify", "/two/two:/"))
|
||||
self.t("add one two three")
|
||||
self.t("1 modify /two/two:/")
|
||||
|
||||
code, out, err = self.t(("ls",))
|
||||
code, out, err = self.t("ls")
|
||||
self.assertIn("one two: three", out)
|
||||
|
||||
|
||||
|
||||
@@ -53,14 +53,14 @@ class TestAnnotation(TestCase):
|
||||
"""Verify filterless annotation is trapped, declined"""
|
||||
self.t("add foo")
|
||||
|
||||
code, out, err = self.t.runError(("annotate", "bar"), input="no\n")
|
||||
code, out, err = self.t.runError("annotate bar", input="no\n")
|
||||
self.assertIn("Command prevented from running", err)
|
||||
self.assertNotIn("Command prevented from running", out)
|
||||
|
||||
def test_filterless_annotate(self):
|
||||
"""Verify filterless annotation is trapped, overridden"""
|
||||
self.t("add foo")
|
||||
code, out, err = self.t(("annotate", "bar"), input="yes\n")
|
||||
code, out, err = self.t("annotate bar", input="yes\n")
|
||||
|
||||
self.assertNotIn("Command prevented from running", err)
|
||||
self.assertNotIn("Command prevented from running", out)
|
||||
|
||||
@@ -44,12 +44,12 @@ class TestCLI(TestCase):
|
||||
|
||||
def test_quoted_args_remain_intact(self):
|
||||
"""Quoted arguments should remain unmolested."""
|
||||
self.t(("add", "'a/b'"))
|
||||
code, out, err = self.t(("_get", "1.description"))
|
||||
self.t("add 'a/b'")
|
||||
code, out, err = self.t("_get 1.description")
|
||||
self.assertIn("a/b", out)
|
||||
|
||||
self.t(("add", "'1-2'"))
|
||||
code, out, err = self.t(("_get", "2.description"))
|
||||
self.t("add '1-2'")
|
||||
code, out, err = self.t("_get 2.description")
|
||||
self.assertIn("1-2", out)
|
||||
|
||||
|
||||
|
||||
@@ -45,20 +45,20 @@ class TestAliasesCompletion(TestCase):
|
||||
|
||||
def test__aliases(self):
|
||||
"""samplealias in _aliases"""
|
||||
code, out, err = self.t(("_aliases",))
|
||||
code, out, err = self.t("_aliases")
|
||||
|
||||
self.assertIn("samplealias", out)
|
||||
|
||||
def test__commands(self):
|
||||
"""samplealias not in _commands"""
|
||||
code, out, err = self.t(("_commands",))
|
||||
code, out, err = self.t("_commands")
|
||||
|
||||
self.assertIn("information", out)
|
||||
self.assertNotIn("samplealias", out)
|
||||
|
||||
def test__zshcommands(self):
|
||||
"""samplealias not in _zshcommands"""
|
||||
code, out, err = self.t(("_zshcommands",))
|
||||
code, out, err = self.t("_zshcommands")
|
||||
|
||||
self.assertIn("information", out)
|
||||
self.assertNotIn("samplealias", out)
|
||||
|
||||
351
test/context.t
351
test/context.t
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -36,6 +36,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from basetest import Task, TestCase
|
||||
|
||||
|
||||
class ContextManagementTest(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
@@ -45,10 +46,9 @@ class ContextManagementTest(TestCase):
|
||||
Test simple context definition.
|
||||
"""
|
||||
|
||||
output = self.t(('context', 'define', 'work', 'project:Work'))[1]
|
||||
code, out, err = self.t('context define work project:Work')
|
||||
|
||||
# Assert successful output
|
||||
self.assertIn("Context 'work' defined.", output)
|
||||
self.assertIn("Context 'work' defined.", out)
|
||||
|
||||
# Assert the config contains context definition
|
||||
self.assertIn('context.work=project:Work\n', self.t.taskrc_content)
|
||||
@@ -62,11 +62,10 @@ class ContextManagementTest(TestCase):
|
||||
Test re-defining the context with the same definition.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
output = self.t(('context', 'define', 'work', 'project:Work'))[1]
|
||||
self.t('context define work project:Work')
|
||||
code, out, err = self.t('context define work project:Work')
|
||||
|
||||
# Assert successful output
|
||||
self.assertIn("Context 'work' defined.", output)
|
||||
self.assertIn("Context 'work' defined.", out)
|
||||
|
||||
# Assert the config contains context definition
|
||||
self.assertIn('context.work=project:Work\n', self.t.taskrc_content)
|
||||
@@ -80,11 +79,10 @@ class ContextManagementTest(TestCase):
|
||||
Test re-defining the context with different definition.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
output = self.t(('context', 'define', 'work', '+work'))[1]
|
||||
self.t('context define work project:Work')
|
||||
code, out, err = self.t('context define work +work')
|
||||
|
||||
# Assert successful output
|
||||
self.assertIn("Context 'work' defined.", output)
|
||||
self.assertIn("Context 'work' defined.", out)
|
||||
|
||||
# Assert the config does not contain the old context definition
|
||||
self.assertNotIn('context.work=project:Work\n', self.t.taskrc_content)
|
||||
@@ -101,11 +99,10 @@ class ContextManagementTest(TestCase):
|
||||
Test simple context deletion.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
output = self.t(('context', 'delete', 'work'))[1]
|
||||
self.t('context define work project:Work')
|
||||
code, out, err = self.t('context delete work')
|
||||
|
||||
# Assert correct output
|
||||
self.assertIn("Context 'work' deleted.", output)
|
||||
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))
|
||||
@@ -115,10 +112,9 @@ class ContextManagementTest(TestCase):
|
||||
Test deletion of undefined context.
|
||||
"""
|
||||
|
||||
output = self.t.runError(('context', 'delete', 'work'))[1]
|
||||
code, out, err = self.t.runError('context delete work')
|
||||
|
||||
# Assert correct output
|
||||
self.assertIn("Context 'work' not deleted.", output)
|
||||
self.assertIn("Context 'work' not 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))
|
||||
@@ -128,19 +124,18 @@ class ContextManagementTest(TestCase):
|
||||
Test that context is unset if its definition has been removed.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'work'))
|
||||
output = self.t(('context', 'delete', 'work'))[1]
|
||||
self.t('context define work project:Work')
|
||||
self.t('context work')
|
||||
code, out, err = self.t('context delete work')
|
||||
|
||||
# Assert correct output
|
||||
self.assertIn("Context 'work' deleted.", output)
|
||||
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))
|
||||
|
||||
# Aseert that the context is not set
|
||||
output = self.t(('context', 'show'))[1]
|
||||
self.assertIn('No context is currently applied.', output)
|
||||
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_list_active(self):
|
||||
@@ -148,30 +143,30 @@ class ContextManagementTest(TestCase):
|
||||
Test the 'context list' command.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t(('context', 'home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
self.t('context home')
|
||||
|
||||
output = self.t(('context', 'list'))[1]
|
||||
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
|
||||
self.assertEqual(len(filter(contains_work, output.splitlines())), 1)
|
||||
self.assertEqual(len(filter(contains_home, output.splitlines())), 1)
|
||||
self.assertEqual(len(filter(contains_work, out.splitlines())), 1)
|
||||
self.assertEqual(len(filter(contains_home, out.splitlines())), 1)
|
||||
|
||||
def test_context_initially_empty(self):
|
||||
"""
|
||||
Test that no context is set initially.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
output = self.t(('context', 'show'))[1]
|
||||
self.assertIn('No context is currently applied.', output)
|
||||
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):
|
||||
@@ -179,11 +174,11 @@ class ContextManagementTest(TestCase):
|
||||
Test simple context setting.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home home')
|
||||
|
||||
output = self.t(('context', 'home'))[1]
|
||||
self.assertIn("Context 'home' set.", output)
|
||||
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):
|
||||
@@ -191,12 +186,12 @@ class ContextManagementTest(TestCase):
|
||||
Test resetting the same context.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('context', 'home'))[1]
|
||||
self.assertIn("Context 'home' set.", output)
|
||||
self.t('context home')
|
||||
code, out, err = self.t('context home')
|
||||
self.assertIn("Context 'home' set.", out)
|
||||
|
||||
contains_home = lambda line: line == "context=home\n"
|
||||
self.assertEqual(len(filter(contains_home, self.t.taskrc_content)), 1)
|
||||
@@ -206,28 +201,28 @@ class ContextManagementTest(TestCase):
|
||||
Test changing the context.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
contains_home = lambda line: line == "context=home\n"
|
||||
contains_work = lambda line: line == "context=work\n"
|
||||
|
||||
# Switch to home context
|
||||
output = self.t(('context', 'home'))[1]
|
||||
self.assertIn("Context 'home' set.", output)
|
||||
code, out, err = self.t('context home')
|
||||
self.assertIn("Context 'home' set.", out)
|
||||
|
||||
self.assertEqual(len(filter(contains_home, self.t.taskrc_content)), 1)
|
||||
|
||||
# Switch to work context
|
||||
output = self.t(('context', 'work'))[1]
|
||||
self.assertIn("Context 'work' set.", output)
|
||||
code, out, err = self.t('context work')
|
||||
self.assertIn("Context 'work' set.", out)
|
||||
|
||||
self.assertNotIn("context=home\n", self.t.taskrc_content)
|
||||
self.assertEqual(len(filter(contains_work, self.t.taskrc_content)), 1)
|
||||
|
||||
# Switch back to home context
|
||||
output = self.t(('context', 'home'))[1]
|
||||
self.assertIn("Context 'home' set.", output)
|
||||
code, out, err = self.t('context home')
|
||||
self.assertIn("Context 'home' set.", out)
|
||||
|
||||
self.assertNotIn("context=work\n", self.t.taskrc_content)
|
||||
self.assertEqual(len(filter(contains_home, self.t.taskrc_content)), 1)
|
||||
@@ -237,103 +232,103 @@ class ContextManagementTest(TestCase):
|
||||
Test removing the context.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('context', 'none'))[1]
|
||||
self.t('context home')
|
||||
code, out, err = self.t('context none')
|
||||
|
||||
# Assert expected output.
|
||||
self.assertIn("Context unset.", 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))
|
||||
|
||||
# Assert no context showing up using show subcommand
|
||||
output = self.t(('context', 'show'))[1]
|
||||
self.assertIn("No context is currently applied.", output)
|
||||
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'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
# 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
|
||||
output = self.t(('context', 'none'))[1]
|
||||
code, out, err = self.t('context none')
|
||||
|
||||
# Assert expected output.
|
||||
self.assertIn("Context unset.", 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))
|
||||
|
||||
# Assert no context showing up using show subcommand
|
||||
output = self.t(('context', 'show'))[1]
|
||||
self.assertIn("No context is currently applied.", output)
|
||||
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'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
output = self.t.runError(('context', 'none'))[1]
|
||||
code, out, err = self.t.runError('context none')
|
||||
|
||||
# Assert expected output.
|
||||
self.assertIn("Context not unset.", output)
|
||||
self.assertIn("Context not 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))
|
||||
|
||||
# Assert no context showing up using show subcommand
|
||||
output = self.t(('context', 'show'))[1]
|
||||
self.assertIn("No context is currently applied.", output)
|
||||
code, out, err = self.t('context show')
|
||||
self.assertIn("No context is currently applied.", out)
|
||||
|
||||
def test_context_completion(self):
|
||||
def test_context(self):
|
||||
"""
|
||||
Test the _context command.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
output = self.t(('_context',))[1]
|
||||
code, out, err = self.t('_context')
|
||||
|
||||
# Assert expected output.
|
||||
self.assertIn("work", output.splitlines())
|
||||
self.assertIn("home", output.splitlines())
|
||||
self.assertEqual(len(output.splitlines()), 2)
|
||||
self.assertIn("work", out.splitlines())
|
||||
self.assertIn("home", out.splitlines())
|
||||
self.assertEqual(len(out.splitlines()), 2)
|
||||
|
||||
def test_context_completion(self):
|
||||
"""
|
||||
Test the _context command with some context set.
|
||||
"""
|
||||
|
||||
self.t(('context', 'define', 'work', 'project:Work'))
|
||||
self.t(('context', 'define', 'home', '+home'))
|
||||
self.t('context define work project:Work')
|
||||
self.t('context define home +home')
|
||||
|
||||
# Activete some context
|
||||
self.t(('context', 'work'))
|
||||
self.t('context work')
|
||||
|
||||
output = self.t(('_context',))[1]
|
||||
code, out, err = self.t('_context')
|
||||
|
||||
# Assert expected output.
|
||||
self.assertIn("work", output.splitlines())
|
||||
self.assertIn("home", output.splitlines())
|
||||
self.assertEqual(len(output.splitlines()), 2)
|
||||
self.assertIn("work", out.splitlines())
|
||||
self.assertIn("home", out.splitlines())
|
||||
self.assertEqual(len(out.splitlines()), 2)
|
||||
|
||||
|
||||
class ContextEvaluationTest(TestCase):
|
||||
@@ -341,105 +336,105 @@ class ContextEvaluationTest(TestCase):
|
||||
self.t = Task()
|
||||
|
||||
# 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"))
|
||||
self.t(('add', '+home', "home task"))
|
||||
self.t(('add', 'project:Work', 'due:today', 'work today task'))
|
||||
self.t(('add', '+home', 'due:today', 'home today task'))
|
||||
self.t('add project:Work "work task"')
|
||||
self.t('add +home "home task"')
|
||||
self.t('add project:Work due:today "work today task"')
|
||||
self.t('add +home due:today "home today task"')
|
||||
|
||||
def test_context_evaluation(self):
|
||||
"""
|
||||
Test the context applied with report list command.
|
||||
"""
|
||||
|
||||
output = self.t(('list',))[1]
|
||||
code, out, err = self.t('list')
|
||||
|
||||
# Assert all the tasks are present in the output
|
||||
self.assertIn("work task", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
# Set the home context and rerun the report
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('list',))[1]
|
||||
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", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertNotIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertNotIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
def test_context_evaluation_switching(self):
|
||||
"""
|
||||
Test swtiching context using the list report.
|
||||
"""
|
||||
|
||||
output = self.t(('list',))[1]
|
||||
code, out, err = self.t('list')
|
||||
|
||||
# Assert all the tasks are present in the output
|
||||
self.assertIn("work task", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
# Set the home context and rerun the report
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('list',))[1]
|
||||
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", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertNotIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertNotIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
# Set the work context and rerun the report
|
||||
self.t(('context', 'work'))
|
||||
output = self.t(('list',))[1]
|
||||
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", output)
|
||||
self.assertNotIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertNotIn("home today task", output)
|
||||
self.assertIn("work task", out)
|
||||
self.assertNotIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertNotIn("home today task", out)
|
||||
|
||||
# Set the today context and rerun the report
|
||||
self.t(('context', 'today'))
|
||||
output = self.t(('list',))[1]
|
||||
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", output)
|
||||
self.assertNotIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertNotIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
def test_context_evaluation_unset(self):
|
||||
"""
|
||||
Test unsetting context with report list command.
|
||||
"""
|
||||
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('list',))[1]
|
||||
self.t('context home')
|
||||
code, out, err = self.t('list')
|
||||
|
||||
# Assert all the tasks home tagged tasks are present
|
||||
self.assertNotIn("work task", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertNotIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertNotIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
# Set the context to none
|
||||
self.t(('context', 'none'))
|
||||
output = self.t(('list',))[1]
|
||||
self.t('context none')
|
||||
code, out, err = self.t('list')
|
||||
|
||||
# Assert all the tasks are present in the output
|
||||
self.assertIn("work task", output)
|
||||
self.assertIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertIn("work task", out)
|
||||
self.assertIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
def test_context_evaluation_with_user_filters(self):
|
||||
"""
|
||||
@@ -448,24 +443,24 @@ class ContextEvaluationTest(TestCase):
|
||||
"""
|
||||
|
||||
# Set the home context
|
||||
self.t(('context', 'home'))
|
||||
output = self.t(('list', 'due:today'))[1]
|
||||
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", output)
|
||||
self.assertNotIn("home task", output)
|
||||
self.assertNotIn("work today task", output)
|
||||
self.assertIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertNotIn("home task", out)
|
||||
self.assertNotIn("work today task", out)
|
||||
self.assertIn("home today task", out)
|
||||
|
||||
# Set the work context and rerun the report
|
||||
self.t(('context', 'work'))
|
||||
output = self.t(('list', 'due:today'))[1]
|
||||
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", output)
|
||||
self.assertNotIn("home task", output)
|
||||
self.assertIn("work today task", output)
|
||||
self.assertNotIn("home today task", output)
|
||||
self.assertNotIn("work task", out)
|
||||
self.assertNotIn("home task", out)
|
||||
self.assertIn("work today task", out)
|
||||
self.assertNotIn("home today task", out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
12
test/count.t
12
test/count.t
@@ -41,17 +41,17 @@ class TestCount(TestCase):
|
||||
def setUpClass(cls):
|
||||
"""Executed once before any test in the class"""
|
||||
cls.t = Task()
|
||||
cls.t(("add", "one"))
|
||||
cls.t(("log", "two"))
|
||||
cls.t(("add", "three"))
|
||||
cls.t(("1", "delete"))
|
||||
cls.t("add one")
|
||||
cls.t("log two")
|
||||
cls.t("add three")
|
||||
cls.t("1 delete")
|
||||
|
||||
def test_count_unfiltered(self):
|
||||
code, out, err = self.t(("count",))
|
||||
code, out, err = self.t("count")
|
||||
self.assertEqual(out.strip(), "3")
|
||||
|
||||
def test_count_filtered(self):
|
||||
code, out, err = self.t(("status:deleted", "count"))
|
||||
code, out, err = self.t("status:deleted count")
|
||||
self.assertEqual(out.strip(), "1")
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestCustomConfig(TestCase):
|
||||
|
||||
Reported in bug 1065
|
||||
"""
|
||||
code, out, err = self.t(("show", "alias"))
|
||||
code, out, err = self.t("show alias")
|
||||
|
||||
self.assertIn(self.DIFFER_MSG, out)
|
||||
self.assertNotIn(self.NOT_RECOG_MSG, out)
|
||||
@@ -62,7 +62,7 @@ class TestCustomConfig(TestCase):
|
||||
|
||||
Reported in bug 1065
|
||||
"""
|
||||
code, out, err = self.t(("show",))
|
||||
code, out, err = self.t("show")
|
||||
|
||||
self.assertIn(self.DIFFER_MSG, out)
|
||||
self.assertIn(self.NOT_RECOG_MSG, out)
|
||||
@@ -72,7 +72,7 @@ class TestCustomConfig(TestCase):
|
||||
|
||||
Reported in bug 1065
|
||||
"""
|
||||
code, out, err = self.t(("show", "report.overdue"))
|
||||
code, out, err = self.t("show report.overdue")
|
||||
|
||||
self.assertNotIn(self.DIFFER_MSG, out)
|
||||
self.assertNotIn(self.NOT_RECOG_MSG, out)
|
||||
@@ -82,7 +82,7 @@ class TestCustomConfig(TestCase):
|
||||
|
||||
Reported in bug 1065
|
||||
"""
|
||||
code, out, err = self.t(("show", "notrecog"))
|
||||
code, out, err = self.t("show notrecog")
|
||||
|
||||
self.assertNotIn(self.DIFFER_MSG, out)
|
||||
self.assertIn(self.NOT_RECOG_MSG, out)
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -45,10 +45,10 @@ class BaseDateTimeNegativeTest(TestCase):
|
||||
self.t = Task()
|
||||
|
||||
def assertInvalidDatetimeFormat(self, value):
|
||||
self.t.runError(('add', 'due:%s' % value, 'test1'))
|
||||
self.t.runError(('add', 'scheduled:%s' % value, 'test2'))
|
||||
self.t.runError(('add', 'wait:%s' % value, 'test3'))
|
||||
self.t.runError(('add', 'until:%s' % value, 'test4'))
|
||||
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):
|
||||
@@ -390,7 +390,7 @@ class TestIncorrectTime(BaseDateTimeNegativeTest):
|
||||
# longer considered an offset, and is instead considered to be the addition
|
||||
# or subtraction of two times. Although valid, the tests are not
|
||||
# datetime-negative.t tests.
|
||||
#
|
||||
#
|
||||
# Tests were:
|
||||
# 12:12:12-13:00
|
||||
# 12:12:12-24:00
|
||||
|
||||
@@ -41,17 +41,17 @@ 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"""
|
||||
code, out, err = self.t(())
|
||||
code, out, err = self.t()
|
||||
self.assertIn("task list]", err)
|
||||
|
||||
def test_info_command(self):
|
||||
"""info command"""
|
||||
code, out, err = self.t(('1'))
|
||||
code, out, err = self.t('1')
|
||||
self.assertRegexpMatches(out, 'Description\s+one')
|
||||
|
||||
|
||||
|
||||
@@ -48,21 +48,21 @@ class TestDiagColor(TestCase):
|
||||
|
||||
def test_diag_color(self):
|
||||
"""Task diag detects terminal as color compatible"""
|
||||
code, out, err = self.t(("diag",))
|
||||
code, out, err = self.t("diag")
|
||||
|
||||
expected = "\x1b[1m"
|
||||
self.assertNotIn(expected, out)
|
||||
|
||||
def test_diag_nocolor(self):
|
||||
"""Task diag respects rc:color=off and disables color"""
|
||||
code, out, err = self.t(("rc.color:off", "diag"))
|
||||
code, out, err = self.t("rc.color:off diag")
|
||||
|
||||
expected = "\x1b[1m"
|
||||
self.assertNotIn(expected, out)
|
||||
|
||||
def test_diag_force_color(self):
|
||||
"""Task diag respects rc:_forcecolor=on and forces color"""
|
||||
code, out, err = self.t(("rc._forcecolor:on", "diag"))
|
||||
code, out, err = self.t("rc._forcecolor:on diag")
|
||||
|
||||
expected = "\x1b[1m"
|
||||
self.assertIn(expected, out)
|
||||
|
||||
60
test/dom.t
60
test/dom.t
@@ -40,144 +40,144 @@ class TestDOM(TestCase):
|
||||
def setUpClass(cls):
|
||||
cls.t = Task()
|
||||
cls.t.config("dateformat", "YMD")
|
||||
cls.t(("add", "one", "due:20110901"))
|
||||
cls.t(("add", "two", "due:1.due"))
|
||||
cls.t(("add", "three", "due:20110901", "wait:due", "+tag1", "+tag2"))
|
||||
cls.t(("3", "annotate", "note"))
|
||||
cls.t("add one due:20110901")
|
||||
cls.t("add two due:1.due")
|
||||
cls.t("add three due:20110901 wait:due +tag1 +tag2")
|
||||
cls.t("3 annotate note")
|
||||
|
||||
def test_dom_task_ref(self):
|
||||
""" DOM reference to other task """
|
||||
code, out, err = self.t(("_get", "2.due"))
|
||||
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 """
|
||||
code, out, err = self.t(("_get", "3.wait"))
|
||||
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 """
|
||||
code, out, err = self.t(("_get", "1.uuid"))
|
||||
code, out, err = self.t("_get 1.uuid")
|
||||
uuid = out.strip()
|
||||
code, out, err = self.t(("_get", uuid + ".id"))
|
||||
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 """
|
||||
code, out, err = self.t(("_get", "4.description"))
|
||||
code, out, err = self.t("_get 4.description")
|
||||
self.assertEqual("\n", out)
|
||||
|
||||
def test_dom_tags(self):
|
||||
""" DOM 3.tags """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "3.due.week"))
|
||||
code, out, err = self.t("_get 3.due.week")
|
||||
self.assertEqual("36\n", out)
|
||||
|
||||
def test_dom_due_weekday(self):
|
||||
""" DOM 3.due.weekday """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "3.due.second"))
|
||||
code, out, err = self.t("_get 3.due.second")
|
||||
self.assertEqual("0\n", out)
|
||||
|
||||
def test_dom_annotation_entry(self):
|
||||
""" DOM 3.annotations.1.entry """
|
||||
code, out, err = self.t(("_get", "3.annotations.1.entry"))
|
||||
code, out, err = self.t("_get 3.annotations.1.entry")
|
||||
self.assertRegexpMatches(out, r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}")
|
||||
|
||||
def test_dom_annotation_description(self):
|
||||
""" DOM 3.annotations.1.description """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "system.version"))
|
||||
code, out, err = self.t("_get system.version")
|
||||
self.assertEqual(code, 0)
|
||||
self.assertRegexpMatches(out, r"\d\.\d+\.\d+")
|
||||
|
||||
def test_dom_system_os(self):
|
||||
""" DOM system.os """
|
||||
code, out, err = self.t(("_get", "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_context_program(self):
|
||||
""" DOM context.program """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t(("_get", "context.width"))
|
||||
code, out, err = self.t("_get context.width")
|
||||
self.assertEqual(code, 0)
|
||||
self.assertRegexpMatches(out, r"\d+")
|
||||
|
||||
def test_dom_context_height(self):
|
||||
""" DOM context.height """
|
||||
code, out, err = self.t(("_get", "context.height"))
|
||||
code, out, err = self.t("_get context.height")
|
||||
self.assertEqual(code, 0)
|
||||
self.assertRegexpMatches(out, r"\d+")
|
||||
|
||||
def test_dom_rc_name(self):
|
||||
""" DOM rc.dateformat """
|
||||
code, out, err = self.t(("_get", "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 """
|
||||
code, out, err = self.t.runError(("_get", "rc.missing"))
|
||||
code, out, err = self.t.runError("_get rc.missing")
|
||||
self.assertEqual(code, 1)
|
||||
|
||||
|
||||
|
||||
28
test/due.t
28
test/due.t
@@ -58,12 +58,12 @@ class TestDue(TestCase):
|
||||
self.just = timestamp_without_leading_zeros(just)
|
||||
self.almost = timestamp_without_leading_zeros(almost)
|
||||
|
||||
self.t(("add", "one", "due:{0}".format(self.just)))
|
||||
self.t(("add", "two", "due:{0}".format(self.almost)))
|
||||
self.t("add one due:{0}".format(self.just))
|
||||
self.t("add two due:{0}".format(self.almost))
|
||||
|
||||
def test_due(self):
|
||||
"""due tasks displayed correctly"""
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertRegexpMatches(out, "\033\[31m.+{0}.+\033\[0m".format(self.just))
|
||||
self.assertRegexpMatches(out, "\s+{0}\s+".format(self.almost))
|
||||
|
||||
@@ -85,17 +85,17 @@ class TestBug418(TestCase):
|
||||
|
||||
def test_bug_418(self):
|
||||
"""due.before:eow bad with dateformat 'MD'"""
|
||||
self.t(("add", "one", "due:6/28/2010"))
|
||||
self.t(("add", "two", "due:6/29/2010"))
|
||||
self.t(("add", "three", "due:6/30/2010"))
|
||||
self.t(("add", "four", "due:7/1/2010"))
|
||||
self.t(("add", "five", "due:7/2/2010"))
|
||||
self.t(("add", "six", "due:7/3/2010"))
|
||||
self.t(("add", "seven", "due:7/4/2010"))
|
||||
self.t(("add", "eight", "due:7/5/2010"))
|
||||
self.t(("add", "nine", "due:7/6/2010"))
|
||||
self.t("add one due:6/28/2010")
|
||||
self.t("add two due:6/29/2010")
|
||||
self.t("add three due:6/30/2010")
|
||||
self.t("add four due:7/1/2010")
|
||||
self.t("add five due:7/2/2010")
|
||||
self.t("add six due:7/3/2010")
|
||||
self.t("add seven due:7/4/2010")
|
||||
self.t("add eight due:7/5/2010")
|
||||
self.t("add nine due:7/6/2010")
|
||||
|
||||
code, out, err = self.t(("foo",))
|
||||
code, out, err = self.t("foo")
|
||||
self.assertIn("one", out)
|
||||
self.assertIn("two", out)
|
||||
self.assertIn("three", out)
|
||||
@@ -106,7 +106,7 @@ class TestBug418(TestCase):
|
||||
self.assertIn("eight", out)
|
||||
self.assertIn("nine", out)
|
||||
|
||||
code, out, err = self.t(("foo", "due.before:7/2/2010"))
|
||||
code, out, err = self.t("foo due.before:7/2/2010")
|
||||
self.assertIn("one", out)
|
||||
self.assertIn("two", out)
|
||||
self.assertIn("three", out)
|
||||
|
||||
10
test/edit.t
10
test/edit.t
@@ -48,13 +48,13 @@ class TestTaskEdit(TestCase):
|
||||
def test_newline_description_edit(self):
|
||||
"""task edit - parsing entries containing multiline descriptions"""
|
||||
|
||||
self.t(("add", "Hello\nLost"))
|
||||
self.t('add "Hello\nLost"')
|
||||
|
||||
code, out, err = self.t()
|
||||
self.assertIn("Lost", out)
|
||||
|
||||
# Newlines may not be correctly parsed
|
||||
code, out, err = self.t(("1", "edit"))
|
||||
code, out, err = self.t("1 edit")
|
||||
|
||||
code, out, err = self.t()
|
||||
self.assertIn("Lost", out)
|
||||
@@ -62,14 +62,14 @@ class TestTaskEdit(TestCase):
|
||||
def test_newline_annotation_edit(self):
|
||||
"""task edit - parsing entries containing multiline annotations"""
|
||||
|
||||
self.t(("add", "Hello"))
|
||||
self.t(("1", "annotate", "Something\nLost"))
|
||||
self.t("add Hello")
|
||||
self.t('1 annotate "Something\nLost"')
|
||||
|
||||
code, out, err = self.t()
|
||||
self.assertIn("Lost", out)
|
||||
|
||||
# Newlines may not be correctly parsed
|
||||
code, out, err = self.t(("1", "edit"))
|
||||
code, out, err = self.t("1 edit")
|
||||
|
||||
code, out, err = self.t()
|
||||
self.assertIn("Lost", out)
|
||||
|
||||
@@ -42,20 +42,20 @@ class TestUtf8(TestCase):
|
||||
|
||||
def test_utf8_tags(self):
|
||||
"""Correct handling of UTF8 characters"""
|
||||
self.t(("add", "one", "+osobní"))
|
||||
self.t("add one +osobní")
|
||||
|
||||
code, out, err = self.t(("list", "+osobní"))
|
||||
code, out, err = self.t("list +osobní")
|
||||
self.assertIn("one", out)
|
||||
|
||||
code, out, err = self.t.runError(("list", "-osobní"))
|
||||
code, out, err = self.t.runError("list -osobní")
|
||||
self.assertNotIn("one", out)
|
||||
|
||||
self.t(("add", "two", "+föo"))
|
||||
code, out, err = self.t(("list", "+föo"))
|
||||
self.t("add two +föo")
|
||||
code, out, err = self.t("list +föo")
|
||||
self.assertIn("two", out)
|
||||
self.assertNotIn("one", out)
|
||||
|
||||
code, out, err = self.t(("list", "-föo"))
|
||||
code, out, err = self.t("list -föo")
|
||||
self.assertNotIn("two", out)
|
||||
self.assertIn("one", out)
|
||||
|
||||
@@ -66,9 +66,9 @@ class TestUtf8(TestCase):
|
||||
self.t.config("print.empty.columns", "no")
|
||||
|
||||
self.t(("add", "abc", "pro:Bar\u263a"))
|
||||
self.t(("add", "def", "pro:Foo"))
|
||||
self.t("add def pro:Foo")
|
||||
|
||||
code, out, err = self.t(("ls",))
|
||||
code, out, err = self.t("ls")
|
||||
|
||||
expected = re.compile("\S\s{4}abc", re.MULTILINE)
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
@@ -47,9 +47,9 @@ class TestEnpassantMultiple(BaseTestEnpassant):
|
||||
def setUp(self):
|
||||
super(TestEnpassantMultiple, self).setUp()
|
||||
|
||||
self.t(("add", "foo"))
|
||||
self.t(("add", "foo", "bar"))
|
||||
self.t(("add", "baz foo baz"))
|
||||
self.t("add foo")
|
||||
self.t("add foo bar")
|
||||
self.t("add baz foo baz")
|
||||
|
||||
def validate_info(self, id, desc):
|
||||
code, out, err = self.t((id, "info"))
|
||||
@@ -73,7 +73,7 @@ class TestEnpassantMultiple(BaseTestEnpassant):
|
||||
|
||||
def test_multiple(self):
|
||||
"Test enpassant in multiple tasks and with multiple changes at once"
|
||||
self.t(("1,2,3", "done", "/foo/FOO/", "pri:H", "+tag"), input="all\n")
|
||||
self.t("1,2,3 done /foo/FOO/ pri:H +tag", input="all\n")
|
||||
|
||||
self.validate_info("1", desc="FOO")
|
||||
self.validate_info("2", desc="FOO bar")
|
||||
@@ -84,35 +84,35 @@ class TestEnpassant(BaseTestEnpassant):
|
||||
def setUp(self):
|
||||
super(TestEnpassant, self).setUp()
|
||||
|
||||
self.t(("add", "one"))
|
||||
self.t(("add", "two"))
|
||||
self.t(("add", "three"))
|
||||
self.t(("add", "four"))
|
||||
self.t(("add", "five"))
|
||||
self.t("add one")
|
||||
self.t("add two")
|
||||
self.t("add three")
|
||||
self.t("add four")
|
||||
self.t("add five")
|
||||
|
||||
def perform_action(self, action):
|
||||
self.t(("1", action, "oneanno"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertRegexpMatches(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"))
|
||||
code, out, err = self.t("2 info")
|
||||
self.assertRegexpMatches(out, "Description +TWO",
|
||||
msg="{0} enpassant modify".format(action))
|
||||
|
||||
self.t(("3", action, "+threetag"))
|
||||
code, out, err = self.t(("3", "info"))
|
||||
code, out, err = self.t("3 info")
|
||||
self.assertRegexpMatches(out, "Tags +threetag",
|
||||
msg="{0} enpassant tag".format(action))
|
||||
|
||||
self.t(("4", action, "pri:H"))
|
||||
code, out, err = self.t(("4", "info"))
|
||||
code, out, err = self.t("4 info")
|
||||
self.assertRegexpMatches(out, "Priority +H",
|
||||
msg="{0} enpassant priority".format(action))
|
||||
|
||||
self.t(("5", action, "pro:PROJ"))
|
||||
code, out, err = self.t(("5", "info"))
|
||||
code, out, err = self.t("5 info")
|
||||
self.assertRegexpMatches(out, "Project +PROJ",
|
||||
msg="{0} enpassant project".format(action))
|
||||
|
||||
@@ -130,7 +130,7 @@ class TestEnpassant(BaseTestEnpassant):
|
||||
|
||||
def test_stop(self):
|
||||
"""Test 'stop' with en-passant changes"""
|
||||
self.t(("1-5", "start"), input="all\n")
|
||||
self.t("1-5 start", input="all\n")
|
||||
|
||||
self.perform_action("stop")
|
||||
|
||||
|
||||
@@ -45,10 +45,11 @@ 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, identifier):
|
||||
return json.loads(self.t((str(identifier), 'rc.json.array=off', 'export'))[1].strip())
|
||||
def export(self, id):
|
||||
code, out, err = self.t(("{0}".format(id), "rc.json.array=off", "export"))
|
||||
return json.loads(out.strip())
|
||||
|
||||
def assertType(self, value, type):
|
||||
self.assertEqual(isinstance(value, type), True)
|
||||
@@ -102,48 +103,48 @@ class TestExportCommand(TestCase):
|
||||
self.assertString(self.export(1)['description'], "test")
|
||||
|
||||
def test_export_start(self):
|
||||
self.t(('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.t('1 done +workaround')
|
||||
self.assertTimestamp(self.export('+workaround')['end'])
|
||||
|
||||
def test_export_due(self):
|
||||
self.t(('1', 'modify', 'due:today'))
|
||||
self.t('1 modify due:today')
|
||||
self.assertTimestamp(self.export(1)['due'])
|
||||
|
||||
def test_export_wait(self):
|
||||
self.t(('1', 'modify', 'wait:tomorrow'))
|
||||
self.t('1 modify wait:tomorrow')
|
||||
self.assertTimestamp(self.export(1)['wait'])
|
||||
|
||||
def test_export_modified(self):
|
||||
self.assertTimestamp(self.export(1)['modified'])
|
||||
|
||||
def test_export_scheduled(self):
|
||||
self.t(('1', 'modify', 'schedule:tomorrow'))
|
||||
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.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.t('1 modify project:Home')
|
||||
self.assertString(self.export(1)['project'], "Home")
|
||||
|
||||
def test_export_priority(self):
|
||||
self.t(('1', 'modify', '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('1 modify depends:2,3')
|
||||
|
||||
values = self.export(1)['depends']
|
||||
self.assertString(values)
|
||||
@@ -152,29 +153,29 @@ 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'])
|
||||
|
||||
def test_export_numeric_uda(self):
|
||||
self.t.config('uda.estimate.type', 'numeric')
|
||||
self.t(('add', 'estimate:42', 'test numeric uda'))
|
||||
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.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.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.t('add estimate:month test duration uda')
|
||||
self.assertString(self.export('2')['estimate'], 'month')
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -50,16 +50,16 @@ class TestDefaultProject(TestCase):
|
||||
"""
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("add", "foobar", "project:garden"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar project:garden")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
|
||||
expected = "Project\s+garden"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
self.t(("1", "modify", "project:"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("1 modify project:")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
self.assertNotRegexpMatches(out, expected)
|
||||
@@ -71,8 +71,8 @@ class TestDefaultProject(TestCase):
|
||||
"""default.project applied when no project is specified"""
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("add", "foobar"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
|
||||
@@ -83,7 +83,7 @@ class TestDefaultProject(TestCase):
|
||||
"""no project applied when default.project is overridden"""
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("add", "foobar", "rc.default.project="))
|
||||
self.t("add foobar rc.default.project=")
|
||||
code, out, err = self.t("1", "info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
@@ -91,38 +91,38 @@ class TestDefaultProject(TestCase):
|
||||
|
||||
def test_without_default_project(self):
|
||||
"""no project applied when default.project is blank"""
|
||||
self.t(("add", "foobar"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
self.assertNotIn("Project", out)
|
||||
|
||||
def test_modify_default_project(self):
|
||||
"""default.project is not applied when modifying a task"""
|
||||
self.t(("add", "foobar"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
self.assertNotIn("Project", out)
|
||||
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("1", "modify", "+tag"))
|
||||
self.t("1 modify +tag")
|
||||
code, out, err = self.t("1", "info")
|
||||
self.assertNotIn("Project", out)
|
||||
|
||||
def test_annotate_default_project(self):
|
||||
"""default.project is not applied when annotating a task"""
|
||||
self.t(("add", "foobar"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
self.assertNotIn("Project", out)
|
||||
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("1", "annotate", "Hello"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("1 annotate Hello")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Description\s+foobar\n[0-9-: ]+ Hello"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
@@ -133,16 +133,16 @@ class TestDefaultProject(TestCase):
|
||||
# Allow keeping track of time spent on task
|
||||
self.t.config("journal.time", "yes")
|
||||
|
||||
self.t(("add", "foobar"))
|
||||
code, out, err = self.t("1", "info")
|
||||
self.t("add foobar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
self.assertNotIn("Project", out)
|
||||
|
||||
self.set_default_project()
|
||||
|
||||
self.t(("1", "start"))
|
||||
self.t(("1", "stop"))
|
||||
self.t("1 start")
|
||||
self.t("1 stop")
|
||||
code, out, err = self.t("1", "info")
|
||||
|
||||
self.assertIn("foobar", out)
|
||||
@@ -153,9 +153,9 @@ 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"))
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn(DESC, out)
|
||||
self.assertRegexpMatches(out, "Status\s+Recurring") # is a parent task
|
||||
@@ -165,7 +165,7 @@ class TestDefaultProject(TestCase):
|
||||
|
||||
self.t() # Ensure creation of recurring children
|
||||
# Try to figure out the ID of last created task
|
||||
code, out, err = self.t(("count",))
|
||||
code, out, err = self.t("count")
|
||||
|
||||
# Will fail if some other message is printed as part of "count"
|
||||
id = out.split()[-1]
|
||||
@@ -189,7 +189,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)
|
||||
@@ -211,7 +211,7 @@ class TestDefaultProject(TestCase):
|
||||
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)
|
||||
@@ -243,7 +243,7 @@ class ServerTestDefaultProject(ServerTestCase):
|
||||
# NOTE - reported on TW-1287
|
||||
desc = "Testing task"
|
||||
self.t1(("add", desc))
|
||||
self.t1(("sync",))
|
||||
self.t1("sync")
|
||||
|
||||
code, out, err = self.t1()
|
||||
|
||||
@@ -252,18 +252,18 @@ class ServerTestDefaultProject(ServerTestCase):
|
||||
# Testing scenario - default.project is applied on task arrival
|
||||
proj2 = "Client2"
|
||||
self.t2.config("default.project", proj2)
|
||||
self.t2(("sync",))
|
||||
self.t2("sync")
|
||||
|
||||
code, out, err = self.t2()
|
||||
self.assertIn(desc, out)
|
||||
self.assertNotIn(proj2, out)
|
||||
|
||||
self.t2(("sync",))
|
||||
self.t2("sync")
|
||||
|
||||
# Testing scenario - default.project is applied on task delivery
|
||||
proj3 = "Client3"
|
||||
self.t3.config("default.project", proj3)
|
||||
self.t3(("sync",))
|
||||
self.t3("sync")
|
||||
|
||||
code, out, err = self.t3()
|
||||
self.assertIn(desc, out)
|
||||
|
||||
@@ -42,13 +42,13 @@ class TestRecurrenceProblems(TestCase):
|
||||
"""Removing due from a recurring task causes date wrapping"""
|
||||
# Originally bug.327.t
|
||||
|
||||
self.t(("add", "foo", "recur:yearly", "due:eoy"))
|
||||
self.t(("list",)) # Trigger garbage collection
|
||||
self.t("add foo recur:yearly due:eoy")
|
||||
self.t("list") # Trigger garbage collection
|
||||
|
||||
code, out, err = self.t.runError(("2", "modify", "due:"))
|
||||
code, out, err = self.t.runError("2 modify due:")
|
||||
self.assertIn("cannot remove the due date from a recurring task", err)
|
||||
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
|
||||
self.assertIn("\n1 task", out)
|
||||
self.assertNotIn("1969", out)
|
||||
@@ -59,8 +59,8 @@ class TestRecurrenceProblems(TestCase):
|
||||
|
||||
self.t.config("dateformat.info", "m/d/Y")
|
||||
|
||||
self.t(("add", "foo", "due:today", "recur:yearly", "until:eom"))
|
||||
code, out, err = self.t(("info", "1"))
|
||||
self.t("add foo due:today recur:yearly until:eom")
|
||||
code, out, err = self.t("info 1")
|
||||
|
||||
self.assertNotRegexpMatches(out, "Until\s+\d{10}")
|
||||
self.assertRegexpMatches(out, "Until\s+\d+\/\d+\/\d{4}")
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -33,6 +33,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from basetest import Task, TestCase
|
||||
|
||||
|
||||
class TestEmptyFilter(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
@@ -40,19 +41,19 @@ class TestEmptyFilter(TestCase):
|
||||
def test_empty_filter_warning(self):
|
||||
"""Modify tasks with no filter."""
|
||||
|
||||
self.t(("add", "foo"))
|
||||
self.t(("add", "bar"))
|
||||
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):
|
||||
"""Modify tasks with no filter, and disallowed confirmation."""
|
||||
|
||||
self.t(("add", "foo"))
|
||||
self.t(("add", "bar"))
|
||||
self.t("add foo")
|
||||
self.t("add bar")
|
||||
|
||||
code, out, err = self.t.runError(("modify", "rc.allow.empty.filter=no", "priority:H"))
|
||||
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)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -42,18 +42,18 @@ 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:bazuno', 'seven bar foo'))
|
||||
cls.t(('add', 'project:bazdos', 'eight bar 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',))
|
||||
code, out, err = self.t('list')
|
||||
self.assertIn('one', out)
|
||||
self.assertIn('two', out)
|
||||
self.assertIn('three', out)
|
||||
@@ -65,7 +65,7 @@ class TestFilterPrefix(TestCase):
|
||||
|
||||
def test_list_project_foo(self):
|
||||
"""Filter on project name."""
|
||||
code, out, err = self.t(('list', 'project:foo'))
|
||||
code, out, err = self.t('list project:foo')
|
||||
self.assertIn('one', out)
|
||||
self.assertIn('two', out)
|
||||
self.assertIn('three', out)
|
||||
@@ -77,7 +77,7 @@ class TestFilterPrefix(TestCase):
|
||||
|
||||
def test_list_project_not_foo(self):
|
||||
"""Filter on not project name."""
|
||||
code, out, err = self.t(('list', 'project.not:foo'))
|
||||
code, out, err = self.t('list project.not:foo')
|
||||
self.assertIn('one', out)
|
||||
self.assertIn('two', out)
|
||||
self.assertIn('three', out)
|
||||
@@ -89,7 +89,7 @@ class TestFilterPrefix(TestCase):
|
||||
|
||||
def test_list_project_startswith_bar(self):
|
||||
"""Filter on project name start."""
|
||||
code, out, err = self.t(('list', 'project.startswith:bar'))
|
||||
code, out, err = self.t('list project.startswith:bar')
|
||||
self.assertNotIn('one', out)
|
||||
self.assertNotIn('two', out)
|
||||
self.assertNotIn('three', out)
|
||||
@@ -101,7 +101,7 @@ class TestFilterPrefix(TestCase):
|
||||
|
||||
def test_list_project_ba(self):
|
||||
"""Filter on project partial match."""
|
||||
code, out, err = self.t(('list', 'project:ba'))
|
||||
code, out, err = self.t('list project:ba')
|
||||
self.assertNotIn('one', out)
|
||||
self.assertNotIn('two', out)
|
||||
self.assertNotIn('three', out)
|
||||
@@ -113,7 +113,7 @@ class TestFilterPrefix(TestCase):
|
||||
|
||||
def test_list_description_has_foo(self):
|
||||
"""Filter on description pattern."""
|
||||
code, out, err = self.t(('list', 'description.has:foo'))
|
||||
code, out, err = self.t('list description.has:foo')
|
||||
self.assertIn('one', out)
|
||||
self.assertNotIn('two', out)
|
||||
self.assertNotIn('three', out)
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -46,7 +46,7 @@ class TestHooksOnLaunch(TestCase):
|
||||
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)
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-accept'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t("add foo")
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
hook.assertTriggeredCount(1)
|
||||
@@ -55,7 +55,7 @@ class TestHooksOnAdd(TestCase):
|
||||
logs = hook.get_logs()
|
||||
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("Description foo", out)
|
||||
|
||||
def test_onadd_builtin_reject(self):
|
||||
@@ -63,7 +63,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-reject'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
hook.assertTriggeredCount(1)
|
||||
@@ -77,7 +77,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave1'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
hook.assertTriggeredCount(1)
|
||||
@@ -91,7 +91,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave2'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
self.assertIn("Hook Error: Expected 1 JSON task(s), found 0", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -103,7 +103,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave3'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
self.assertIn("Hook Error: Expected 1 JSON task(s), found 2", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -115,7 +115,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave4'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
self.assertIn("Hook Error: JSON must be for the same task:", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -130,7 +130,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave5'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
self.assertIn("Hook Error: JSON syntax error in: {\"}", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -146,7 +146,7 @@ class TestHooksOnAdd(TestCase):
|
||||
hookname = 'on-add-misbehave6'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t.runError(("add", "foo"))
|
||||
code, out, err = self.t.runError("add foo")
|
||||
self.assertIn("Hook Error: JSON Object missing 'uuid' attribute.", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestHooksOnExit(TestCase):
|
||||
hookname = 'on-exit-good'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("version",))
|
||||
code, out, err = self.t("version")
|
||||
self.assertIn("Taskwarrior", out)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -62,7 +62,7 @@ class TestHooksOnExit(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t.runError(("version",))
|
||||
code, out, err = self.t.runError("version")
|
||||
self.assertIn("Taskwarrior", out)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -78,7 +78,7 @@ class TestHooksOnExit(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t(("version",))
|
||||
code, out, err = self.t("version")
|
||||
self.assertIn("Taskwarrior", out)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -94,7 +94,7 @@ class TestHooksOnExit(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t.runError(("version",))
|
||||
code, out, err = self.t.runError("version")
|
||||
self.assertIn("Hook Error: Expected 0 JSON task(s), found 1", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestHooksOnLaunch(TestCase):
|
||||
hookname = 'on-launch-good'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("version",))
|
||||
code, out, err = self.t("version")
|
||||
self.assertIn("Taskwarrior", out)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -62,7 +62,7 @@ class TestHooksOnLaunch(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t.runError(("version",))
|
||||
code, out, err = self.t.runError("version")
|
||||
self.assertNotIn("Taskwarrior", out)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -78,7 +78,7 @@ class TestHooksOnLaunch(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t.runError(("version",))
|
||||
code, out, err = self.t.runError("version")
|
||||
self.assertNotIn("Could not get Hook exit status!", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -94,7 +94,7 @@ class TestHooksOnLaunch(TestCase):
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
# Failing hook should prevent processing.
|
||||
code, out, err = self.t.runError(("version",))
|
||||
code, out, err = self.t.runError("version")
|
||||
self.assertIn("Hook Error: Expected 0 JSON task(s), found 1", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
|
||||
@@ -46,8 +46,8 @@ class TestHooksOnModify(TestCase):
|
||||
hookname = 'on-modify-accept'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t(("1", "modify", "+tag"))
|
||||
code, out, err = self.t("add foo")
|
||||
code, out, err = self.t("1 modify +tag")
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
hook.assertTriggeredCount(1)
|
||||
@@ -56,7 +56,7 @@ class TestHooksOnModify(TestCase):
|
||||
logs = hook.get_logs()
|
||||
self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK")
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("Description foo", out)
|
||||
self.assertIn("Tags tag", out)
|
||||
|
||||
@@ -65,8 +65,8 @@ class TestHooksOnModify(TestCase):
|
||||
hookname = 'on-modify-reject'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t.runError(("1", "modify", "+tag"))
|
||||
code, out, err = self.t("add foo")
|
||||
code, out, err = self.t.runError("1 modify +tag")
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
hook.assertTriggeredCount(1)
|
||||
@@ -80,8 +80,8 @@ class TestHooksOnModify(TestCase):
|
||||
hookname = 'on-modify-misbehave2'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t.runError(("1", "modify", "+tag"))
|
||||
code, out, err = self.t("add foo")
|
||||
code, out, err = self.t.runError("1 modify +tag")
|
||||
self.assertIn("Hook Error: Expected 1 JSON task(s), found 0", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -96,8 +96,8 @@ class TestHooksOnModify(TestCase):
|
||||
hookname = 'on-modify-misbehave3'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t.runError(("1", "modify", "+tag"))
|
||||
code, out, err = self.t("add foo")
|
||||
code, out, err = self.t.runError("1 modify +tag")
|
||||
self.assertIn("Hook Error: Expected 1 JSON task(s), found 2", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -112,8 +112,8 @@ class TestHooksOnModify(TestCase):
|
||||
hookname = 'on-modify-misbehave4'
|
||||
self.t.hooks.add_default(hookname, log=True)
|
||||
|
||||
code, out, err = self.t(("add", "foo"))
|
||||
code, out, err = self.t.runError(("1", "modify", "+tag"))
|
||||
code, out, err = self.t("add foo")
|
||||
code, out, err = self.t.runError("1 modify +tag")
|
||||
self.assertIn("Hook Error: JSON must be for the same task:", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -128,8 +128,8 @@ class TestHooksOnModify(TestCase):
|
||||
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"))
|
||||
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)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
@@ -144,8 +144,8 @@ class TestHooksOnModify(TestCase):
|
||||
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"))
|
||||
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.", err)
|
||||
|
||||
hook = self.t.hooks[hookname]
|
||||
|
||||
26
test/ids.t
26
test/ids.t
@@ -41,50 +41,50 @@ class TestIDs(TestCase):
|
||||
def setUpClass(self):
|
||||
self.t = Task()
|
||||
|
||||
self.t(("add", "one", "+A", "+B"))
|
||||
self.t(("add", "two", "+A" ))
|
||||
self.t(("add", "three", "+A", "+B"))
|
||||
self.t(("add", "four" ))
|
||||
self.t(("add", "five", "+A", "+B"))
|
||||
self.t("add one +A +B")
|
||||
self.t("add two +A" )
|
||||
self.t("add three +A +B")
|
||||
self.t("add four" )
|
||||
self.t("add five +A +B")
|
||||
|
||||
def test_ids_count_A(self):
|
||||
"""ids +A"""
|
||||
code, out, err = self.t(("ids", "+A"))
|
||||
code, out, err = self.t("ids +A")
|
||||
self.assertRegexpMatches(out, "^1-3,5$")
|
||||
|
||||
def test_ids_count_B(self):
|
||||
"""ids +B"""
|
||||
code, out, err = self.t(("ids", "+B"))
|
||||
code, out, err = self.t("ids +B")
|
||||
self.assertRegexpMatches(out, "^1,3,5$")
|
||||
|
||||
def test_ids_count_A_B(self):
|
||||
"""ids +A -B"""
|
||||
code, out, err = self.t(("ids", "+A", "-B"))
|
||||
code, out, err = self.t("ids +A -B")
|
||||
self.assertRegexpMatches(out, "^2$")
|
||||
|
||||
def test_get_ids_count_A(self):
|
||||
"""_ids +A"""
|
||||
code, out, err = self.t(("_ids", "+A"))
|
||||
code, out, err = self.t("_ids +A")
|
||||
self.assertRegexpMatches(out, "^1\n2\n3\n5$")
|
||||
|
||||
def test_get_zshids_count_A(self):
|
||||
"""_zshids +A"""
|
||||
code, out, err = self.t(("_zshids", "+A"))
|
||||
code, out, err = self.t("_zshids +A")
|
||||
self.assertRegexpMatches(out, "^1:one\n2:two\n3:three\n5:five$")
|
||||
|
||||
def test_uuids_count_A(self):
|
||||
"""uuids +A"""
|
||||
code, out, err = self.t(("uuids", "+A"))
|
||||
code, out, err = self.t("uuids +A")
|
||||
self.assertRegexpMatches(out, "{0},{0},{0},{0}".format(UUID_REGEXP))
|
||||
|
||||
def test_get_uuids_count_A(self):
|
||||
"""_uuids +A"""
|
||||
code, out, err = self.t(("_uuids", "+A"))
|
||||
code, out, err = self.t("_uuids +A")
|
||||
self.assertRegexpMatches(out, "{0}\n{0}\n{0}\n{0}".format(UUID_REGEXP))
|
||||
|
||||
def test_get_zshuuids_count_A(self):
|
||||
"""_zshuuids +A"""
|
||||
code, out, err = self.t(("_zshuuids", "+A"))
|
||||
code, out, err = self.t("_zshuuids +A")
|
||||
self.assertRegexpMatches(
|
||||
out, "{0}:one\n{0}:two\n{0}:three\n{0}:five".format(UUID_REGEXP))
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ class TestImport(TestCase):
|
||||
self.t.config("dateformat", "m/d/Y")
|
||||
|
||||
self.data1 = """[
|
||||
{"uuid":"00000000-0000-0000-0000-000000000000","description":"zero","project":"A","status":"pending","entry":"1234567889"},
|
||||
{"uuid":"11111111-1111-1111-1111-111111111111","description":"one","project":"B","status":"pending","entry":"1234567889"},
|
||||
{"uuid":"22222222-2222-2222-2222-222222222222","description":"two","status":"completed","entry":"1234524689","end":"1234524690"}
|
||||
{"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"}
|
||||
]
|
||||
"""
|
||||
|
||||
@@ -53,24 +53,24 @@ class TestImport(TestCase):
|
||||
"""
|
||||
|
||||
def assertData1(self):
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertRegexpMatches(out, "1.+A.+zero")
|
||||
self.assertRegexpMatches(out, "2.+B.+one")
|
||||
self.assertNotIn("two", out)
|
||||
|
||||
code, out, err = self.t(("completed",))
|
||||
code, out, err = self.t("completed")
|
||||
self.assertNotIn("zero", out)
|
||||
self.assertNotIn("one", out)
|
||||
# complete has completion date as 1st column
|
||||
self.assertRegexpMatches(out, "2/13/2009.+two")
|
||||
|
||||
def assertData2(self):
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertRegexpMatches(out, "3.+three")
|
||||
|
||||
def test_import_stdin(self):
|
||||
"""Import from stdin"""
|
||||
code, out, err = self.t(("import", "-"), input=self.data1)
|
||||
code, out, err = self.t("import -", input=self.data1)
|
||||
self.assertIn("Imported 3 tasks", err)
|
||||
|
||||
self.assertData1()
|
||||
@@ -86,17 +86,17 @@ class TestImport(TestCase):
|
||||
"""Import from a file"""
|
||||
filename = mkstemp(self.data1)
|
||||
|
||||
code, out, err = self.t(("import", filename))
|
||||
code, out, err = self.t("import {0}".format(filename))
|
||||
self.assertIn("Imported 3 tasks", err)
|
||||
|
||||
self.assertData1()
|
||||
|
||||
def test_double_import(self):
|
||||
"""Multiple imports persist data"""
|
||||
code, out, err = self.t(("import", "-"), input=self.data1)
|
||||
code, out, err = self.t("import -", input=self.data1)
|
||||
self.assertIn("Imported 3 tasks", err)
|
||||
|
||||
code, out, err = self.t(("import", "-"), input=self.data2)
|
||||
code, out, err = self.t("import -", input=self.data2)
|
||||
self.assertIn("Imported 1 tasks", err)
|
||||
|
||||
self.assertData1()
|
||||
@@ -105,9 +105,7 @@ class TestImport(TestCase):
|
||||
def test_import_update(self):
|
||||
"""Update existing tasks"""
|
||||
self.t("import", input=self.data1)
|
||||
self.t("2 delete") # Depends on import order. Bad. See next line.
|
||||
# TODO: Use this once filtering by UUID works again...
|
||||
#self.t("11111111-1111-1111-1111-111111111111 delete")
|
||||
self.t("a1111111-a111-a111-a111-a11111111111 delete")
|
||||
self.t("next") # Run GC
|
||||
|
||||
_t = sorted(self.t.export(), key=lambda t: t["uuid"])
|
||||
@@ -146,14 +144,53 @@ class TestImport(TestCase):
|
||||
def test_import_newlines_whitespace(self):
|
||||
"""JSON array with whitespace before and after names and values"""
|
||||
_data = """[
|
||||
{ "uuid":"00000000-0000-0000-0000-000000000000" , "description" : "zero" ,"project":"A", "status":"pending","entry":"1234567889" } ,
|
||||
{ "uuid":"11111111-1111-1111-1111-111111111111","description":"one","project":"B","status":"pending","entry":"1234567889"}, {"uuid":"22222222-2222-2222-2222-222222222222","description":"two","status":"completed","entry":"1234524689","end":"1234524690" }
|
||||
{ "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)
|
||||
self.assertIn("Imported 3 tasks", err)
|
||||
self.assertData1()
|
||||
|
||||
|
||||
class TestImportExportRoundtrip(TestCase):
|
||||
def setUp(self):
|
||||
self.t1 = Task()
|
||||
self.t2 = Task()
|
||||
|
||||
for client in (self.t1, self.t2):
|
||||
client.config("dateformat", "m/d/Y")
|
||||
client.config("verbose", "off")
|
||||
client.config("defaultwidth", "100")
|
||||
client.config("json.array", "off")
|
||||
|
||||
def _validate_data(self, client):
|
||||
code, out, err = client("_get 1.priority")
|
||||
self.assertEqual("H\n", out)
|
||||
code, out, err = client("_get 1.project")
|
||||
self.assertEqual("A\n", out)
|
||||
code, out, err = client("_get 1.description")
|
||||
self.assertEqual("one/1\n", out)
|
||||
code, out, err = client("_get 2.tags")
|
||||
self.assertEqual("tag1,tag2\n", out)
|
||||
code, out, err = client("_get 2.description")
|
||||
self.assertEqual("two\n", out)
|
||||
|
||||
def test_import_export(self):
|
||||
"""Test importing exported data"""
|
||||
self.t1("add priority:H project:A -- one/1")
|
||||
self.t1("add +tag1 +tag2 two")
|
||||
|
||||
code, out1, err = self.t1("export")
|
||||
|
||||
self.t2("import -", input=out1)
|
||||
code, out2, err = self.t2("export")
|
||||
|
||||
self.assertEqual(out1, out2)
|
||||
|
||||
self._validate_data(self.t1)
|
||||
self._validate_data(self.t2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from simpletap import TAPTestRunner
|
||||
unittest.main(testRunner=TAPTestRunner())
|
||||
|
||||
@@ -83,7 +83,7 @@ if __name__ == "__main__":
|
||||
stop = float(timestamp.match(line).group(1))
|
||||
|
||||
# Remove expected failures from the skipped tests category
|
||||
for filename, value in expected.iteritems():
|
||||
for filename, value in expected.items():
|
||||
if skipped[filename] == value:
|
||||
del skipped[filename]
|
||||
else:
|
||||
|
||||
@@ -46,11 +46,11 @@ class TestProjects(TestCase):
|
||||
"""'task projects' shouldn't consider deleted tasks in summary.
|
||||
Reported in bug 1044
|
||||
"""
|
||||
self.t(("add", "project:A", "1"))
|
||||
self.t(("add", "project:B", "2"))
|
||||
self.t(("add", "project:B", "3"))
|
||||
self.t(("3", "delete"))
|
||||
code, out, err = self.t(("project:B", "projects"))
|
||||
self.t("add project:A 1")
|
||||
self.t("add project:B 2")
|
||||
self.t("add project:B 3")
|
||||
self.t("3 delete")
|
||||
code, out, err = self.t("project:B projects")
|
||||
|
||||
expected = "1 project \(1 task\)"
|
||||
self.assertRegexpMatches(out, expected)
|
||||
@@ -58,31 +58,31 @@ class TestProjects(TestCase):
|
||||
def test_project_progress(self):
|
||||
"""project status/progress is shown and is up-to-date"""
|
||||
|
||||
code, out, err = self.t(("add", "one", "pro:foo"))
|
||||
code, out, err = self.t("add one pro:foo")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "0%",
|
||||
"1 task"))
|
||||
|
||||
code, out, err = self.t(("add", "two", "pro:foo"))
|
||||
code, out, err = self.t("add two pro:foo")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "0%",
|
||||
"2 of 2 tasks"))
|
||||
|
||||
code, out, err = self.t(("add", "three", "pro:foo"))
|
||||
code, out, err = self.t("add three pro:foo")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "0%",
|
||||
"3 of 3 tasks"))
|
||||
|
||||
code, out, err = self.t(("add", "four", "pro:foo"))
|
||||
code, out, err = self.t("add four pro:foo")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "0%",
|
||||
"4 of 4 tasks"))
|
||||
|
||||
code, out, err = self.t(("1", "done"))
|
||||
code, out, err = self.t("1 done")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "25%",
|
||||
"3 of 4 tasks"))
|
||||
|
||||
code, out, err = self.t(("2", "delete"))
|
||||
code, out, err = self.t("2 delete")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "33%",
|
||||
"2 of 3 tasks"))
|
||||
|
||||
code, out, err = self.t(("3", "modify", "pro:bar"))
|
||||
code, out, err = self.t("3 modify pro:bar")
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo", "50%",
|
||||
"1 of 2 tasks"))
|
||||
self.assertRegexpMatches(err, self.STATUS.format("bar", "0%",
|
||||
@@ -91,18 +91,18 @@ class TestProjects(TestCase):
|
||||
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.t("add hello pro:bob")
|
||||
code, out, err = self.t('1 mod pro:"foo bar"')
|
||||
self.assertRegexpMatches(err, self.STATUS.format("foo bar", "0%",
|
||||
"1 task"))
|
||||
|
||||
def add_tasks(self):
|
||||
self.t(("add", "testing", "project:existingParent"))
|
||||
self.t(("add", "testing", "project:existingParent.child"))
|
||||
self.t(("add", "testing", "project:abstractParent.kid"))
|
||||
self.t(("add", "testing", "project:.myProject"))
|
||||
self.t(("add", "testing", "project:myProject"))
|
||||
self.t(("add", "testing", "project:.myProject."))
|
||||
self.t("add testing project:existingParent")
|
||||
self.t("add testing project:existingParent.child")
|
||||
self.t("add testing project:abstractParent.kid")
|
||||
self.t("add testing project:.myProject")
|
||||
self.t("add testing project:myProject")
|
||||
self.t("add testing project:.myProject.")
|
||||
|
||||
def validate_indentation(self, out):
|
||||
order = (
|
||||
@@ -137,7 +137,7 @@ class TestProjects(TestCase):
|
||||
"""
|
||||
self.add_tasks()
|
||||
|
||||
code, out, err = self.t(("projects",))
|
||||
code, out, err = self.t("projects")
|
||||
|
||||
self.validate_indentation(out)
|
||||
|
||||
@@ -148,7 +148,7 @@ class TestProjects(TestCase):
|
||||
"""
|
||||
self.add_tasks()
|
||||
|
||||
code, out, err = self.t(("summary",))
|
||||
code, out, err = self.t("summary")
|
||||
|
||||
self.validate_indentation(out)
|
||||
|
||||
@@ -156,19 +156,19 @@ class TestProjects(TestCase):
|
||||
class TestBug299(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
self.t(("add", "project:one", "foo"))
|
||||
self.t(("add", "project:ones", "faz"))
|
||||
self.t(("add", "project:phone", "boo"))
|
||||
self.t(("add", "project:bones", "too"))
|
||||
self.t(("add", "project:two", "bar"))
|
||||
self.t(("add", "project:three", "baz"))
|
||||
self.t("add project:one foo")
|
||||
self.t("add project:ones faz")
|
||||
self.t("add project:phone boo")
|
||||
self.t("add project:bones too")
|
||||
self.t("add project:two bar")
|
||||
self.t("add project:three baz")
|
||||
|
||||
def test_project_exclusion_isnt(self):
|
||||
"""check project exclusion using project.isnt:<name>
|
||||
|
||||
Reported in bug 299
|
||||
"""
|
||||
code, out, err = self.t(("list", "project.isnt:one", "pro.isnt:two"))
|
||||
code, out, err = self.t("list project.isnt:one pro.isnt:two")
|
||||
|
||||
self.assertNotRegexpMatches(out, "one.*foo")
|
||||
self.assertRegexpMatches(out, "ones.*faz")
|
||||
@@ -183,7 +183,7 @@ class TestBug299(TestCase):
|
||||
|
||||
Reported in bug 299
|
||||
"""
|
||||
code, out, err = self.t(("list", "project.hasnt:one", "pro.hasnt:two"))
|
||||
code, out, err = self.t("list project.hasnt:one pro.hasnt:two")
|
||||
|
||||
self.assertNotRegexpMatches(out, "one.*foo")
|
||||
self.assertNotRegexpMatches(out, "ones.*faz")
|
||||
@@ -203,7 +203,7 @@ class TestBug555(TestCase):
|
||||
|
||||
Reported in bug 555
|
||||
"""
|
||||
code, out, err = self.t(("log", "description", "project:p"))
|
||||
code, out, err = self.t("log description project:p")
|
||||
|
||||
self.assertNotIn("Segmentation fault", out)
|
||||
self.assertNotIn("Segmentation fault", err)
|
||||
@@ -221,11 +221,11 @@ class TestBug605(TestCase):
|
||||
"""
|
||||
self.t("add One project:p1")
|
||||
|
||||
code, out, err = self.t(("1", "delete"), input="y\n")
|
||||
code, out, err = self.t("1 delete", input="y\n")
|
||||
self.assertIn("is 0% complete", err)
|
||||
|
||||
self.t("add Two project:p1")
|
||||
code, out, err = self.t(("2", "done"))
|
||||
code, out, err = self.t("2 done")
|
||||
self.assertIn("is 100% complete", err)
|
||||
|
||||
class TestBug906(TestCase):
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -47,13 +47,13 @@ class TestRecurrenceDisabled(TestCase):
|
||||
"""
|
||||
|
||||
self.t.config("recurrence", "no")
|
||||
self.t(("add", "due:today", "recur:daily", "Recurrent task."))
|
||||
self.t("add due:today recur:daily Recurrent task.")
|
||||
|
||||
# Trigger GC, expect no match and therefore non-zero code
|
||||
self.t.runError(("list",))
|
||||
self.t.runError("list")
|
||||
|
||||
# Check that no task has been generated.
|
||||
code, out, err = self.t(("task", "count"))
|
||||
code, out, err = self.t("task count")
|
||||
self.assertEqual("0", out.strip())
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
#! /usr/bin/env perl
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 5;
|
||||
|
||||
# Ensure environment has no influence.
|
||||
delete $ENV{'TASKDATA'};
|
||||
delete $ENV{'TASKRC'};
|
||||
|
||||
use File::Basename;
|
||||
my $ut = basename ($0);
|
||||
my $rc = $ut . '.rc';
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', $rc)
|
||||
{
|
||||
print $fh "data.location=.\n",
|
||||
"verbose=off\n",
|
||||
"confirmation=no\n",
|
||||
"defaultwidth=100\n",
|
||||
"dateformat=m/d/Y\n",
|
||||
"json.array=off";
|
||||
close $fh;
|
||||
}
|
||||
|
||||
# Add two tasks.
|
||||
qx{../src/task rc:$rc add priority:H project:A -- one/1 2>&1};
|
||||
qx{../src/task rc:$rc add +tag1 +tag2 two 2>&1};
|
||||
|
||||
# trip 1.
|
||||
qx{../src/task rc:$rc export > roundtrip1.json 2>/dev/null};
|
||||
ok (-s 'roundtrip1.json' > 0, "$ut: roundtrip1.json is not empty");
|
||||
unlink 'pending.data', 'completed.data', 'undo.data', 'backlog.data';
|
||||
qx{../src/task rc:$rc import roundtrip1.json 2>/dev/null};
|
||||
|
||||
# trip 2.
|
||||
qx{../src/task rc:$rc export > roundtrip2.json 2>/dev/null};
|
||||
ok (-s 'roundtrip2.json' > 0, "$ut: roundtrip2.json is not empty");
|
||||
unlink 'pending.data', 'completed.data', 'undo.data', 'backlog.data';
|
||||
qx{../src/task rc:$rc import roundtrip2.json 2>/dev/null};
|
||||
|
||||
# Examine.
|
||||
#
|
||||
# ID Created P Project Tags Description
|
||||
# -- ---------- - ------- --------- -----------
|
||||
# 1 1/7/2014 H A one/1
|
||||
# 2 1/7/2014 tag1 tag2 two
|
||||
|
||||
my $output = qx{../src/task rc:$rc long 2>&1};
|
||||
like ($output, qr/1\s+\d+\/\d+\/\d+.+\sH\s+A\s+one\/1/, "$ut: 2 round trips task 1 identical");
|
||||
like ($output, qr/2\s+\d+\/\d+\/\d+.+\stag1\s+tag2\s+two/, "$ut: 2 round trips task 2 identical");
|
||||
|
||||
# Compare the actual JSON files.
|
||||
$output = qx{diff roundtrip1.json roundtrip2.json 2>&1};
|
||||
like ($output, qr/^$/, "$ut: JSON files roundtrip1.json and roundtrip2.json identical");
|
||||
|
||||
# Cleanup.
|
||||
unlink qw(roundtrip1.json roundtrip2.json pending.data completed.data undo.data backlog.data), $rc;
|
||||
exit 0;
|
||||
|
||||
16
test/run_all
16
test/run_all
@@ -9,10 +9,16 @@ import argparse
|
||||
import logging
|
||||
import time
|
||||
from multiprocessing import cpu_count
|
||||
from Queue import Queue, Empty
|
||||
from threading import Thread
|
||||
from subprocess import call, Popen, PIPE
|
||||
|
||||
try:
|
||||
# python 2
|
||||
from Queue import Queue, Empty
|
||||
except ImportError:
|
||||
# python 3
|
||||
from queue import Queue, Empty
|
||||
|
||||
# Look for taskd in $PATH instead of task/src/
|
||||
os.environ["TASKD_USE_PATH"] = "1"
|
||||
|
||||
@@ -38,6 +44,9 @@ def run_test(testqueue, outqueue, threadname):
|
||||
# Premature end
|
||||
break
|
||||
|
||||
if sys.version_info > (3,):
|
||||
out, err = out.decode('utf-8'), err.decode('utf-8')
|
||||
|
||||
output = ("# {0}\n".format(os.path.basename(test)), out, err)
|
||||
log.debug("Collected output %s", output)
|
||||
outqueue.put(output)
|
||||
@@ -62,8 +71,8 @@ class TestRunner(object):
|
||||
if os.access(test, os.X_OK):
|
||||
# Executables only
|
||||
if not cmd_args.serial:
|
||||
with open(test) as fh:
|
||||
if "/usr/bin/env python" in fh.readline():
|
||||
with open(test, 'rb') as fh:
|
||||
if b"/usr/bin/env python" in fh.read(50):
|
||||
log.debug("Treating as parallel: %s", test)
|
||||
self._parallelq.put(test)
|
||||
else:
|
||||
@@ -166,6 +175,7 @@ def parse_args():
|
||||
parser.add_argument('--verbose', '-v', action="store_true",
|
||||
help="Also send TAP output to stdout")
|
||||
parser.add_argument('--logging', '-l', action="count",
|
||||
default=0,
|
||||
help="Logging level. -lll is the highest level")
|
||||
parser.add_argument('--serial', action="store_true",
|
||||
help="Do not run tests in parallel")
|
||||
|
||||
@@ -41,15 +41,15 @@ class TestFilterPrefix(TestCase):
|
||||
"""Executed once before any test in the class"""
|
||||
cls.t = Task()
|
||||
cls.t.config("verbose", "nothing")
|
||||
cls.t(('add', 'foo'))
|
||||
cls.t('add foo')
|
||||
|
||||
def test_success(self):
|
||||
"""Test successful search returns zero."""
|
||||
code, out, err = self.t(('list', '/foo/'))
|
||||
code, out, err = self.t('list /foo/')
|
||||
|
||||
def test_failure(self):
|
||||
"""Test failed search returns non-zero."""
|
||||
code, out, err = self.t.runError(('list', '/bar/'))
|
||||
code, out, err = self.t.runError('list /bar/')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -48,8 +48,7 @@ class MetaTests(type):
|
||||
def test(self):
|
||||
# ### Body of the usual test_testcase ### #
|
||||
code, out, err = self.t(
|
||||
("rc.report.{0}.sort:{1}".format(self._report, filter),
|
||||
self._report)
|
||||
"rc.report.{0}.sort:{1} {0}".format(self._report, filter)
|
||||
)
|
||||
|
||||
for expected in expectations:
|
||||
@@ -99,12 +98,12 @@ class TestSorting(TestCase):
|
||||
# Report to use when running this class's tests
|
||||
cls._report = "list"
|
||||
|
||||
cls.t(("add", "zero"))
|
||||
cls.t(("add", "priority:H", "project:A", "due:yesterday", "one"))
|
||||
cls.t(("add", "priority:M", "project:B", "due:today", "two"))
|
||||
cls.t(("add", "priority:L", "project:C", "due:tomorrow", "three"))
|
||||
cls.t(("add", "priority:H", "project:C", "due:today", "four"))
|
||||
cls.t(("2", "start"))
|
||||
cls.t("add zero")
|
||||
cls.t("add priority:H project:A due:yesterday one")
|
||||
cls.t("add priority:M project:B due:today two")
|
||||
cls.t("add priority:L project:C due:tomorrow three")
|
||||
cls.t("add priority:H project:C due:today four")
|
||||
cls.t("2 start")
|
||||
|
||||
TESTS = {
|
||||
# Filter # Expected matches/outputs
|
||||
@@ -250,29 +249,19 @@ class TestBug438(TestCase):
|
||||
# 2 tasks created in the past, and finished 20 seconds later
|
||||
|
||||
stamp = int(time.time())
|
||||
cls.t(("add", "one older",
|
||||
"entry:{0}".format(stamp)))
|
||||
cls.t("add one older entry:{0}".format(stamp))
|
||||
stamp += 1
|
||||
cls.t(("add", "one newer",
|
||||
"entry:{0}".format(stamp)))
|
||||
cls.t("add one newer entry:{0}".format(stamp))
|
||||
|
||||
start = stamp + 10
|
||||
cls.t(("add", "two older",
|
||||
"entry:{0}".format(stamp),
|
||||
"start:{0}".format(start)))
|
||||
cls.t("add two older entry:{0} start:{1}".format(stamp, start))
|
||||
start += 1
|
||||
cls.t(("add", "two newer",
|
||||
"entry:{0}".format(stamp),
|
||||
"start:{0}".format(start)))
|
||||
cls.t("add two newer entry:{0} start:{1}".format(stamp, start))
|
||||
|
||||
end = start + 10
|
||||
cls.t(("log", "three older",
|
||||
"entry:{0}".format(stamp),
|
||||
"end:{0}".format(end)))
|
||||
cls.t("log three older entry:{0} end:{1}".format(stamp, end))
|
||||
end += 1
|
||||
cls.t(("log", "three newer",
|
||||
"entry:{0}".format(stamp),
|
||||
"end:{0}".format(end)))
|
||||
cls.t("log three newer entry:{0} end:{1}".format(stamp, end))
|
||||
|
||||
TESTS = {
|
||||
"entry+": ["one older.+one newer"],
|
||||
|
||||
@@ -41,7 +41,7 @@ def run_test(test):
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Run Taskwarrior tests repeatedly")
|
||||
parser.add_argument('--logging', '-l', action="count",
|
||||
parser.add_argument('--logging', '-l', action="count", default=0,
|
||||
help="Logging level. -lll is the highest level")
|
||||
parser.add_argument('--repeat', metavar="N", type=int, default=100,
|
||||
help="How many times to run each test (default: 100)")
|
||||
|
||||
113
test/tw-101.t
113
test/tw-101.t
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -40,89 +40,72 @@ class TestBug101(TestCase):
|
||||
def setUp(self):
|
||||
"""Executed before each test in the class"""
|
||||
self.t = Task()
|
||||
|
||||
# Define report with truncated_count style
|
||||
with open(self.t.taskrc, 'a') as fh:
|
||||
fh.write("report.bug101.columns=description.truncated_count\n")
|
||||
#Find screen width in order to generate long enough string
|
||||
command = ("_get", "context.width")
|
||||
code, out, err = self.t(command)
|
||||
self.t.config("report.bug101.columns", "description.truncated_count")
|
||||
|
||||
# Find screen width in order to generate long enough string
|
||||
code, out, err = self.t("_get context.width")
|
||||
self.width = int(out)
|
||||
#Since task strips leading and trailing spaces, for the purposes
|
||||
#of these tests, ensure description contains no spaces so we know
|
||||
#exactly what string we are expecting
|
||||
# Since task strips leading and trailing spaces, for the purposes
|
||||
# of these tests, ensure description contains no spaces so we know
|
||||
# exactly what string we are expecting
|
||||
self.short_description = "A_task_description_"
|
||||
#Generate long string
|
||||
# Generate long string
|
||||
self.long_description = self.short_description * int(math.ceil(float(self.width)/len(self.short_description)))
|
||||
|
||||
def test_short_no_count(self):
|
||||
"""Check short description with no annotations"""
|
||||
command = ("add", self.short_description)
|
||||
self.t(command)
|
||||
self.t(("add", self.short_description))
|
||||
|
||||
command = ("bug101",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("bug101")
|
||||
|
||||
expected = self.short_description
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def test_short_with_count(self):
|
||||
"""Check short description with annotations"""
|
||||
command = ("add", self.short_description)
|
||||
self.t(command)
|
||||
self.t(("add", self.short_description))
|
||||
|
||||
command = ("1", "annotate", "A task annotation")
|
||||
self.t(command)
|
||||
self.t("1 annotate 'A task annotation'")
|
||||
|
||||
command = ("bug101",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("bug101")
|
||||
|
||||
expected = self.short_description + " [1]"
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def test_long_no_count(self):
|
||||
"""Check long description with no annotations"""
|
||||
command = ("add", self.long_description)
|
||||
self.t(command)
|
||||
self.t(("add", self.long_description))
|
||||
|
||||
command = ("bug101",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("bug101")
|
||||
|
||||
expected = self.long_description[:(self.width - 3)] + "..."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def test_long_with_count(self):
|
||||
"""Check long description with annotations"""
|
||||
command = ("add", self.long_description)
|
||||
self.t(command)
|
||||
self.t(("add", self.long_description))
|
||||
|
||||
command = ("1", "annotate", "A task annotation")
|
||||
self.t(command)
|
||||
self.t("1 annotate 'A task annotation'")
|
||||
|
||||
command = ("bug101",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("bug101")
|
||||
|
||||
expected = self.long_description[:(self.width - 7)] + "... [1]"
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def test_long_with_double_digit_count(self):
|
||||
"""Check long description with double digit amount of annotations"""
|
||||
command = ("add", self.long_description)
|
||||
self.t(command)
|
||||
self.t(("add", self.long_description))
|
||||
|
||||
for a in range(10):
|
||||
command = ("1", "annotate", "A task annotation")
|
||||
self.t(command)
|
||||
for i in range(10):
|
||||
self.t("1 annotate 'A task annotation'")
|
||||
|
||||
command = ("bug101",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("bug101")
|
||||
|
||||
expected = self.long_description[:(self.width - 8)] + "... [10]"
|
||||
self.assertIn(expected, out)
|
||||
|
||||
def tearDown(self):
|
||||
command = ("1", "delete")
|
||||
self.t(command, "y\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from simpletap import TAPTestRunner
|
||||
|
||||
@@ -17,15 +17,11 @@ class TestBug1262(TestCase):
|
||||
def setUpClass(cls):
|
||||
cls.t = Task()
|
||||
|
||||
command = ("add", "Buy oranges")
|
||||
cls.t(command)
|
||||
|
||||
command = ("add", "Buy apples")
|
||||
cls.t(command)
|
||||
cls.t('add "Buy oranges"')
|
||||
cls.t('add "Buy apples"')
|
||||
|
||||
cls.DEPS = ("1", "2")
|
||||
command = ("add", "dep:" + ",".join(cls.DEPS), "Make fruit salad!")
|
||||
cls.t(command)
|
||||
cls.t("add dep:" + ",".join(cls.DEPS) + '"Make fruit salad!"')
|
||||
|
||||
def test_dependency_contains_matches_ID(self):
|
||||
"""dep.contains matches task IDs"""
|
||||
@@ -34,25 +30,24 @@ class TestBug1262(TestCase):
|
||||
# fail, which means it's actually using the UUID.
|
||||
# Still, it passes on most cases. Which is WRONG!.
|
||||
for char in self.DEPS:
|
||||
self.t(("list", "dep.contains:{0}".format(char)))
|
||||
self.t("list dep.contains:{0}".format(char))
|
||||
|
||||
def test_dependency_contains_not_matches_other(self):
|
||||
"""dep.contains matches other characters not present in ID nor UUID"""
|
||||
for char in set(string.letters).difference(string.hexdigits):
|
||||
self.t.runError(("list", "dep.contains:{0}".format(char)))
|
||||
self.t.runError("list dep.contains:{0}".format(char))
|
||||
|
||||
def test_dependency_contains_not_UUID(self):
|
||||
"""dep.contains matches characters in the tasks' UUIDs"""
|
||||
# Get the UUID of the task with description "Buy"
|
||||
command = ("uuid", "Buy")
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("uuid Buy")
|
||||
|
||||
# Get only characters that show up in the UUID
|
||||
uuid = {chr for chr in out.splitlines()[0] if chr in string.hexdigits}
|
||||
|
||||
for char in uuid:
|
||||
if char not in self.DEPS:
|
||||
self.t.runError(("list", "dep.contains:{0}".format(char)))
|
||||
self.t.runError("list dep.contains:{0}".format(char))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -43,12 +43,12 @@ class TestBug1300(TestCase):
|
||||
def test_dom_exit_status_good(self):
|
||||
"""If the DOM recognizes a reference, it should return '0'
|
||||
"""
|
||||
self.t(("_get", "context.program"))
|
||||
self.t("_get context.program")
|
||||
|
||||
def test_dom_exit_status_bad(self):
|
||||
"""If the DOM does not recognize a reference, it should return '1'
|
||||
"""
|
||||
self.t.runError(("_get", "XYZ"))
|
||||
self.t.runError("_get XYZ")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -40,8 +40,8 @@ class TestBug1306(TestCase):
|
||||
|
||||
def test_mod_before_add(self):
|
||||
"""FILTER before 'add' command upgraded to MODIFICATION"""
|
||||
self.t(("project:PROJ", "add", "foo"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
self.t("project:PROJ add foo")
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("PROJ", out)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -40,9 +40,9 @@ class TestBug1359(TestCase):
|
||||
|
||||
def test_add_hyphenated(self):
|
||||
""""one-two-three" in description triggers Malformed ID error"""
|
||||
self.t(("add", "'one-two-three.ca'"))
|
||||
self.t("add 'one-two-three.ca'")
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("one-two-three.ca", out)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -40,8 +40,8 @@ class TestBug1377(TestCase):
|
||||
|
||||
def test_bad_tag_parser(self):
|
||||
"""Task doesn't accept tags in default.command"""
|
||||
self.t(("add", "Something interesting"))
|
||||
self.t(("add", "dep:1", "NOTSHOWN"))
|
||||
self.t("add Something interesting")
|
||||
self.t("add dep:1 NOTSHOWN")
|
||||
self.t.config("default.command", "next -BLOCKED")
|
||||
|
||||
code, out, err = self.t()
|
||||
|
||||
104
test/tw-1379.t
104
test/tw-1379.t
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -56,84 +56,84 @@ class TestBug1379(TestCase):
|
||||
"""color.tag.BLOCKED changes color of BLOCKED tasks"""
|
||||
self.t.config("color.tag.BLOCKED", "red")
|
||||
|
||||
self.t(("add", "Blocks"))
|
||||
self.t(("add", "dep:1", "Blocked"))
|
||||
self.t("add Blocks")
|
||||
self.t("add dep:1 Blocked")
|
||||
|
||||
code, out, err = self.t(("all", "+BLOCKED"))
|
||||
code, out, err = self.t("all +BLOCKED")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Blocked.*" + self.CLEAR)
|
||||
|
||||
def test_color_UNBLOCKED(self):
|
||||
"""color.tag.UNBLOCKED changes color of UNBLOCKED tasks"""
|
||||
self.t.config("color.tag.UNBLOCKED", "red")
|
||||
|
||||
self.t(("add", "Blocks"))
|
||||
self.t(("add", "dep:1", "Blocked"))
|
||||
self.t("add Blocks")
|
||||
self.t("add dep:1 Blocked")
|
||||
|
||||
code, out, err = self.t(("all", "+UNBLOCKED"))
|
||||
code, out, err = self.t("all +UNBLOCKED")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Blocks.*" + self.CLEAR)
|
||||
|
||||
def test_color_BLOCKING(self):
|
||||
"""color.tag.BLOCKING changes color of BLOCKING tasks"""
|
||||
self.t.config("color.tag.BLOCKING", "red")
|
||||
|
||||
self.t(("add", "Blocks"))
|
||||
self.t(("add", "dep:1", "Blocked"))
|
||||
self.t("add Blocks")
|
||||
self.t("add dep:1 Blocked")
|
||||
|
||||
code, out, err = self.t(("all", "+BLOCKING"))
|
||||
code, out, err = self.t("all +BLOCKING")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Blocks.*" + self.CLEAR)
|
||||
|
||||
def test_color_SCHEDULED(self):
|
||||
"""color.tag.SCHEDULED changes color of SCHEDULED tasks"""
|
||||
self.t.config("color.tag.SCHEDULED", "red")
|
||||
|
||||
self.t(("add", "scheduled:tomorrow", "Have fun"))
|
||||
self.t("add scheduled:tomorrow Have fun")
|
||||
|
||||
code, out, err = self.t(("all", "+SCHEDULED"))
|
||||
code, out, err = self.t("all +SCHEDULED")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Have fun.*" + self.CLEAR)
|
||||
|
||||
def test_color_UNTIL(self):
|
||||
"""color.tag.UNTIL changes color of UNTIL tasks"""
|
||||
self.t.config("color.tag.UNTIL", "red")
|
||||
|
||||
self.t(("add", "until:tomorrow", "Urgent"))
|
||||
self.t("add until:tomorrow Urgent")
|
||||
|
||||
code, out, err = self.t(("all", "+UNTIL"))
|
||||
code, out, err = self.t("all +UNTIL")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Urgent.*" + self.CLEAR)
|
||||
|
||||
def test_color_WAITING(self):
|
||||
"""color.tag.WAITING changes color of WAITING tasks"""
|
||||
self.t.config("color.tag.WAITING", "red")
|
||||
|
||||
self.t(("add", "wait:tomorrow", "Tomorrow"))
|
||||
self.t("add wait:tomorrow Tomorrow")
|
||||
|
||||
code, out, err = self.t(("all", "+WAITING"))
|
||||
code, out, err = self.t("all +WAITING")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Tomorrow.*" + self.CLEAR)
|
||||
|
||||
def test_color_PARENT(self):
|
||||
"""color.tag.PARENT changes color of PARENT tasks"""
|
||||
self.t.config("color.tag.PARENT", "red")
|
||||
|
||||
self.t(("add", "recur:daily", "due:tomorrow", "Email"))
|
||||
self.t("add recur:daily due:tomorrow Email")
|
||||
|
||||
code, out, err = self.t(("all", "+PARENT"))
|
||||
code, out, err = self.t("all +PARENT")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Email.*" + self.CLEAR)
|
||||
|
||||
def test_color_CHILD(self):
|
||||
"""color.tag.CHILD changes color of CHILD tasks"""
|
||||
self.t.config("color.tag.CHILD", "red")
|
||||
|
||||
self.t(("add", "recur:daily", "due:tomorrow", "Email"))
|
||||
self.t("add recur:daily due:tomorrow Email")
|
||||
|
||||
code, out, err = self.t(("all", "+CHILD"))
|
||||
code, out, err = self.t("all +CHILD")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Email.*" + self.CLEAR)
|
||||
|
||||
def test_color_PENDING(self):
|
||||
"""color.tag.PENDING changes color of PENDING tasks"""
|
||||
self.t.config("color.tag.PENDING", "red")
|
||||
|
||||
self.t(("add", "Pending"))
|
||||
self.t("add Pending")
|
||||
|
||||
code, out, err = self.t(("all", "+PENDING"))
|
||||
code, out, err = self.t("all +PENDING")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Pending.*" + self.CLEAR)
|
||||
|
||||
def test_color_COMPLETED(self):
|
||||
@@ -141,10 +141,10 @@ class TestBug1379(TestCase):
|
||||
self.t.config("color.tag.COMPLETED", "red")
|
||||
self.t.config("color.completed", "")
|
||||
|
||||
self.t(("add", "Complete"))
|
||||
self.t(("1", "done"))
|
||||
self.t("add Complete")
|
||||
self.t("1 done")
|
||||
|
||||
code, out, err = self.t(("all", "+COMPLETED"))
|
||||
code, out, err = self.t("all +COMPLETED")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Complete.*" + self.CLEAR)
|
||||
|
||||
def test_color_DELETED(self):
|
||||
@@ -152,10 +152,10 @@ class TestBug1379(TestCase):
|
||||
self.t.config("color.tag.DELETED", "red")
|
||||
self.t.config("color.deleted", "")
|
||||
|
||||
self.t(("add", "Delete"))
|
||||
self.t(("1", "delete"))
|
||||
self.t("add Delete")
|
||||
self.t("1 delete")
|
||||
|
||||
code, out, err = self.t(("all", "+DELETED"))
|
||||
code, out, err = self.t("all +DELETED")
|
||||
self.assertRegexpMatches(out, self.RED + r".*Delete.*" + self.CLEAR)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -40,9 +40,9 @@ class TestBug1381(TestCase):
|
||||
|
||||
def test_blocking(self):
|
||||
"""Blocking report displays tasks that are blocking other tasks"""
|
||||
self.t(("add", "blocks"))
|
||||
self.t(("add", "dep:1", "blocked"))
|
||||
code, out, err = self.t(("blocking",))
|
||||
self.t("add blocks")
|
||||
self.t("add dep:1 blocked")
|
||||
code, out, err = self.t("blocking")
|
||||
|
||||
self.assertIn("blocks", out)
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -44,19 +44,19 @@ class TestBug1414(TestCase):
|
||||
|
||||
def test_execute(self):
|
||||
"""use execute"""
|
||||
code, out, err = self.t(("exec", "echo hello"))
|
||||
code, out, err = self.t("exec echo hello")
|
||||
self.assertIn("hello", out)
|
||||
|
||||
def test_exec_alias(self):
|
||||
"""use exec in alias"""
|
||||
self.t.config("alias.asdf", "exec echo hello")
|
||||
code, out, err = self.t(("asdf", ""))
|
||||
code, out, err = self.t("asdf")
|
||||
self.assertIn("hello", out)
|
||||
|
||||
def test_execute_alias(self):
|
||||
"""use execute in alias"""
|
||||
self.t.config("alias.asdf", "execute echo hello")
|
||||
code, out, err = self.t(("asdf", ""))
|
||||
code, out, err = self.t("asdf")
|
||||
self.assertIn("hello", out)
|
||||
|
||||
def test_default_command(self):
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -42,20 +42,20 @@ class Test1418(TestCase):
|
||||
|
||||
# Helper methods
|
||||
def find_in_list(self, description):
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertIn(description, out)
|
||||
|
||||
def search_task_pattern(self, description):
|
||||
command = ("/" + description.replace("/", "\\/") + "/",)
|
||||
command = "/" + description.replace("/", "\\/") + "/"
|
||||
code, out, err = self.t(command)
|
||||
self.assertIn(description, out)
|
||||
|
||||
def add_search_task(self, description):
|
||||
command = ("add", description)
|
||||
command = "add " + description
|
||||
self.t(command)
|
||||
|
||||
def add_search_task_description(self, description):
|
||||
command = ("add", "description:'" + description + "'")
|
||||
command = "add description:'" + description + "'"
|
||||
self.t(command)
|
||||
|
||||
def test_slash_in_description(self):
|
||||
@@ -108,7 +108,7 @@ class Test1418(TestCase):
|
||||
|
||||
# Different from the other tests, because we want to escape the '+'
|
||||
# in the regex, but not in the 'add' or 'list'
|
||||
code, out, err = self.t(("/foo\\+/",))
|
||||
code, out, err = self.t("/foo\\+/")
|
||||
self.assertIn(description, out)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -43,8 +43,8 @@ class Test1424(TestCase):
|
||||
|
||||
def test_1824_days(self):
|
||||
"""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
|
||||
@@ -55,8 +55,8 @@ class Test1424(TestCase):
|
||||
|
||||
def test_3648_days(self):
|
||||
"""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
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -62,7 +62,7 @@ class TestBug1436(TestCase):
|
||||
code, out, err = self.t("add Use this backslash \\\\\\\\")
|
||||
self.assertIn("Created task 1", out)
|
||||
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertIn("Use this backslash \\", out)
|
||||
|
||||
def test_backslashes(self):
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -42,16 +42,14 @@ class TestBug1438(TestCase):
|
||||
|
||||
def test_recurring_tasks_shouldn_ask_for_confirmation(self):
|
||||
"""rc.confirmation=off still prompts while changing recurring tasks"""
|
||||
command = ("add", "Sometimes", "due:tomorrow", "recur:daily",)
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("add Sometimes due:tomorrow recur:daily")
|
||||
self.assertIn("Created task 1", out)
|
||||
code, out, err = self.t(("list",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertIn("Sometimes", out)
|
||||
|
||||
command = ("rc.confirmation=off", "rc.recurrence.confirmation=off", "2", "mod", "/Sometimes/Everytime/")
|
||||
code, out, err = self.t(command)
|
||||
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",))
|
||||
code, out, err = self.t("list")
|
||||
self.assertIn("Everytime", out)
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -41,8 +41,7 @@ class TestBug1441(TestCase):
|
||||
|
||||
def test_import_filename(self):
|
||||
"""import fails if file doesn't exist"""
|
||||
command = ("import", "xxx_doesnotexist")
|
||||
code, out, err = self.t.runError(command)
|
||||
code, out, err = self.t.runError("import xxx_doesnotexist")
|
||||
|
||||
self.assertIn("File 'xxx_doesnotexist' not found.", err)
|
||||
|
||||
|
||||
@@ -44,16 +44,16 @@ class Test1445(TestCase):
|
||||
def test_alias_single_word(self):
|
||||
"""Verify single-word aliases"""
|
||||
self.t.config('alias.when', 'execute date')
|
||||
code, out, err = self.t(('when',))
|
||||
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):
|
||||
"""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('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)
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ class Test1447(TestCase):
|
||||
def test_filter_uda(self):
|
||||
"""Verify single-word aliases"""
|
||||
self.t.config('uda.sep.type', 'string')
|
||||
self.t(('add', 'one'))
|
||||
self.t(('add', 'two', 'sep:foo'))
|
||||
code, out, err = self.t(('sep:', 'list'))
|
||||
self.t('add one')
|
||||
self.t('add two sep:foo')
|
||||
code, out, err = self.t('sep: list')
|
||||
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
|
||||
self.assertIn('one', out)
|
||||
|
||||
|
||||
@@ -40,23 +40,19 @@ from basetest import Task, TestCase
|
||||
class Test1469(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
self.t(('add', 'foo'))
|
||||
self.t(('add', 'neue Badmöbel kaufen'))
|
||||
self.t('add foo')
|
||||
self.t('add "neue Badmöbel kaufen"')
|
||||
|
||||
def test_implicit_search_sensitive_regex(self):
|
||||
"""Implicit search, case sensitive, regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=yes',
|
||||
'rc.regex=on'))
|
||||
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)
|
||||
|
||||
def test_implicit_search_sensitive_noregex(self):
|
||||
"""Implicit search, case sensitive, no regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=yes',
|
||||
'rc.regex=off'))
|
||||
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)
|
||||
@@ -64,9 +60,7 @@ class Test1469(TestCase):
|
||||
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin')
|
||||
def test_implicit_search_insensitive_regex(self):
|
||||
"""Implicit search, case insensitive, regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=no',
|
||||
'rc.regex=on'))
|
||||
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)
|
||||
@@ -74,27 +68,21 @@ class Test1469(TestCase):
|
||||
|
||||
def test_implicit_search_insensitive_noregex(self):
|
||||
"""Implicit search, case insensitive, no regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=no',
|
||||
'rc.regex=off'))
|
||||
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)
|
||||
|
||||
def test_explicit_search_sensitive_regex(self):
|
||||
"""Explicit search, case sensitive, regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=yes',
|
||||
'rc.regex=on'))
|
||||
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)
|
||||
|
||||
def test_explicit_search_sensitive_noregex(self):
|
||||
"""Explicit search, case sensitive, no regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=yes',
|
||||
'rc.regex=off'))
|
||||
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)
|
||||
@@ -102,18 +90,14 @@ class Test1469(TestCase):
|
||||
@unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin')
|
||||
def test_explicit_search_insensitive_regex(self):
|
||||
"""Explicit search, case insensitive, regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=no',
|
||||
'rc.regex=on'))
|
||||
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_explicit_search_insensitive_noregex(self):
|
||||
"""Explicit search, case insensitive, no regex """
|
||||
code, out, err = self.t(('list', '/möbel/',
|
||||
'rc.search.case.sensitive=no',
|
||||
'rc.regex=off'))
|
||||
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)
|
||||
|
||||
@@ -44,10 +44,10 @@ class Test1486(TestCase):
|
||||
"""Verify waiting report shows waiting tasks"""
|
||||
self.t.config('uda.sep.type', 'string')
|
||||
|
||||
self.t(('add', 'regular'))
|
||||
self.t(('add', 'waited', 'wait:later'))
|
||||
self.t('add regular')
|
||||
self.t('add waited wait:later')
|
||||
|
||||
code, out, err = self.t(('waiting',))
|
||||
code, out, err = self.t('waiting')
|
||||
self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code))
|
||||
self.assertIn('waited', out)
|
||||
self.assertNotIn('regular', out)
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -35,6 +35,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from basetest import Task, TestCase
|
||||
|
||||
|
||||
class Test1510(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
@@ -52,8 +53,8 @@ class Test1510(TestCase):
|
||||
backlog.data with empty string value
|
||||
"""
|
||||
|
||||
self.t(('add', 'test', 'due:2015-05-05'))
|
||||
self.t(('1', 'mod', 'due:'))
|
||||
self.t('add test due:2015-05-05')
|
||||
self.t('1 mod due:')
|
||||
self.assertNoEmptyValueInBacklog('due')
|
||||
|
||||
def test_no_empty_value_for_empty_priority_in_backlog(self):
|
||||
@@ -62,10 +63,10 @@ class Test1510(TestCase):
|
||||
backlog.data with empty string value
|
||||
"""
|
||||
|
||||
self.t(('add', 'test', 'pri:""'))
|
||||
self.t(('add', 'test2', "pri:''"))
|
||||
self.t(('add', 'test3', "pri:"))
|
||||
self.t(('add', 'test4', "pri:H"))
|
||||
self.t('add test pri:""')
|
||||
self.t("add test2 pri:''")
|
||||
self.t("add test3 pri:")
|
||||
self.t("add test4 pri:H")
|
||||
self.assertNoEmptyValueInBacklog('priority')
|
||||
|
||||
def test_no_empty_value_for_empty_project_in_backlog(self):
|
||||
@@ -74,10 +75,10 @@ class Test1510(TestCase):
|
||||
backlog.data with empty string value
|
||||
"""
|
||||
|
||||
self.t(('add', 'test', 'project:""'))
|
||||
self.t(('add', 'test2', "project:''"))
|
||||
self.t(('add', 'test3', "project:"))
|
||||
self.t(('add', 'test4', "project:random"))
|
||||
self.t('add test project:""')
|
||||
self.t("add test2 project:''")
|
||||
self.t("add test3 project:")
|
||||
self.t("add test4 project:random")
|
||||
self.assertNoEmptyValueInBacklog('project')
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,39 +1,38 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
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__)))
|
||||
|
||||
from basetest import Task, TestCase, Taskd, ServerTestCase
|
||||
from basetest import Task, TestCase
|
||||
|
||||
|
||||
class TestBug1527(TestCase):
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -46,8 +46,8 @@ class Test1542(TestCase):
|
||||
Make sure the numeric UDA value 1187962 does not get converted to
|
||||
scientific notation on export.
|
||||
"""
|
||||
self.t(('add', 'large', 'bugid:1187962'))
|
||||
code, out, err = self.t(('1', 'export'))
|
||||
self.t('add large bugid:1187962')
|
||||
code, out, err = self.t('1 export')
|
||||
self.assertIn("\"bugid\":1187962,", out)
|
||||
|
||||
def test_small_numeric_uda_retains_value(self):
|
||||
@@ -55,8 +55,8 @@ class Test1542(TestCase):
|
||||
Make sure the numeric UDA value 43.21 does not get converted to
|
||||
integer on export.
|
||||
"""
|
||||
self.t(('add', 'small', 'bugid:43.21'))
|
||||
code, out, err = self.t(('1', 'export'))
|
||||
self.t('add small bugid:43.21')
|
||||
code, out, err = self.t('1 export')
|
||||
self.assertIn("\"bugid\":43.21", out)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -35,6 +35,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from basetest import Task, TestCase
|
||||
|
||||
|
||||
class Test1549(TestCase):
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
@@ -51,7 +52,7 @@ class Test1549(TestCase):
|
||||
"""
|
||||
|
||||
# This command will hang and therefore timeout in 2.4.1.
|
||||
code, out, err = self.t(('add', '1e x'))
|
||||
code, out, err = self.t('add 1e x')
|
||||
self.assertIn("Created task 1.", out)
|
||||
|
||||
|
||||
|
||||
54
test/tw-21.t
54
test/tw-21.t
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -43,8 +43,8 @@ class TestBug21(TestCase):
|
||||
self.t.config('uda.foo.type', 'string')
|
||||
self.t.config('uda.foo.label', 'FOO')
|
||||
|
||||
self.t(("add", "this", "is", "a", "foo", "bar"))
|
||||
code, out, err = self.t(("1", "info"))
|
||||
self.t("add this is a foo bar")
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
self.assertIn("this is a foo bar", out)
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -41,30 +41,25 @@ class TestBug252(TestCase):
|
||||
|
||||
def test_done_stop(self):
|
||||
"""done should also stop a task timer"""
|
||||
command = ("add", "Timeit")
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("add Timeit")
|
||||
|
||||
# Starting the newly added task
|
||||
command = ("1", "start")
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("1 start")
|
||||
|
||||
notexpected = "Start deleted"
|
||||
self.assertNotIn(notexpected, out)
|
||||
|
||||
# Completing the task should also stop the timer
|
||||
command = ("1", "done")
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("1 done")
|
||||
|
||||
# Confirm that "start" was removed
|
||||
command = ("1", "info")
|
||||
code, out, err = self.t(command)
|
||||
code, out, err = self.t("1 info")
|
||||
|
||||
expected = "Start deleted"
|
||||
self.assertIn(expected, out)
|
||||
|
||||
# Confirm that the timer was indeed stopped
|
||||
command = ("1", "stop")
|
||||
code, out, err = self.t.runError(command)
|
||||
code, out, err = self.t.runError("1 stop")
|
||||
|
||||
expected = "Task 1 'Timeit' not started."
|
||||
self.assertIn(expected, out)
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -41,75 +41,63 @@ class TestBug262(TestCase):
|
||||
cls.t = Task()
|
||||
|
||||
cls.absent = "Taskwarrior project"
|
||||
command = ("add", "proj:tw", cls.absent)
|
||||
cls.t(command)
|
||||
cls.t(("add", "proj:tw", cls.absent))
|
||||
|
||||
cls.present = "Another project"
|
||||
command = ("add", "proj:something_else", cls.present)
|
||||
cls.t(command)
|
||||
cls.t(("add", "proj:something_else", cls.present))
|
||||
|
||||
def _check_expectation(self, command):
|
||||
code, out, err = self.t(command)
|
||||
# Add quotes to ensure spaces around are not split by the shell lexer
|
||||
code, out, err = self.t((command,))
|
||||
|
||||
self.assertIn(self.present, out)
|
||||
self.assertNotIn(self.absent, out)
|
||||
|
||||
def test_proj_isnt(self):
|
||||
"""project.isnt works"""
|
||||
command = ("project.isnt:tw",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation("project.isnt:tw")
|
||||
|
||||
def test_proj_isnt_spaces(self):
|
||||
"""project.isnt works if wrapped in spaces"""
|
||||
command = (" project.isnt:tw ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" project.isnt:tw ")
|
||||
|
||||
def test_proj_isnt_space_leading(self):
|
||||
"""project.isnt works if leading space is present"""
|
||||
command = (" project.isnt:tw",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" project.isnt:tw")
|
||||
|
||||
def test_proj_isnt_space_trailing(self):
|
||||
"""project.isnt works if trailing space is present"""
|
||||
command = ("project.isnt:tw ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation("project.isnt:tw ")
|
||||
|
||||
def test_proj_isnt_parenthesis(self):
|
||||
"""project.isnt works within parenthesis"""
|
||||
command = ("(project.isnt:tw)",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation("(project.isnt:tw)")
|
||||
|
||||
def test_proj_isnt_parenthesis_space_leading(self):
|
||||
"""project.isnt works within parenthesis after a leading space"""
|
||||
command = (" (project.isnt:tw)",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" (project.isnt:tw)")
|
||||
|
||||
def test_proj_isnt_parenthesis_space_leading_double(self):
|
||||
"""project.isnt works within parenthesis after a double leading space
|
||||
"""
|
||||
command = (" ( project.isnt:tw)",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" ( project.isnt:tw)")
|
||||
|
||||
def test_proj_isnt_parenthesis_space_trailing(self):
|
||||
"""project.isnt works within parenthesis after a trailing space"""
|
||||
command = ("(project.isnt:tw) ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation("(project.isnt:tw) ")
|
||||
|
||||
def test_proj_isnt_parenthesis_space_trailing_double(self):
|
||||
"""project.isnt works within parenthesis after a double trailing space
|
||||
"""
|
||||
command = ("(project.isnt:tw ) ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation("(project.isnt:tw ) ")
|
||||
|
||||
def test_proj_isnt_spaces_parenthesis(self):
|
||||
"""project.isnt works within parenthesis and spaces"""
|
||||
command = (" (project.isnt:tw) ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" (project.isnt:tw) ")
|
||||
|
||||
def test_proj_isnt_spaces_parenthesis_double(self):
|
||||
"""project.isnt works within parenthesis and double spaces"""
|
||||
command = (" ( project.isnt:tw ) ",)
|
||||
self._check_expectation(command)
|
||||
self._check_expectation(" ( project.isnt:tw ) ")
|
||||
|
||||
if __name__ == "__main__":
|
||||
from simpletap import TAPTestRunner
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -41,10 +41,10 @@ class TestBug268(TestCase):
|
||||
def test_add_hyphenated(self):
|
||||
"""escaped backslashes do not work with 'modify'"""
|
||||
|
||||
self.t(("add", "a", "b", "or", "c"))
|
||||
self.t(("1", "modify", "/a b/a\/b/"))
|
||||
self.t("add a b or c")
|
||||
self.t('1 modify "/a b/a\/b/"')
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertIn("a/b or c", out)
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
#!/usr/bin/env python2.7
|
||||
# -*- coding: utf-8 -*-
|
||||
################################################################################
|
||||
##
|
||||
## Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
@@ -50,42 +50,42 @@ class Test285(TestCase):
|
||||
# due:1month - - - - - - - ?
|
||||
# due:1year - - - - - - - -
|
||||
|
||||
cls.t(('add', 'due_last_week', 'due:-1week'))
|
||||
cls.t(('add', 'due_yesterday', 'due:-1day'))
|
||||
cls.t(('add', 'due_earlier_today', 'due:today'))
|
||||
cls.t(('add', 'due_later_today', 'due:tomorrow'))
|
||||
cls.t(('add', 'due_three_days', 'due:3days'))
|
||||
cls.t(('add', 'due_next_month', 'due:1month'))
|
||||
cls.t(('add', 'due_next_year', 'due:1year'))
|
||||
cls.t('add due_last_week due:-1week')
|
||||
cls.t('add due_yesterday due:-1day')
|
||||
cls.t('add due_earlier_today due:today')
|
||||
cls.t('add due_later_today due:tomorrow')
|
||||
cls.t('add due_three_days due:3days')
|
||||
cls.t('add due_next_month due:1month')
|
||||
cls.t('add due_next_year due:1year')
|
||||
|
||||
def test_overdue(self):
|
||||
"""+OVERDUE"""
|
||||
code, out, err = self.t(("+OVERDUE", "count"))
|
||||
code, out, err = self.t("+OVERDUE count")
|
||||
self.assertEqual(out, "3\n", "+OVERDUE == 3 tasks")
|
||||
|
||||
def test_yesterday(self):
|
||||
"""+YESTERDAY"""
|
||||
code, out, err = self.t(("+YESTERDAY", "count"))
|
||||
code, out, err = self.t("+YESTERDAY count")
|
||||
self.assertEqual(out, "1\n", "+YESTERDAY == 1 task")
|
||||
|
||||
def test_due(self):
|
||||
"""+DUE"""
|
||||
code, out, err = self.t(("+DUE", "count"))
|
||||
code, out, err = self.t("+DUE count")
|
||||
self.assertEqual(out, "3\n", "+DUE == 3 task")
|
||||
|
||||
def test_today(self):
|
||||
"""+TODAY"""
|
||||
code, out, err = self.t(("+TODAY", "count"))
|
||||
code, out, err = self.t("+TODAY count")
|
||||
self.assertEqual(out, "1\n", "+TODAY == 1 task")
|
||||
|
||||
def test_duetoday(self):
|
||||
"""+DUETODAY"""
|
||||
code, out, err = self.t(("+DUETODAY", "count"))
|
||||
code, out, err = self.t("+DUETODAY count")
|
||||
self.assertEqual(out, "1\n", "+DUETODAY == 1 task")
|
||||
|
||||
def test_tomorrow(self):
|
||||
"""+TOMORROW"""
|
||||
code, out, err = self.t(("+TOMORROW", "count"))
|
||||
code, out, err = self.t("+TOMORROW count")
|
||||
self.assertEqual(out, "1\n", "+TOMORROW == 1 task")
|
||||
|
||||
|
||||
|
||||
@@ -52,18 +52,18 @@ class TestUdaReports(TestCase):
|
||||
cls.t.config("report.bad.labels", "ID,Extra2")
|
||||
cls.t.config("report.bad.sort", "ID")
|
||||
|
||||
cls.t(("add", "one", "extra:foo"))
|
||||
cls.t("add one extra:foo")
|
||||
|
||||
def test_uda_show_report(self):
|
||||
"""UDA shown in report"""
|
||||
|
||||
code, out, err = self.t(("good",))
|
||||
code, out, err = self.t("good")
|
||||
self.assertIn("foo", out)
|
||||
|
||||
def test_uda_no_show_report(self):
|
||||
"""UDA not shown in report"""
|
||||
|
||||
code, out, err = self.t.runError(("bad",))
|
||||
code, out, err = self.t.runError("bad")
|
||||
self.assertNotIn("foo", out)
|
||||
self.assertIn("Unrecognized column name", err)
|
||||
|
||||
|
||||
@@ -44,15 +44,15 @@ class TestUDACustomSort(TestCase):
|
||||
cls.t.config('uda.foo.values', 'H,M,L,')
|
||||
cls.t.config('report.list.columns', 'id,description,foo')
|
||||
cls.t.config('report.list.labels', 'ID,Desc,Foo')
|
||||
cls.t(('add', 'four', 'foo:H'))
|
||||
cls.t(('add', 'three', 'foo:M'))
|
||||
cls.t(('add', 'two', 'foo:L'))
|
||||
cls.t(('add', 'one'))
|
||||
cls.t('add four foo:H')
|
||||
cls.t('add three foo:M')
|
||||
cls.t('add two foo:L')
|
||||
cls.t('add one')
|
||||
|
||||
def test_ascending(self):
|
||||
"""Ascending sort order"""
|
||||
self.t.config('uda.foo.values', 'H,M,L,')
|
||||
code, out, err = self.t(('rc.report.list.sort:foo+', 'list'))
|
||||
code, out, err = self.t('rc.report.list.sort:foo+ list')
|
||||
|
||||
one = out.find('one')
|
||||
two = out.find('two')
|
||||
@@ -66,7 +66,7 @@ class TestUDACustomSort(TestCase):
|
||||
def test_descending(self):
|
||||
"""Descending sort order"""
|
||||
self.t.config('uda.foo.values', 'H,M,L,')
|
||||
code, out, err = self.t(('rc.report.list.sort:foo-', 'list'))
|
||||
code, out, err = self.t('rc.report.list.sort:foo- list')
|
||||
|
||||
one = out.find('one')
|
||||
two = out.find('two')
|
||||
@@ -80,7 +80,7 @@ class TestUDACustomSort(TestCase):
|
||||
def test_ridiculous(self):
|
||||
"""Ridiculous sort order"""
|
||||
self.t.config('uda.foo.values', 'H,M,,L')
|
||||
code, out, err = self.t(('rc.report.list.sort:foo-', 'list'))
|
||||
code, out, err = self.t('rc.report.list.sort:foo- list')
|
||||
|
||||
one = out.find('one')
|
||||
two = out.find('two')
|
||||
|
||||
20
test/undo.t
20
test/undo.t
@@ -42,23 +42,23 @@ class TestUndo(TestCase):
|
||||
|
||||
def test_add_undo(self):
|
||||
"""'add' then 'undo'"""
|
||||
code, out, err = self.t(('add', 'one'))
|
||||
code, out, err = self.t(('_get', '1.status'))
|
||||
code, out, err = self.t('add one')
|
||||
code, out, err = self.t('_get 1.status')
|
||||
self.assertEqual(out.strip(), 'pending')
|
||||
code, out, err = self.t(('undo'))
|
||||
code, out, err = self.t(('_get', '1.status'))
|
||||
code, out, err = self.t('undo')
|
||||
code, out, err = self.t('_get 1.status')
|
||||
self.assertEqual(out.strip(), '')
|
||||
|
||||
def test_add_done_undo(self):
|
||||
"""'add' then 'done' then 'undo'"""
|
||||
code, out, err = self.t(('add', 'two'))
|
||||
code, out, err = self.t(('_get', '1.status'))
|
||||
code, out, err = self.t('add two')
|
||||
code, out, err = self.t('_get 1.status')
|
||||
self.assertEqual(out.strip(), 'pending')
|
||||
code, out, err = self.t(('1', 'done'))
|
||||
code, out, err = self.t(('_get', '1.status'))
|
||||
code, out, err = self.t('1 done')
|
||||
code, out, err = self.t('_get 1.status')
|
||||
self.assertEqual(out.strip(), 'completed')
|
||||
code, out, err = self.t(('undo'))
|
||||
code, out, err = self.t(('_get', '1.status'))
|
||||
code, out, err = self.t('undo')
|
||||
code, out, err = self.t('_get 1.status')
|
||||
self.assertEqual(out.strip(), 'pending')
|
||||
|
||||
def test_undo_en_passant(self):
|
||||
|
||||
@@ -41,20 +41,20 @@ class TestUpgrade(TestCase):
|
||||
|
||||
def test_upgrade_to_recurring(self):
|
||||
"""Upgrade a task to recurring"""
|
||||
self.t(("add", "one"))
|
||||
self.t("add one")
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertRegexpMatches(out, "Status\s+Pending")
|
||||
|
||||
self.t(("1", "modify", "due:tomorrow", "recur:weekly"))
|
||||
self.t(("list",))
|
||||
self.t("1 modify due:tomorrow recur:weekly")
|
||||
self.t("list")
|
||||
|
||||
code, out, err = self.t(("1", "info"))
|
||||
code, out, err = self.t("1 info")
|
||||
self.assertRegexpMatches(out, "Status\s+Recurring")
|
||||
self.assertRegexpMatches(out, "Recurrence\s+weekly")
|
||||
|
||||
# Also check for the presence of a children task with pending state
|
||||
code, out, err = self.t(("2", "info"))
|
||||
code, out, err = self.t("2 info")
|
||||
self.assertRegexpMatches(out, "Status\s+Pending")
|
||||
self.assertRegexpMatches(out, "Recurrence\s+weekly")
|
||||
|
||||
|
||||
@@ -43,16 +43,16 @@ class TestVerbosity(TestCase):
|
||||
self.t = Task()
|
||||
self.t.config("print.empty.columns", "yes")
|
||||
|
||||
self.t(("add", "Sample"))
|
||||
self.t("add Sample")
|
||||
|
||||
# TODO Verbosity: 'edit'
|
||||
|
||||
def test_verbosity_new_id(self):
|
||||
"""Verbosity new-id"""
|
||||
code, out, err = self.t(("rc.verbose:new-id", "add", "Sample1"))
|
||||
code, out, err = self.t("rc.verbose:new-id add Sample1")
|
||||
self.assertRegexpMatches(out, r"Created task \d")
|
||||
|
||||
code, out, err = self.t(("rc.verbose:nothing", "add", "Sample2"))
|
||||
code, out, err = self.t("rc.verbose:nothing add Sample2")
|
||||
self.assertNotRegexpMatches(out, r"Created task \d")
|
||||
|
||||
def test_verbosity_new_uuid(self):
|
||||
@@ -62,7 +62,7 @@ class TestVerbosity(TestCase):
|
||||
|
||||
def test_verbosity_label(self):
|
||||
"""Verbosity label"""
|
||||
code, out, err = self.t(("rc.verbose:label", "ls"))
|
||||
code, out, err = self.t("rc.verbose:label ls")
|
||||
self.assertRegexpMatches(
|
||||
out,
|
||||
"ID.+A.+D.+Project.+Tags.+R.+Wait.+S.+Due.+Until.+Description"
|
||||
@@ -70,14 +70,14 @@ class TestVerbosity(TestCase):
|
||||
|
||||
def test_verbosity_affected(self):
|
||||
"""Verbosity affected"""
|
||||
code, out, err = self.t(("rc.verbose:affected", "ls"))
|
||||
code, out, err = self.t("rc.verbose:affected ls")
|
||||
|
||||
expected = re.compile(r"^\d+ tasks?$", re.MULTILINE)
|
||||
self.assertRegexpMatches(out, expected)
|
||||
|
||||
def test_verbosity_off(self):
|
||||
"""Verbosity off"""
|
||||
code, out, err = self.t(("rc.verbose:nothing", "ls"))
|
||||
code, out, err = self.t("rc.verbose:nothing ls")
|
||||
|
||||
expected = re.compile(r"^\d+ tasks?$", re.MULTILINE)
|
||||
self.assertNotRegexpMatches(out, expected)
|
||||
@@ -85,7 +85,7 @@ class TestVerbosity(TestCase):
|
||||
|
||||
def test_verbosity_special(self):
|
||||
"""Verbosity special"""
|
||||
code, out, err = self.t(("rc.verbose:special", "1", "mod", "+next"))
|
||||
code, out, err = self.t("rc.verbose:special 1 mod +next")
|
||||
|
||||
self.assertIn("The 'next' special tag will boost the urgency of this "
|
||||
"task so it appears on the 'next' report.", out)
|
||||
@@ -96,30 +96,30 @@ class TestVerbosity(TestCase):
|
||||
def count_blank_lines(x):
|
||||
return len(filter(operator.not_, x.splitlines()))
|
||||
|
||||
code, out, err = self.t(("rc.verbose:nothing", "ls"))
|
||||
code, out, err = self.t("rc.verbose:nothing ls")
|
||||
self.assertEqual(count_blank_lines(out), 0)
|
||||
|
||||
code, out, err = self.t(("rc.verbose:blank", "ls"))
|
||||
code, out, err = self.t("rc.verbose:blank ls")
|
||||
self.assertEqual(count_blank_lines(out), 2)
|
||||
|
||||
def test_verbosity_header(self):
|
||||
"""Verbosity header"""
|
||||
|
||||
code, out, err = self.t(("rc.verbose:nothing", "ls"))
|
||||
code, out, err = self.t("rc.verbose:nothing ls")
|
||||
self.assertNotIn("TASKRC override:", err)
|
||||
self.assertNotIn("TASKDATA override:", err)
|
||||
|
||||
code, out, err = self.t(("rc.verbose:header", "ls"))
|
||||
code, out, err = self.t("rc.verbose:header ls")
|
||||
self.assertIn("TASKRC override:", err)
|
||||
self.assertIn("TASKDATA override:", err)
|
||||
|
||||
def test_verbosity_project(self):
|
||||
"""Verbosity project"""
|
||||
|
||||
code, out, err = self.t(("rc.verbose:nothing", "add", "proj:T", "one"))
|
||||
code, out, err = self.t("rc.verbose:nothing add proj:T one")
|
||||
self.assertNotIn("The project 'T' has changed.", err)
|
||||
|
||||
code, out, err = self.t(("rc.verbose:project", "add", "proj:T", "two"))
|
||||
code, out, err = self.t("rc.verbose:project add proj:T two")
|
||||
self.assertIn("The project 'T' has changed.", err)
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestVersion(TestCase):
|
||||
|
||||
def test_copyright_up_to_date(self):
|
||||
"""Copyright is current"""
|
||||
code, out, err = self.t(("version",))
|
||||
code, out, err = self.t("version")
|
||||
|
||||
expected = "Copyright \(C\) \d{4} - %d" % (datetime.now().year,)
|
||||
self.assertRegexpMatches(out, expected)
|
||||
@@ -70,7 +70,7 @@ class TestVersion(TestCase):
|
||||
|
||||
def test_version(self):
|
||||
"""version command outputs expected version and license"""
|
||||
code, out, err = self.t(("version",))
|
||||
code, out, err = self.t("version")
|
||||
|
||||
expected = "task {0}".format(self.slurp())
|
||||
self.assertIn(expected, out)
|
||||
@@ -84,7 +84,7 @@ class TestVersion(TestCase):
|
||||
|
||||
def test_under_version(self):
|
||||
"""_version outputs expected version and syntax"""
|
||||
code, out, err = self.t(("_version",))
|
||||
code, out, err = self.t("_version")
|
||||
|
||||
# version = "x.x.x (git-hash)" or simply "x.x.x"
|
||||
# corresponding to "compiled from git" or "compiled from tarball"
|
||||
|
||||
14
test/wait.t
14
test/wait.t
@@ -49,16 +49,16 @@ class TestWait(TestCase):
|
||||
# [1] an hour before current time (visible 'now')
|
||||
# [2] 22 hours after current time (hidden 'now', visible 'tomorrow')
|
||||
self.t.faketime("-2h")
|
||||
self.t(("add", "wait:1h", "visible"))
|
||||
self.t(("add", "wait:1d", "hidden"))
|
||||
self.t("add wait:1h visible")
|
||||
self.t("add wait:1d hidden")
|
||||
|
||||
self.t.faketime()
|
||||
code, out, err = self.t(("ls",))
|
||||
code, out, err = self.t("ls")
|
||||
self.assertIn("visible", out)
|
||||
self.assertNotIn("hidden", out)
|
||||
|
||||
self.t.faketime("+1d")
|
||||
code, out, err = self.t(("ls",))
|
||||
code, out, err = self.t("ls")
|
||||
self.assertIn("visible", out)
|
||||
self.assertIn("hidden", out)
|
||||
|
||||
@@ -71,12 +71,12 @@ class TestBug434(TestCase):
|
||||
|
||||
def test_complete_waiting(self):
|
||||
"""completion of waiting tasks"""
|
||||
self.t(("add", "One", "wait:tomorrow"))
|
||||
self.t("add One wait:tomorrow")
|
||||
|
||||
code, out, err = self.t(("1", "done"))
|
||||
code, out, err = self.t("1 done")
|
||||
self.assertIn("Completed 1 task", out)
|
||||
|
||||
code, out, err = self.t.runError(("ls",))
|
||||
code, out, err = self.t.runError("ls")
|
||||
self.assertNotIn("One", out)
|
||||
self.assertIn("No matches", err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user