From patchwork Tue Jun 21 22:42:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 2135 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id BB57A23F08 for ; Tue, 21 Jun 2011 22:42:24 +0000 (UTC) Received: from mail-vw0-f52.google.com (mail-vw0-f52.google.com [209.85.212.52]) by fiordland.canonical.com (Postfix) with ESMTP id 4D950A1870E for ; Tue, 21 Jun 2011 22:42:24 +0000 (UTC) Received: by vws16 with SMTP id 16so321331vws.11 for ; Tue, 21 Jun 2011 15:42:23 -0700 (PDT) Received: by 10.52.175.197 with SMTP id cc5mr6185251vdc.287.1308696143584; Tue, 21 Jun 2011 15:42:23 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.52.183.130 with SMTP id em2cs102821vdc; Tue, 21 Jun 2011 15:42:23 -0700 (PDT) Received: by 10.216.64.15 with SMTP id b15mr1514489wed.9.1308696142561; Tue, 21 Jun 2011 15:42:22 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id b50si5066462wed.72.2011.06.21.15.42.22; Tue, 21 Jun 2011 15:42:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QZ9eH-0000ht-U8 for ; Tue, 21 Jun 2011 22:42:21 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id DDEAF2E800B for ; Tue, 21 Jun 2011 22:42:21 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: libmatrix X-Launchpad-Branch: ~jesse-barker/libmatrix/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 20 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~jesse-barker/libmatrix/trunk] Rev 20: Refactor tests into its own component. Push the test source into a separate Message-Id: <20110621224221.3913.1505.launchpad@loganberry.canonical.com> Date: Tue, 21 Jun 2011 22:42:21 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13242"; Instance="initZopeless config overlay" X-Launchpad-Hash: c7a4155b50e4e2667937b91bff63a1f3edfdacac ------------------------------------------------------------ revno: 20 committer: Jesse Barker branch nick: trunk timestamp: Tue 2011-06-21 15:37:41 -0700 message: Refactor tests into its own component. Push the test source into a separate directory and allow for easier expansion of test functionality. There is now a common test object and a common options object that can both be expanded and derived from. Main test framework pushes tests onto a vector and iterates across it asserting passing behavior (stopping at first failure as before). added: test/ test/inverse_test.cc test/inverse_test.h test/libmatrix_test.h test/options.cc renamed: matrix_inverse_test.cc => test/libmatrix_test.cc modified: Makefile test/libmatrix_test.cc --- lp:libmatrix https://code.launchpad.net/~jesse-barker/libmatrix/trunk You are subscribed to branch lp:libmatrix. To unsubscribe from this branch go to https://code.launchpad.net/~jesse-barker/libmatrix/trunk/+edit-subscription === modified file 'Makefile' --- Makefile 2011-06-17 16:37:04 +0000 +++ Makefile 2011-06-21 22:37:41 +0000 @@ -1,24 +1,31 @@ -TARGETS = libmatrix.a -TESTS = matrix_inverse_test -SRCS = mat.cc program.cc matrix_inverse_test.cc -OBJS = $(SRCS:.cc=.o) CXXFLAGS = -Wall -Werror -pedantic -O3 +LIBMATRIX = libmatrix.a +LIBSRCS = mat.cc program.cc +LIBOBJS = $(LIBSRCS:.cc=.o) +TESTDIR = test +LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test +TESTSRCS = $(TESTDIR)/options.cc \ + $(TESTDIR)/inverse_test.cc \ + $(TESTDIR)/libmatrix_test.cc +TESTOBJS = $(TESTSRCS:.cc=.o) # Make sure to build both the library targets and the tests, and generate # a make failure if the tests don't pass. -default: $(TARGETS) $(TESTS) run_tests +default: $(LIBMATRIX) $(LIBMATRIX_TESTS) run_tests # Main library targets here. -mat.o : mat.cc mat.h -program.o: program.cc program.h +mat.o : mat.cc mat.h vec.h +program.o: program.cc program.h mat.h vec.h libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h - $(AR) -r $@ $(OBJS) + $(AR) -r $@ $(LIBOBJS) # Tests and execution targets here. -matrix_inverse_test.o: matrix_inverse_test.cc mat.h -matrix_inverse_test: matrix_inverse_test.o libmatrix.a +$(TESTDIR)/options.o: $(TESTDIR)/options.cc $(TESTDIR)/libmatrix_test.h +$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h +$(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h +$(TESTDIR)/libmatrix_test: $(TESTDIR)/options.o $(TESTDIR)/libmatrix_test.o $(TESTDIR)/inverse_test.o libmatrix.a $(CXX) -o $@ $? -run_tests: $(TESTS) - ./matrix_inverse_test +run_tests: $(LIBMATRIX_TESTS) + $(LIBMATRIX_TESTS) clean : - $(RM) $(OBJS) $(TARGETS) + $(RM) $(LIBOBJS) $(TESTOBJS) $(LIBMATRIX) $(LIBMATRIX_TESTS) === added directory 'test' === added file 'test/inverse_test.cc' --- test/inverse_test.cc 1970-01-01 00:00:00 +0000 +++ test/inverse_test.cc 2011-06-21 22:37:41 +0000 @@ -0,0 +1,161 @@ +#include +#include "libmatrix_test.h" +#include "inverse_test.h" +#include "../mat.h" + +using LibMatrix::mat2; +using LibMatrix::mat3; +using LibMatrix::mat4; +using std::cout; +using std::endl; + +void +MatrixTest2x2Inverse::run(const Options& options) +{ + mat2 m; + + if (options.beVerbose()) + { + cout << "Starting with mat2 (should be identity): " << endl << endl; + m.print(); + } + + m[0][1] = -2.5; + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl; + m.print(); + } + + mat2 mi(m); + + if (options.beVerbose()) + { + cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl; + mi.print(); + } + + mi.inverse(); + + if (options.beVerbose()) + { + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + } + + mat2 i = m * mi; + + if (options.beVerbose()) + { + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + } + + mat2 ident; + if (i == ident) + { + pass_ = true; + } +} + +void +MatrixTest3x3Inverse::run(const Options& options) +{ + mat3 m; + + if (options.beVerbose()) + { + cout << "Starting with mat3 (should be identity): " << endl << endl; + m.print(); + } + + m[1][2] = -2.5; + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl; + m.print(); + } + + mat3 mi(m); + + if (options.beVerbose()) + { + cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl; + mi.print(); + } + + mi.inverse(); + + if (options.beVerbose()) + { + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + } + + mat3 i = m * mi; + + if (options.beVerbose()) + { + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + } + + mat3 ident; + if (i == ident) + { + pass_ = true; + } +} + +void +MatrixTest4x4Inverse::run(const Options& options) +{ + mat4 m; + + if (options.beVerbose()) + { + cout << "Starting with mat4 (should be identity): " << endl << endl; + m.print(); + } + + m[2][3] = -2.5; + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl; + m.print(); + } + + mat4 mi(m); + + if (options.beVerbose()) + { + cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl; + mi.print(); + } + + mi.inverse(); + + if (options.beVerbose()) + { + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + } + + mat4 i = m * mi; + + if (options.beVerbose()) + { + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + } + + mat4 ident; + if (i == ident) + { + pass_ = true; + } +} + === added file 'test/inverse_test.h' --- test/inverse_test.h 1970-01-01 00:00:00 +0000 +++ test/inverse_test.h 2011-06-21 22:37:41 +0000 @@ -0,0 +1,28 @@ +#ifndef INVERSE_TEST_H_ +#define INVERSE_TEST_H_ + +class MatrixTest; +class Options; + +class MatrixTest2x2Inverse : public MatrixTest +{ +public: + MatrixTest2x2Inverse() : MatrixTest("mat2::inverse") {} + virtual void run(const Options& options); +}; + +class MatrixTest3x3Inverse : public MatrixTest +{ +public: + MatrixTest3x3Inverse() : MatrixTest("mat3::inverse") {} + virtual void run(const Options& options); +}; + +class MatrixTest4x4Inverse : public MatrixTest +{ +public: + MatrixTest4x4Inverse() : MatrixTest("mat4::inverse") {} + virtual void run(const Options& options); +}; + +#endif // INVERSE_TEST_H_ === renamed file 'matrix_inverse_test.cc' => 'test/libmatrix_test.cc' --- matrix_inverse_test.cc 2011-06-16 22:37:59 +0000 +++ test/libmatrix_test.cc 2011-06-21 22:37:41 +0000 @@ -10,143 +10,48 @@ // Jesse Barker - original implementation. // #include -#include "mat.h" +#include +#include +#include "libmatrix_test.h" +#include "inverse_test.h" -using LibMatrix::mat4; -using LibMatrix::mat3; -using LibMatrix::mat2; using std::cerr; using std::cout; using std::endl; -bool mat2OK() -{ - mat2 m; - cout << "Starting with mat2 (should be identity): " << endl << endl; - m.print(); - - m[0][1] = -2.5; - - cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl; - m.print(); - - mat2 mi(m); - - cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl; - mi.print(); - - mi.inverse(); - - cout << endl << "Inverse of copy: " << endl << endl; - mi.print(); - - mat2 i = m * mi; - - cout << endl << "Product of original and inverse (should be identity): " << endl << endl; - i.print(); - - mat2 ident; - if (i != ident) - { - return false; - } - - return true; -} - -bool mat3OK() -{ - mat3 m; - cout << "Starting with mat3 (should be identity): " << endl << endl; - m.print(); - - m[1][2] = -2.5; - - cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl; - m.print(); - - mat3 mi(m); - - cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl; - mi.print(); - - mi.inverse(); - - cout << endl << "Inverse of copy: " << endl << endl; - mi.print(); - - mat3 i = m * mi; - - cout << endl << "Product of original and inverse (should be identity): " << endl << endl; - i.print(); - - mat3 ident; - if (i != ident) - { - return false; - } - - return true; -} - -bool mat4OK() -{ - mat4 m; - cout << "Starting with mat4 (should be identity): " << endl << endl; - m.print(); - - m[2][3] = -2.5; - - cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl; - m.print(); - - mat4 mi(m); - - cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl; - mi.print(); - - mi.inverse(); - - cout << endl << "Inverse of copy: " << endl << endl; - mi.print(); - - mat4 i = m * mi; - - cout << endl << "Product of original and inverse (should be identity): " << endl << endl; - i.print(); - - mat4 ident; - if (i != ident) - { - return false; - } - - return true; -} - int main(int argc, char** argv) { - if (!mat2OK()) - { - cerr << "mat2::inverse() does not work!" << endl; - return 1; - } - cout << "mat2::inverse() is okay!" << endl << endl; - - if (!mat3OK()) - { - cerr << "mat3::inverse() does not work!" << endl; - return 1; - } - cout << "mat3::inverse() is okay!" << endl << endl; - - if (!mat4OK()) - { - cerr << "mat4::inverse() does not work!" << endl; - return 1; - } - cout << "mat4::inverse() is okay!" << endl << endl; + Options testOptions("matrix_test"); + testOptions.parseArgs(argc, argv); + if (testOptions.showHelp()) + { + testOptions.printUsage(); + return 0; + } + + using std::vector; + vector testVec; + testVec.push_back(new MatrixTest2x2Inverse()); + testVec.push_back(new MatrixTest3x3Inverse()); + testVec.push_back(new MatrixTest4x4Inverse()); + + for (vector::iterator testIt = testVec.begin(); + testIt != testVec.end(); + testIt++) + { + MatrixTest* curTest = *testIt; + curTest->run(testOptions); + if (!curTest->passed()) + { + cerr << curTest->name() << " does not work!" << endl; + return 1; + } + if (testOptions.beVerbose()) + { + cout << curTest->name() << " is okay!" << endl; + } + } return 0; } === added file 'test/libmatrix_test.h' --- test/libmatrix_test.h 1970-01-01 00:00:00 +0000 +++ test/libmatrix_test.h 2011-06-21 22:37:41 +0000 @@ -0,0 +1,40 @@ +#ifndef LIBMATRIX_TEST_H_ +#define LIBMATRIX_TEST_H_ + +class Options +{ + Options(); + static const std::string verbose_name_; + static const std::string help_name_; + std::string app_name_; + bool show_help_; + bool verbose_; +public: + Options(const std::string& app_name) : + app_name_(app_name), + show_help_(false), + verbose_(false) {} + ~Options() {} + bool beVerbose() const { return verbose_; } + bool showHelp() const { return show_help_; } + void parseArgs(int argc, char** argv); + void printUsage(); +}; + +class MatrixTest +{ + std::string name_; +protected: + bool pass_; + MatrixTest(); +public: + MatrixTest(const std::string& name) : + name_(name), + pass_(false) {} + ~MatrixTest(); + const std::string& name() const { return name_; } + virtual void run(const Options& options) = 0; + const bool passed() const { return pass_; } +}; + +#endif // LIBMATRIX_TEST_H_ === added file 'test/options.cc' --- test/options.cc 1970-01-01 00:00:00 +0000 +++ test/options.cc 2011-06-21 22:37:41 +0000 @@ -0,0 +1,56 @@ +#include +#include +#include +#include "libmatrix_test.h" + +using std::cout; +using std::endl; + +const std::string Options::verbose_name_("verbose"); +const std::string Options::help_name_("help"); + +void +Options::parseArgs(int argc, char** argv) +{ + static struct option long_options[] = { + {"verbose", 0, 0, 0}, + {"help", 0, 0, 0}, + {0, 0, 0, 0} + }; + int option_index(0); + int c = getopt_long(argc, argv, "", long_options, &option_index); + while (c != -1) + { + std::string optname(long_options[option_index].name); + + if (optname == verbose_name_) + { + verbose_ = true; + } + else if (optname == help_name_) + { + show_help_ = true; + } + c = getopt_long(argc, argv, "", + long_options, &option_index); + } +} + + +static void +emitColumnOne(const std::string& text) +{ + cout << std::setw(16) << text; +} + +void +Options::printUsage() +{ + cout << app_name_ << ": directed functional test utility for libmatrix." << endl; + cout << "Options:" << endl; + emitColumnOne("--verbose"); + cout << std::setw(0) << " Enable verbose output during test runs." << endl; + emitColumnOne("--help"); + cout << std::setw(0) << " Print this usage text." << endl; +} +