Newer
Older
libj / include / j / cppunit / cppunit.hpp
/**
 * @file cppunit.hpp
 * @brief J Library Cppunit ヘッダファイル。
 * @copyright  2001 - 2024  Nomura Kei
 * @depends
 */
#ifndef J_CPPUNIT_CPPUNIT_HPP
#define J_CPPUNIT_CPPUNIT_HPP

#include <j.hpp>
#include <j/lang/assertion_error.hpp>
#include <j/cppunit/assert.hpp>

namespace j
{
    namespace cppunit
    {
        /**
         * テストケース。
         * 各テストクラスは、本クラスを継承して作成します。
         *
         * 以下に実装例を示します。
         *
         * @code
         * #include <j/cppunit/cppunit.hpp>
         * #include <j/cppunit/assert.hpp>
         *
         * using namespace j;
         * using namespace j::cppunit;
         * class SampleTest : public TestCase
         * {
         * public:
         *   SampleTest() {}
         *   ~SampleTest() {}
         *   void setUp()
         *   { // 各テストケース実行前に実施する処理を記載する。
         *   }
         *   void tearDown()
         *   { // 各テストケース実行後に実施する処理を記載する。
         *   }
         *   void testSample1()
         *   { // テスト内容を記載する。
         *   }
         *   void testSample2()
         *   { // テスト内容を記載する。
         *   }
         *   void suite()
         *   {
         *     RUN_TEST("テストサンプル1", testSample1);
         *     RUN_TEST("テストサンプル2", testSample2);
         *   }
         * }
         *
         * ---
         * int main()
         * {
         * SampleTest test;
         * test.suite();
         * }
         * @endcode
         */
        class TestCase
        {
        public:
            TestCase() noexcept;
            TestCase(const TestCase &) noexcept = delete;
            TestCase(TestCase &&) noexcept = delete;
            TestCase &operator=(const TestCase &) noexcept = delete;
            TestCase &operator=(TestCase &&) noexcept = delete;
            virtual ~TestCase();
            virtual void setUp();
            virtual void tearDown();
            virtual void suite() = 0;
        };

        class TestManager
        {
        public:
            TestManager();
            TestManager(const TestManager &) noexcept = delete;
            TestManager(TestManager &&) noexcept = delete;
            TestManager &operator=(const TestManager &) noexcept = delete;
            TestManager &operator=(TestManager &&) noexcept = delete;
            virtual ~TestManager();
            void addTestResult(const char *title, const char *func, const char *file, int line, bool result, const j::lang::AssertionError *e = nullptr);
            void printResult();

        private:
            int okCount;
            int ngCount;
        };

        extern TestManager testManager;

/**
 * テスト実行用マクロ
 */
#define RUN_TEST(title, func)                                                                    \
    {                                                                                            \
        setUp();                                                                                 \
        try                                                                                      \
        {                                                                                        \
            func();                                                                              \
            j::cppunit::testManager.addTestResult(title, #func, __FILE__, __LINE__, true);       \
        }                                                                                        \
        catch (j::lang::AssertionError & e)                                                      \
        {                                                                                        \
            j::cppunit::testManager.addTestResult(title, #func, __FILE__, __LINE__, false, &e);  \
        }                                                                                        \
        catch (std::exception & e)                                                               \
        {                                                                                        \
            j::lang::AssertionError as(String(e.what()), __FILE__, #func, 0);                    \
            j::cppunit::testManager.addTestResult(title, #func, __FILE__, __LINE__, false, &as); \
        }                                                                                        \
        catch (...)                                                                              \
        {                                                                                        \
            j::cppunit::testManager.addTestResult(title, #func, __FILE__, __LINE__, false);      \
        }                                                                                        \
        tearDown();                                                                              \
    }

    } // cppunit
} // namespace j

#endif // J_CPPUNIT_CPPUNIT_HPP