From 6db04f4320cd5d24ae625dbc1df5a8a71b93e51d Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Sat, 10 Oct 2009 21:36:03 +0000 Subject: tests: Added simple test framework, added a couple of tests git-svn-id: http://pugixml.googlecode.com/svn/trunk@140 99668b35-9821-0410-8761-19e4c4f06640 --- Jamfile.jam | 2 +- Jamrules.jam | 27 +++++++++++++++++++-- tests/common.hpp | 5 ++++ tests/main.cpp | 43 +++++++++++++++++++++++++++++---- tests/test.hpp | 59 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_dom_traverse.cpp | 51 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 tests/common.hpp create mode 100644 tests/test.hpp create mode 100644 tests/test_dom_traverse.cpp diff --git a/Jamfile.jam b/Jamfile.jam index bebeae5..420a3e0 100644 --- a/Jamfile.jam +++ b/Jamfile.jam @@ -13,6 +13,6 @@ LDFLAGS = -fprofile-arcs ; GCOVFLAGS = -n ; Library pugixml : src/pugixml.cpp src/pugixpath.cpp ; -Application tests : tests/main.cpp : pugixml ; +Application tests : tests/main.cpp [ Glob tests : test_*.cpp ] : pugixml ; Test run_tests : tests ; Coverage coverage : run_tests ; diff --git a/Jamrules.jam b/Jamrules.jam index 43d817f..4fda7f4 100644 --- a/Jamrules.jam +++ b/Jamrules.jam @@ -25,16 +25,21 @@ actions RunAction $(>:\\) } -actions quietly ignore MakeDir +actions quietly ignore MakeDirAction { mkdir $(<:\\) >nul 2>&1 } +actions quietly ignore DeleteAction +{ + del /F $(>:\\) >nul 2>&1 +} + rule MakeFileDir TARGET { local DIR = $(TARGET:D) ; - MakeDir $(DIR) ; + MakeDirAction $(DIR) ; Needs $(TARGET) : $(DIR) ; } @@ -118,6 +123,21 @@ rule Application TARGET : SOURCES : LIBRARIES $(TARGET)_objects = $(OBJECTS) $($(LIBRARIES)_objects) ; } +rule CleanCoverage TARGET +{ + # make target + local CLEAN_TARGET = $(TARGET)_clean_coverage ; + + NotFile $(CLEAN_TARGET) ; + Always $(CLEAN_TARGET) ; + Depends $(TARGET) : $(CLEAN_TARGET) ; + + # clean object files + local FILES = $($(SOURCE)_objects:S=.gcda) ; + + DeleteAction $(CLEAN_TARGET) : $(FILES) ; +} + rule Test TARGET : SOURCE { # make alias @@ -128,6 +148,9 @@ rule Test TARGET : SOURCE # remember executable objects for coverage $(TARGET)_objects = $($(SOURCE)_objects) ; + + # clean coverage files before run + CleanCoverage $(TARGET) ; } rule Coverage TARGET : SOURCE diff --git a/tests/common.hpp b/tests/common.hpp new file mode 100644 index 0000000..0091e1c --- /dev/null +++ b/tests/common.hpp @@ -0,0 +1,5 @@ +#include "test.hpp" + +#include "../src/pugixml.hpp" + +using namespace pugi; diff --git a/tests/main.cpp b/tests/main.cpp index ab3187c..55903b9 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,10 +1,43 @@ -#include "../src/pugixml.hpp" +#include "test.hpp" + +#include +#include + +test_runner* test_runner::_tests = 0; int main() { - pugi::xml_document doc; - doc.load(""); - doc.select_single_node("node"); + unsigned int total = 0; + unsigned int passed = 0; + + for (test_runner* test = test_runner::_tests; test; test = test->_next) + { + try + { + total++; + test->run(); + passed++; + } + catch (const std::exception& e) + { + printf("Test %s failed: exception %s\n", test->_name, e.what()); + } + catch (const char* e) + { + printf("Test %s failed: %s\n", test->_name, e); + } + catch (...) + { + printf("Test %s failed for unknown reason\n", test->_name); + } + } + + unsigned int failed = total - passed; + + if (failed != 0) + printf("FAILURE: %u out of %u tests failed.\n", failed, total); + else + printf("Success: %d tests passed.\n", total); - // doc.select_single_node("//"); - fails? why? :) + return failed; } diff --git a/tests/test.hpp b/tests/test.hpp new file mode 100644 index 0000000..09d7024 --- /dev/null +++ b/tests/test.hpp @@ -0,0 +1,59 @@ +#ifndef HEADER_TEST_HPP +#define HEADER_TEST_HPP + +struct test_runner +{ + test_runner(const char* name) + { + _name = name; + _next = _tests; + _tests = this; + } + + virtual ~test_runner() {} + + virtual void run() = 0; + + const char* _name; + test_runner* _next; + + static test_runner* _tests; +}; + +struct dummy_fixture {}; + +#define TEST_FIXTURE(name, fixture) \ + struct test_runner_helper_##name: fixture \ + { \ + void run(); \ + }; \ + static struct test_runner_##name: test_runner \ + { \ + test_runner_##name(): test_runner(#name) {} \ + \ + virtual void run() \ + { \ + test_runner_helper_##name helper; \ + helper.run(); \ + } \ + } test_runner_instance_##name; \ + void test_runner_helper_##name::run() + +#define TEST(name) TEST_FIXTURE(name, dummy_fixture) + +#define TEST_XML(name, xml) \ + struct test_fixture_##name \ + { \ + pugi::xml_document doc; \ + \ + test_fixture_##name() \ + { \ + CHECK(doc.load(xml)); \ + } \ + }; \ + \ + TEST_FIXTURE(name, test_fixture_##name) + +#define CHECK(condition) if (condition) ; else throw #condition " is false" + +#endif diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp new file mode 100644 index 0000000..bbee076 --- /dev/null +++ b/tests/test_dom_traverse.cpp @@ -0,0 +1,51 @@ +#include "common.hpp" + +TEST_XML(dom_attr_bool_ops, "") +{ + xml_attribute attr1; + xml_attribute attr2 = doc.child("node").attribute("attr"); + + CHECK(!attr1); + CHECK(attr2); + CHECK(!!attr2); + + bool attr1b = attr1; + bool attr2b = attr2; + + CHECK(!attr1b); + CHECK(attr2b); +} + +TEST_XML(dom_attr_empty, "") +{ + xml_attribute attr1; + xml_attribute attr2 = doc.child("node").attribute("attr"); + + CHECK(attr1.empty()); + CHECK(!attr2.empty()); +} + +TEST_XML(dom_node_bool_ops, "") +{ + xml_node node1; + xml_node node2 = doc.child("node"); + + CHECK(!node1); + CHECK(node2); + CHECK(!!node2); + + bool node1b = node1; + bool node2b = node2; + + CHECK(!node1b); + CHECK(node2b); +} + +TEST_XML(dom_node_empty, "") +{ + xml_node node1; + xml_node node2 = doc.child("node"); + + CHECK(node1.empty()); + CHECK(!node2.empty()); +} -- cgit v1.2.3