diff --git a/src/Context.cpp b/src/Context.cpp index ddfe9fd19..9d2c16686 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -439,6 +439,7 @@ Context* Context::context; //////////////////////////////////////////////////////////////////////////////// Context& Context::getContext () { + assert (Context::context); return *Context::context; } diff --git a/src/commands/CmdVersion.cpp b/src/commands/CmdVersion.cpp index 0797c02f3..efdf90d6d 100644 --- a/src/commands/CmdVersion.cpp +++ b/src/commands/CmdVersion.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #ifdef HAVE_COMMIT @@ -70,6 +71,8 @@ int CmdVersion::execute (std::string& output) link.add (""); link.set (link.addRow (), 0, "Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man task-color', 'man task-sync' or at https://taskwarrior.org"); + Datetime now; + Color bold; if (Context::getContext ().color ()) bold = Color ("bold"); @@ -78,7 +81,7 @@ int CmdVersion::execute (std::string& output) << format ("{1} {2} built for ", bold.colorize (PACKAGE), bold.colorize (VERSION)) << osName () << '\n' - << "Copyright (C) 2006 - 2021 T. Babej, P. Beckingham, F. Hernandez." + << "Copyright (C) 2006 - " << now.year () << " T. Babej, P. Beckingham, F. Hernandez." << '\n' << '\n' << disclaimer.render () diff --git a/test/basetest/utils.py b/test/basetest/utils.py index c6a1970eb..ad68b8701 100644 --- a/test/basetest/utils.py +++ b/test/basetest/utils.py @@ -42,6 +42,9 @@ DEFAULT_HOOK_PATH = os.path.abspath( os.path.join("${CMAKE_SOURCE_DIR}", "test", "test_hooks") ) +# Source directory +SOURCE_DIR = os.path.abspath("${CMAKE_SOURCE_DIR}") + # Environment flags to control skipping of task tests TASKW_SKIP = os.environ.get("TASKW_SKIP", False) diff --git a/test/eval.test.cpp b/test/eval.test.cpp index 987df0617..85ed424c4 100644 --- a/test/eval.test.cpp +++ b/test/eval.test.cpp @@ -26,6 +26,7 @@ #include #include +#include #include //////////////////////////////////////////////////////////////////////////////// @@ -44,6 +45,8 @@ bool get (const std::string& name, Variant& value) int main (int, char**) { UnitTest t (52); + Context context; + Context::setContext(&context); // Test the source independently. Variant v; diff --git a/test/lexer.test.cpp b/test/lexer.test.cpp index 787b9c16a..8ebce5d4c 100644 --- a/test/lexer.test.cpp +++ b/test/lexer.test.cpp @@ -37,7 +37,7 @@ int main (int, char**) { #ifdef PRODUCT_TASKWARRIOR - UnitTest t (1253); + UnitTest t (1255); #else UnitTest t (1235); #endif diff --git a/test/run_all b/test/run_all index f20f092d1..70f060eb0 100755 --- a/test/run_all +++ b/test/run_all @@ -47,6 +47,9 @@ def run_test(testqueue, outqueue, threadname): if sys.version_info > (3,): out, err = out.decode('utf-8'), err.decode('utf-8') + if p.returncode != 0: + out = out + "\nnot ok - test executable failed\n" + output = ("# {0}\n".format(os.path.basename(test)), out, err) log.debug("Collected output %s", output) outqueue.put(output) diff --git a/test/t.test.cpp b/test/t.test.cpp index 69ac90a11..a6ea56268 100644 --- a/test/t.test.cpp +++ b/test/t.test.cpp @@ -33,6 +33,8 @@ int main (int, char**) { UnitTest test (49); + Context context; + Context::setContext(&context); // Ensure environment has no influence. unsetenv ("TASKDATA"); @@ -152,44 +154,10 @@ TODO Task::decode //////////////////////////////////////////////////////////////////////////////// Task task; - // (blank) - good = true; - try {task = Task ("");} - catch (const std::string& e){test.diag (e); good = false;} - test.notok (good, "Task::Task ('')"); - - // [] - good = true; - try {task = Task ("[]");} - catch (const std::string& e){test.diag (e); good = false;} - test.notok (good, "Task::Task ('[]')"); - - // [name:"value"] - good = true; - try {task = Task ("[name:\"value\"]");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, "Task::Task ('[name:\"value\"]')"); - test.is (task.get ("name"), "value", "name=value"); - - // [name:"one two"] - good = true; - try {task = Task ("[name:\"one two\"]");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, "Task::Task ('[name:\"one two\"]')"); - test.is (task.get ("name"), "one two", "name=one two"); - - // [one:two three:four] - good = true; - try {task = Task (R"([one:"two" three:"four"])");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, R"(Task::Task ('[one:"two" three:"four"]'))"); - test.is (task.get ("one"), "two", "one=two"); - test.is (task.get ("three"), "four", "three=four"); - // Task::set task = Task(); task.set ("name", "value"); - test.is (task.composeF4 (), "[name:\"value\"]", "Task::set"); + test.is (task.composeJSON (), "{\"name\":\"value\"}", "Task::set"); // Task::has test.ok (task.has ("name"), "Task::has"); @@ -197,18 +165,18 @@ TODO Task::decode // Task::get_int task.set ("one", 1); - test.is (task.composeF4 (), R"([name:"value" one:"1"])", "Task::set"); + test.is (task.composeJSON (), R"({"name":"value","one":"1"})", "Task::set"); test.is (task.get_int ("one"), 1, "Task::get_int"); // Task::get_ulong task.set ("two", "4294967295"); - test.is (task.composeF4 (), R"([name:"value" one:"1" two:"4294967295"])", "Task::set"); + test.is (task.composeJSON (), R"({"name":"value","one":"1","two":"4294967295"})", "Task::set"); test.is ((size_t)task.get_ulong ("two"), (size_t)4294967295UL, "Task::get_ulong"); // Task::remove task.remove ("one"); task.remove ("two"); - test.is (task.composeF4 (), "[name:\"value\"]", "Task::remove"); + test.is (task.composeJSON (), "{\"name\":\"value\"}", "Task::remove"); // Task::all test.is (task.all ().size (), (size_t)1, "Task::all size"); @@ -230,16 +198,14 @@ TODO Task::decode catch (const std::string& e){test.diag (e); good = false;} test.ok (good, "Task::Task ('{}')"); - // Verify tag handling is correct between F4 and JSON. + // Verify tag handling is correct Task t6; t6.set ("entry", "20130602T224000Z"); t6.set ("description", "DESC"); t6.addTag ("tag1"); - test.is (t6.composeF4 (), R"([description:"DESC" entry:"20130602T224000Z" tags:"tag1"])", "F4 good"); test.is (t6.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1"]})", "JSON good"); t6.addTag ("tag2"); - test.is (t6.composeF4 (), R"([description:"DESC" entry:"20130602T224000Z" tags:"tag1,tag2"])", "F4 good"); test.is (t6.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", "JSON good"); good = true; @@ -247,7 +213,6 @@ TODO Task::decode try {t7 = Task (R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})");} catch (const std::string& e){test.diag (e); good = false;} test.ok (good, "Task::Task ('{two tags}')"); - test.is (t7.composeF4 (), R"([description:"DESC" entry:"1370212800" tags:"tag1,tag2"])", "F4 good"); test.is (t7.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", "JSON good"); return 0; diff --git a/test/tdb2.test.cpp b/test/tdb2.test.cpp index 398a4b130..f469dacfb 100644 --- a/test/tdb2.test.cpp +++ b/test/tdb2.test.cpp @@ -37,16 +37,15 @@ void cleardb () { // Remove any residual test files. rmdir ("./extensions"); - unlink ("./pending.data"); - unlink ("./completed.data"); - unlink ("./undo.data"); - unlink ("./backlog.data"); + unlink ("./taskchampion.sqlite3"); } //////////////////////////////////////////////////////////////////////////////// int main (int, char**) { UnitTest t (12); + Context context; + Context::setContext(&context); // Ensure environment has no influence. unsetenv ("TASKDATA"); @@ -84,8 +83,8 @@ int main (int, char**) t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task"); t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks"); - t.is ((int) num_reverts_possible, 3, "TDB2 after add, 3 undo lines"); - t.is ((int) num_local_changes, 1, "TDB2 after add, 1 backlog task"); + t.is ((int) num_reverts_possible, 1, "TDB2 after add, 1 revert possible"); + t.is ((int) num_local_changes, 6, "TDB2 after add, 6 local changes"); task.set ("description", "This is a test"); context.tdb2.modify (task); @@ -95,10 +94,10 @@ int main (int, char**) num_reverts_possible = context.tdb2.num_reverts_possible (); num_local_changes = context.tdb2.num_local_changes (); - t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task"); - t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks"); - t.is ((int) num_reverts_possible, 7, "TDB2 after add, 7 undo lines"); - t.is ((int) num_local_changes, 2, "TDB2 after add, 2 backlog task"); + t.is ((int) pending.size (), 1, "TDB2 after set, 1 pending task"); + t.is ((int) completed.size (), 0, "TDB2 after set, 0 completed tasks"); + t.is ((int) num_reverts_possible, 1, "TDB2 after set, 1 revert possible"); + t.is ((int) num_local_changes, 7, "TDB2 after set, 7 local changes"); // Reset for reuse. cleardb (); diff --git a/test/test.cpp b/test/test.cpp index 16a7fb176..7f092af90 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -128,7 +128,8 @@ void UnitTest::ok (bool expression, const std::string& name, bool expfail /* = f } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -158,7 +159,8 @@ void UnitTest::notok (bool expression, const std::string& name, bool expfail /* } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -187,7 +189,8 @@ void UnitTest::is (bool actual, bool expected, const std::string& name, bool exp } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -220,7 +223,8 @@ void UnitTest::is (size_t actual, size_t expected, const std::string& name, bool } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -253,7 +257,8 @@ void UnitTest::is (int actual, int expected, const std::string& name, bool expfa } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -286,7 +291,8 @@ void UnitTest::is (double actual, double expected, const std::string& name, bool } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -319,7 +325,8 @@ void UnitTest::is (double actual, double expected, double tolerance, const std:: } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -352,7 +359,8 @@ void UnitTest::is (unsigned char actual, unsigned char expected, const std::stri } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -389,7 +397,8 @@ void UnitTest::is ( } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter @@ -427,7 +436,8 @@ void UnitTest::is ( } else { - ++_failed; + if (success == expfail) + ++_failed; std::cout << red ("not ok") << " " << _counter diff --git a/test/util.test.cpp b/test/util.test.cpp index 6f554f3f6..74901dfd5 100644 --- a/test/util.test.cpp +++ b/test/util.test.cpp @@ -35,6 +35,8 @@ int main (int, char**) { UnitTest t (19); + Context context; + Context::setContext(&context); // Ensure environment has no influence. unsetenv ("TASKDATA"); diff --git a/test/version.test.py b/test/version.test.py index cf30f28b4..747eacac0 100755 --- a/test/version.test.py +++ b/test/version.test.py @@ -35,7 +35,7 @@ from datetime import datetime sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase -from basetest.utils import run_cmd_wait +from basetest.utils import run_cmd_wait, SOURCE_DIR class TestVersion(TestCase): @@ -50,7 +50,6 @@ class TestVersion(TestCase): self.assertIn("You must specify a command or a task to modify", err) - @unittest.skip(reason="See #3424") def test_copyright_up_to_date(self): """Copyright is current""" code, out, err = self.t("version") @@ -58,18 +57,16 @@ class TestVersion(TestCase): expected = r"Copyright \(C\) \d{4} - %d" % (datetime.now().year,) self.assertRegex(out, expected) - def slurp(self, file="../CMakeLists.txt"): - number = r"\.".join(["[0-9]+"] * 3) - ver = re.compile("^set \\(PROJECT_VERSION \"({0}[^\"]*)\"\\)$".format(number)) + def slurp(self, file=os.path.join(SOURCE_DIR, "CMakeLists.txt")): + number = "\.".join(["[0-9]+"] * 3) + ver = re.compile("^ *VERSION ({0}[^\"]*)$".format(number)) with open(file) as fh: for line in fh: - if "PROJECT_VERSION" in line: - match = ver.match(line) - if match: - return match.group(1) + match = ver.match(line) + if match: + return match.group(1).strip() raise ValueError("Couldn't find matching version in {0}".format(file)) - @unittest.skip(reason="See #3424") def test_version(self): """version command outputs expected version and license""" code, out, err = self.t("version") @@ -79,7 +76,6 @@ class TestVersion(TestCase): self.assertIn("MIT license", out) self.assertIn("https://taskwarrior.org", out) - @unittest.skip(reason="See #3424") def test_under_version(self): """_version and diagnostics output expected version and syntax""" code, out, err = self.t("_version") diff --git a/test/view.test.cpp b/test/view.test.cpp index cdf4b4685..7c0e4f500 100644 --- a/test/view.test.cpp +++ b/test/view.test.cpp @@ -43,6 +43,8 @@ extern std::string configurationDefaults; int main (int, char**) { UnitTest t (1); + Context context; + Context::setContext(&context); // Ensure environment has no influence. unsetenv ("TASKDATA");