From 61fdc0da5298b3b30724b152e7c222ebfeabcc47 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 7 Apr 2013 00:09:16 -0400 Subject: [PATCH] Unit Tests - Updated test class to conform to coding standards. - Implemented TAP.py to allow Python unit tests. --- test/.gitignore | 1 + test/TAP.py | 132 +++++++++++++++++++++++++++++++++++ test/test.cpp | 182 ++++++++++++++++++++++++------------------------ test/test.h | 12 ++-- 4 files changed, 230 insertions(+), 97 deletions(-) create mode 100644 test/TAP.py diff --git a/test/.gitignore b/test/.gitignore index 616db93d7..890d93fa8 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,4 +1,5 @@ *.o +*.pyc *.data *.log autocomplete.t diff --git a/test/TAP.py b/test/TAP.py new file mode 100644 index 000000000..32c6a8faa --- /dev/null +++ b/test/TAP.py @@ -0,0 +1,132 @@ +################################################################################ +## taskwarrior - a command line task list manager. +## +## Copyright 2006-2013, 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 re + +class TAP: + """TAP-compliant unit test class.""" + + def __init__(self, planned = 0): + self.planned = planned + self.counter = 0 + self.passed = 0 + self.failed = 0 + self.skipped = 0 + print "1..%d " % self.planned + + def __del__(self): + percentPassed = 0.0 + if self.planned > 0: + percentPassed = (100.0 * self.passed) / max (self.planned, self.passed + self.failed + self.skipped) + + if self.counter < self.planned: + print "# Only %d tests, out of a planned %d were run." % (self.counter, self.planned) + self.skipped += self.planned - self.counter + elif self.counter > self.planned: + print "# %d tests were run, but only %d were planned." % (self.counter, self.planned) + + print "# %d passed, %d failed, %d skipped. %.2f%% passed." % (self.passed, self.failed, self.skipped, percentPassed) + + def plan(self, planned): + self.planned = planned + print "1..%d " % self.planned + + def planMore(self, extra): + self.planned += extra + print "1..%d" % self.planned + + def ok(self, expression, description): + self.counter += 1 + if bool(expression): + self.passed += 1 + print "ok %d - %s" % (self.counter, description) + else: + self.failed += 1 + print "not ok %d - %s" % (self.counter, description) + + def notok(self, expression, description): + self.counter += 1 + if not bool(expression): + self.passed += 1 + print "ok %d - %s" % (self.counter, description) + else: + self.failed += 1 + print "not ok %d - %s" % (self.counter, description) + + def equals(self, actual, expected, description): + self.counter += 1 + if actual == expected: + self.passed += 1 + print "ok %d - %s" % (self.counter, description) + else: + self.failed += 1 + print "not ok %d - %s" % (self.counter, description) + print "# expected:", expected, "\n# got:", actual + + def like(self, actual, pattern, description): + self.counter += 1 + if re.search(pattern, actual): + self.passed += 1 + print "ok %d - %s" % (self.counter, description) + else: + self.failed += 1 + print "not ok %d - %s" % (self.counter, description) + + def unlike(self, actual, pattern, description): + self.counter += 1 + if re.search(pattern, actual): + self.failed += 1 + print "not ok %d - %s" % (self.counter, description) + else: + self.passed += 1 + print "ok %d - %s" % (self.counter, description) + + def diag(self, stuff): + for line in stuff.strip().split("\n"): + print "#", line.strip() + + def skip(self, message): + self.counter += 1 + self.skipped += 1 + print "skip %d %s" % (self.counter, message) + + def passed(self, message): + self.counter += 1 + self.passed += 1 + print "ok %d %s" % (self.counter, message) + + def fail(self, message): + self.counter += 1 + self.failed += 1 + print "not ok %d %s" % (self.counter, message) + + def skip(self, message): + self.counter += 1 + self.skipped += 1 + print "skip %d %s" % (self.counter, message) + +################################################################################ diff --git a/test/test.cpp b/test/test.cpp index e5cddaa0e..82bcf73e5 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // taskwarrior - a command line task list manager. // -// Copyright 2006-2012, Paul Beckingham, Federico Hernandez. +// Copyright 2006-2013, 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 @@ -33,55 +33,55 @@ /////////////////////////////////////////////////////////////////////////////// UnitTest::UnitTest () -: mPlanned (0) -, mCounter (0) -, mPassed (0) -, mFailed (0) -, mSkipped (0) +: _planned (0) +, _counter (0) +, _passed (0) +, _failed (0) +, _skipped (0) { } /////////////////////////////////////////////////////////////////////////////// UnitTest::UnitTest (int planned) -: mPlanned (planned) -, mCounter (0) -, mPassed (0) -, mFailed (0) -, mSkipped (0) +: _planned (planned) +, _counter (0) +, _passed (0) +, _failed (0) +, _skipped (0) { - std::cout << "1.." << mPlanned << "\n"; + std::cout << "1.." << _planned << "\n"; } /////////////////////////////////////////////////////////////////////////////// UnitTest::~UnitTest () { float percentPassed = 0.0; - if (mPlanned > 0) - percentPassed = (100.0 * mPassed) / std::max (mPlanned, mPassed + mFailed + mSkipped); + if (_planned > 0) + percentPassed = (100.0 * _passed) / std::max (_planned, _passed + _failed + _skipped); - if (mCounter < mPlanned) + if (_counter < _planned) { std::cout << "# Only " - << mCounter + << _counter << " tests, out of a planned " - << mPlanned + << _planned << " were run.\n"; - mSkipped += mPlanned - mCounter; + _skipped += _planned - _counter; } - else if (mCounter > mPlanned) + else if (_counter > _planned) std::cout << "# " - << mCounter + << _counter << " tests were run, but only " - << mPlanned + << _planned << " were planned.\n"; std::cout << "# " - << mPassed + << _passed << " passed, " - << mFailed + << _failed << " failed, " - << mSkipped + << _skipped << " skipped. " << std::setprecision (3) << percentPassed << "% passed.\n"; @@ -90,41 +90,41 @@ UnitTest::~UnitTest () /////////////////////////////////////////////////////////////////////////////// void UnitTest::plan (int planned) { - mPlanned = planned; - mCounter = 0; - mPassed = 0; - mFailed = 0; - mSkipped = 0; + _planned = planned; + _counter = 0; + _passed = 0; + _failed = 0; + _skipped = 0; - std::cout << "1.." << mPlanned << "\n"; + std::cout << "1.." << _planned << "\n"; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::planMore (int extra) { - mPlanned += extra; - std::cout << "1.." << mPlanned << "\n"; + _planned += extra; + std::cout << "1.." << _planned << "\n"; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::ok (bool expression, const std::string& name) { - ++mCounter; + ++_counter; if (expression) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n"; @@ -134,22 +134,22 @@ void UnitTest::ok (bool expression, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::notok (bool expression, const std::string& name) { - ++mCounter; + ++_counter; if (!expression) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n"; @@ -159,21 +159,21 @@ void UnitTest::notok (bool expression, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (bool actual, bool expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -187,21 +187,21 @@ void UnitTest::is (bool actual, bool expected, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (size_t actual, size_t expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -215,21 +215,21 @@ void UnitTest::is (size_t actual, size_t expected, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (int actual, int expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -243,21 +243,21 @@ void UnitTest::is (int actual, int expected, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (double actual, double expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -271,21 +271,21 @@ void UnitTest::is (double actual, double expected, const std::string& name) /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (double actual, double expected, double tolerance, const std::string& name) { - ++mCounter; + ++_counter; if (fabs (actual - expected) <= tolerance) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -299,21 +299,21 @@ void UnitTest::is (double actual, double expected, double tolerance, const std:: /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (unsigned char actual, unsigned char expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: " @@ -330,21 +330,21 @@ void UnitTest::is ( const std::string& expected, const std::string& name) { - ++mCounter; + ++_counter; if (actual == expected) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: '" @@ -362,21 +362,21 @@ void UnitTest::is ( const char* expected, const std::string& name) { - ++mCounter; + ++_counter; if (! strcmp (actual, expected)) { - ++mPassed; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " - " << name << "\n"; } else { - ++mFailed; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " - " << name << "\n# expected: '" @@ -399,10 +399,10 @@ void UnitTest::diag (const std::string& text) /////////////////////////////////////////////////////////////////////////////// void UnitTest::pass (const std::string& text) { - ++mCounter; - ++mPassed; + ++_counter; + ++_passed; std::cout << "ok " - << mCounter + << _counter << " " << text << "\n"; @@ -411,10 +411,10 @@ void UnitTest::pass (const std::string& text) /////////////////////////////////////////////////////////////////////////////// void UnitTest::fail (const std::string& text) { - ++mCounter; - ++mFailed; + ++_counter; + ++_failed; std::cout << "not ok " - << mCounter + << _counter << " " << text << "\n"; @@ -423,10 +423,10 @@ void UnitTest::fail (const std::string& text) /////////////////////////////////////////////////////////////////////////////// void UnitTest::skip (const std::string& text) { - ++mCounter; - ++mSkipped; + ++_counter; + ++_skipped; std::cout << "skip " - << mCounter + << _counter << " " << text << "\n"; diff --git a/test/test.h b/test/test.h index 0bceec71f..a41ae71e5 100644 --- a/test/test.h +++ b/test/test.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // taskwarrior - a command line task list manager. // -// Copyright 2006-2012, Paul Beckingham, Federico Hernandez. +// Copyright 2006-2013, 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 @@ -55,11 +55,11 @@ public: void skip (const std::string&); private: - int mPlanned; - int mCounter; - int mPassed; - int mFailed; - int mSkipped; + int _planned; + int _counter; + int _passed; + int _failed; + int _skipped; }; #endif