Matt Oswald avatar Matt Oswald committed ea80127

refactored the test runner and friends to allow unit testing them

Comments (0)

Files changed (6)

Tests/Attributes.cpp

 #include "Fact.h"
+#include "IOutput.h"
 #include "TestCollection.h"
+#include "xUnitTestRunner.h"
 #include "xUnit++.h"
 
 using xUnitpp::Assert;
 ATTRIBUTES(TestWithAttributes, ("Cats", "Meow"))
 FACT(TestWithAttributes)
 {
-    for (const auto &fact : xUnitpp::TestCollection::Facts())
+    for (const auto &fact : xUnitpp::TestCollection::Instance().Facts())
     {
         if (fact.TestDetails().Name == "TestWithAttributes")
         {
     Assert.Fail("Could not find self in test list.");
 }
 
-ATTRIBUTES(SkippedTest, ("Skip", "no reason"))
-FACT(SkippedTest)
+FACT(SkippedTestsShouldNotBeInstantiated)
 {
-    Assert.Fail("Skipped tests should not be run.");
+    // have to set this internal test up manually since the macros don't work embedded within each other
+    struct SkippedTest : xUnitpp::NoFixture
+    {
+        SkippedTest()
+        {
+            Assert.False("Should not be instantiated.");
+        }
+    
+        void RunTest()
+        {
+            Assert.False("Should not be run.");
+        }
+    };
+
+    struct EmptyReporter : xUnitpp::IOutput
+    {
+        virtual void ReportStart(const xUnitpp::TestDetails &, int) override
+        {
+        }
+
+        virtual void ReportFailure(const xUnitpp::TestDetails &, int, const std::string &) override
+        {
+        }
+
+        virtual void ReportSkip(const xUnitpp::TestDetails &, const std::string &) override
+        {
+        }
+
+        virtual void ReportFinish(const xUnitpp::TestDetails &, int, std::chrono::milliseconds) override
+        {
+        }
+
+        virtual void ReportAllTestsComplete(size_t, size_t, size_t, std::chrono::milliseconds) override 
+        {
+        }
+    };
+
+    xUnitpp::AttributeCollection attributes;
+    attributes.insert(std::make_pair("Skip", "Testing skip."));
+
+    xUnitpp::TestCollection collection;
+    xUnitpp::TestCollection::Register reg(collection, []() { SkippedTest().RunTest(); }, "SkippedTest", "Attributes", attributes, -1, __FILE__, __LINE__);
+
+    xUnitpp::TestRunner local(std::make_shared<EmptyReporter>());
+    local.RunTests([](const xUnitpp::TestDetails &) { return true; },
+        collection.Facts(), collection.Theories(), std::chrono::milliseconds::zero(), 0);
 }
 
 }

xUnit++/TestCollection.cpp

 {
     extern "C" __declspec(dllexport) void ListAllTests(std::vector<xUnitpp::TestDetails> &tests)
     {
-        for (const auto &fact : xUnitpp::TestCollection::Facts())
+        for (const auto &fact : xUnitpp::TestCollection::Instance().Facts())
         {
             tests.push_back(fact.TestDetails());
         }
 
-        for (const auto &theory : xUnitpp::TestCollection::Theories())
+        for (const auto &theory : xUnitpp::TestCollection::Instance().Theories())
         {
             tests.push_back(theory.TestDetails());
         }
     return collection;
 }
 
-TestCollection::Register::Register(const std::function<void()> &fn, const std::string &name, const std::string &suite,
+TestCollection::Register::Register(TestCollection &collection, const std::function<void()> &fn, const std::string &name, const std::string &suite,
                                    const AttributeCollection &attributes, int milliseconds, const std::string &filename, int line)
 {
-    TestCollection::Instance().mFacts.emplace_back(Fact(fn, name, suite, attributes, std::chrono::milliseconds(milliseconds), filename, line));
+    collection.mFacts.emplace_back(Fact(fn, name, suite, attributes, std::chrono::milliseconds(milliseconds), filename, line));
 }
 
 const std::vector<Fact> &TestCollection::Facts()
 {
-    return Instance().mFacts;
+    return mFacts;
 }
 
 const std::vector<Theory> &TestCollection::Theories()
 {
-    return Instance().mTheories;
+    return mTheories;
 }
 
 }

xUnit++/TestCollection.h

         }
 
     public:
-        Register(const std::function<void()> &fn, const std::string &name, const std::string &suite,
+        Register(TestCollection &collection, const std::function<void()> &fn, const std::string &name, const std::string &suite,
             const AttributeCollection &attributes, int milliseconds, const std::string &filename, int line);
 
         template<typename TTheory, typename TTheoryData>
-        Register(TTheory theory, TTheoryData theoryData, const std::string &name, const std::string &suite,
+        Register(TestCollection &collection, TTheory theory, TTheoryData theoryData, const std::string &name, const std::string &suite,
             const AttributeCollection &attributes, int milliseconds, const std::string &filename, int line)
         {
             std::vector<std::function<void()>> theorySet;
                 theorySet.emplace_back(TheoryHelper(theory, std::move(t)));
             }
         
-            TestCollection::Instance().mTheories.emplace_back(Theory(theorySet, name, suite, attributes, std::chrono::milliseconds(milliseconds), filename, line));
+            collection.mTheories.emplace_back(Theory(theorySet, name, suite, attributes, std::chrono::milliseconds(milliseconds), filename, line));
         }
     };
 
-    static const std::vector<Fact> &Facts();
-    static const std::vector<Theory> &Theories();
+    static TestCollection &Instance();
+
+    const std::vector<Fact> &Facts();
+    const std::vector<Theory> &Theories();
 
 private:
-    static TestCollection &Instance();
-
     std::vector<Fact> mFacts;
     std::vector<Theory> mTheories;
 };

xUnit++/xUnitMacros.h

         { \
         public: \
             void FactName(); \
-        } FactName ## _instance; \
-        xUnitpp::TestCollection::Register reg(std::bind(&FactName ## _Fixture::FactName, FactName ## _instance), #FactName, xUnitSuite::Name(), xUnitAttributes::Attributes(), timeout, __FILE__, __LINE__); \
+        }; \
+        void FactName ## _runner() { FactName ## _Fixture().FactName(); } \
+        xUnitpp::TestCollection::Register reg(xUnitpp::TestCollection::Instance(), &FactName ## _runner, #FactName, xUnitSuite::Name(), xUnitAttributes::Attributes(), timeout, __FILE__, __LINE__); \
     } \
     void FactName ## _ns::FactName ## _Fixture::FactName()
 
 
 #define TIMED_THEORY(TheoryName, params, DataProvider, timeout) \
     void TheoryName params; \
-    namespace TheoryName ## _ns { xUnitpp::TestCollection::Register reg(TheoryName, DataProvider, #TheoryName, xUnitSuite::Name(), xUnitAttributes::Attributes(), timeout, __FILE__, __LINE__); } \
+    namespace TheoryName ## _ns { xUnitpp::TestCollection::Register reg(xUnitpp::TestCollection::Instance(), TheoryName, DataProvider, #TheoryName, xUnitSuite::Name(), xUnitAttributes::Attributes(), timeout, __FILE__, __LINE__); } \
     void TheoryName params
 
 #define THEORY(TheoryName, params, DataProvider) TIMED_THEORY(TheoryName, params, DataProvider, -1)

xUnit++/xUnitTestRunner.cpp

 extern "C" __declspec(dllexport) int FilteredTestsRunner(int timeLimit, std::shared_ptr<xUnitpp::IOutput> testReporter, std::function<bool(const xUnitpp::TestDetails &)> filter)
 {
     return xUnitpp::TestRunner(testReporter)
-        .RunTests(filter, xUnitpp::TestCollection::Facts(), xUnitpp::TestCollection::Theories(), std::chrono::milliseconds(timeLimit), 0);
+        .RunTests(filter, xUnitpp::TestCollection::Instance().Facts(), xUnitpp::TestCollection::Instance().Theories(), std::chrono::milliseconds(timeLimit), 0);
 }
 
 class ActiveTests

xUnit++/xUnitTestRunner.h

 
 private:
     class Impl;
-    std::unique_ptr<Impl> mImpl;
+    std::shared_ptr<Impl> mImpl;
 };
 
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.