[colobot] 183/377: CBot testing framework; fixed a few bugs

Didier Raboud odyx at moszumanska.debian.org
Wed Mar 30 13:34:13 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit 8437a9bdd2b394055595565a6af84ff976688314
Author: krzys-h <krzys_h at interia.pl>
Date:   Wed Dec 23 20:39:56 2015 +0100

    CBot testing framework; fixed a few bugs
---
 src/CBot/CBotProgram.cpp |   2 +-
 src/CBot/CBotStack.cpp   |   8 +-
 test/unit/CBot/CBot.cpp  | 221 +++++++++++++++++++++++++++++++++++++++++++++++
 test/unit/CMakeLists.txt |   1 +
 4 files changed, 227 insertions(+), 5 deletions(-)

diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index 8fffb67..a15108d 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -257,7 +257,7 @@ void CBotProgram::Stop()
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotProgram::GetRunPos(std::string& functionName, int& start, int& end)
 {
-    functionName = nullptr;
+    functionName = "";
     start = end = 0;
     if (m_pStack == nullptr) return false;
 
diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp
index f91b56e..3387ef4 100644
--- a/src/CBot/CBotStack.cpp
+++ b/src/CBot/CBotStack.cpp
@@ -747,7 +747,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
     res = CBotCall::DoCall(nIdent, nullptr, ppVar, this, rettype );
     if (res.GetType() >= 0) return res.GetType();
 
-    res = m_prog->GetFunctions()->DoCall(nIdent, nullptr, ppVar, this, token );
+    res = m_prog->GetFunctions()->DoCall(nIdent, "", ppVar, this, token );
     if (res.GetType() >= 0) return res.GetType();
 
     // if not found (recompile?) seeks by name
@@ -828,7 +828,7 @@ void CBotStack::GetRunPos(std::string& FunctionName, int& start, int& end)
 CBotVar* CBotStack::GetStackVars(std::string& FunctionName, int level)
 {
     CBotProgram*    prog = m_prog;                        // current program
-    FunctionName    = nullptr;
+    FunctionName    = "";
 
     // back the stack in the current module
     CBotStack*        p = this;
@@ -844,13 +844,13 @@ CBotVar* CBotStack::GetStackVars(std::string& FunctionName, int level)
 
 
     // descends upon the elements of block
-    while ( p != nullptr && p->m_bBlock != UnknownEnumBlock::UNKNOWN_FALSE ) p = p->m_prev;
+    while ( p != nullptr && p->m_bBlock == UnknownEnumBlock::UNKNOWN_FALSE ) p = p->m_prev;
     // Now p is on the beggining of the top block (with local variables)
 
     while ( p != nullptr && level++ < 0 )
     {
         p = p->m_prev;
-        while ( p != nullptr && p->m_bBlock != UnknownEnumBlock::UNKNOWN_FALSE ) p = p->m_prev;
+        while ( p != nullptr && p->m_bBlock == UnknownEnumBlock::UNKNOWN_FALSE ) p = p->m_prev;
     }
     // Now p is on the block "level"
 
diff --git a/test/unit/CBot/CBot.cpp b/test/unit/CBot/CBot.cpp
new file mode 100644
index 0000000..ff5bc46
--- /dev/null
+++ b/test/unit/CBot/CBot.cpp
@@ -0,0 +1,221 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+#include "CBot/CBot.h"
+
+#include <gtest/gtest.h>
+
+class CBotTestFail : public std::runtime_error {
+public:
+    CBotTestFail(const std::string& message) : runtime_error(message)
+    {
+    }
+
+    CBotTestFail(std::string message, int cursor1, int cursor2) : CBotTestFail(message)
+    {
+        this->cursor1 = cursor1;
+        this->cursor2 = cursor2;
+    }
+
+    int cursor1 = -1;
+    int cursor2 = -1;
+};
+
+CBotTypResult cFail(CBotVar* &var, void* user)
+{
+    if (var != nullptr)
+    {
+        if (var->GetType() != CBotTypString) return CBotTypResult(CBotErrBadString);
+        var = var->GetNext();
+    }
+    if (var != nullptr) return CBotTypResult(CBotErrOverParam);
+    return CBotTypResult(CBotTypVoid);
+}
+
+bool rFail(CBotVar* var, CBotVar* result, int& exception, void* user)
+{
+    std::string message = "CBot test failed";
+    if (var != nullptr)
+    {
+        message = var->GetValString();
+    }
+
+    throw CBotTestFail(message);
+}
+
+class CBotUT : public testing::Test
+{
+public:
+    void SetUp()
+    {
+        CBotProgram::Init();
+        CBotProgram::AddFunction("FAIL", rFail, cFail);
+    }
+
+    void TearDown()
+    {
+        CBotProgram::Free();
+    }
+
+protected:
+    // Modified version of PutList from src/script/script.cpp
+    // Should be probably moved somewhere into the CBot library
+    void PrintVars(std::stringstream& ss, CBotVar* var, const std::string& baseName = "", bool bArray = false)
+    {
+        if (var == nullptr && !baseName.empty())
+        {
+            ss << "    " << baseName << " = null" << std::endl;
+            return;
+        }
+
+        int index = 0;
+        while (var != nullptr)
+        {
+            CBotVar* pStatic = var->GetStaticVar();  // finds the static element
+
+            std::string p = pStatic->GetName();  // variable name
+
+            std::stringstream varName;
+            if (baseName.empty())
+            {
+                varName << p;
+            }
+            else
+            {
+                if (bArray)
+                {
+                    varName << baseName << "[" << index << "]";
+                }
+                else
+                {
+                    varName << baseName << "." << p;
+                }
+            }
+
+            CBotType type = pStatic->GetType();
+            if ( type < CBotTypBoolean )
+            {
+                ss << "    " << varName.str() << " = " << pStatic->GetValString() << std::endl;
+            }
+            else if ( type == CBotTypString )
+            {
+                ss << "    " << varName.str() << " = " << "\"" << pStatic->GetValString() << "\"" << std::endl;
+            }
+            else if ( type == CBotTypArrayPointer )
+            {
+                PrintVars(ss, pStatic->GetItemList(), varName.str(), true);
+            }
+            else if ( type == CBotTypClass   ||
+                      type == CBotTypPointer )
+            {
+                PrintVars(ss, pStatic->GetItemList(), varName.str(), false);
+            }
+            else
+            {
+                ss << "    " << varName.str() << " = ?" << std::endl;
+            }
+
+            index ++;
+            var = var->GetNext();
+        }
+    }
+
+    void ExecuteTest(const std::string& code, CBotError expectedError = CBotNoErr)
+    {
+        auto program = std::unique_ptr<CBotProgram>(new CBotProgram());
+        std::vector<std::string> tests;
+        program->Compile(code, tests);
+
+        CBotError error;
+        int cursor1, cursor2;
+        if (program->GetError(error, cursor1, cursor2))
+        {
+            FAIL() << "Compile error - " << error << " (" << cursor1 << "-" << cursor2 << ")"; // TODO: Error messages are on Colobot side
+        }
+
+        for (const std::string& test : tests)
+        {
+            try
+            {
+                program->Start(test);
+                while (!program->Run());
+                program->GetError(error, cursor1, cursor2);
+                if (error != expectedError)
+                {
+                    std::stringstream ss;
+                    if (error != CBotNoErr)
+                    {
+                        ss << "RUNTIME ERROR - " << error; // TODO: Error messages are on Colobot side
+                    }
+                    else
+                    {
+                        ss << "No runtime error, expected " << expectedError; // TODO: Error messages are on Colobot side
+                        cursor1 = cursor2 = -1;
+                    }
+                    throw CBotTestFail(ss.str(), cursor1, cursor2);
+                }
+            }
+            catch (const CBotTestFail& e)
+            {
+                std::stringstream ss;
+                ss << "*** Failed test " << test << ": " << e.what() << std::endl;
+
+                std::string funcName;
+                program->GetRunPos(funcName, cursor1, cursor2);
+                if (!funcName.empty())
+                {
+                    ss << "    while executing function " << funcName << " (" << cursor1 << "-" << cursor2 << ")" << std::endl;
+                }
+                else if(e.cursor1 >= 0 && e.cursor2 >= 0)
+                {
+                    ss << "    at unknown location " << e.cursor1 << "-" << e.cursor2 << std::endl;
+                }
+                ss << std::endl;
+
+                ss << "Variables:" << std::endl;
+                int level = 0;
+                while (true)
+                {
+                    CBotVar* var = program->GetStackVars(funcName, level--);
+                    if (var == nullptr) break;
+
+                    ss << "  Block " << -level << ":" << std::endl;
+                    PrintVars(ss, var);
+                }
+
+                ADD_FAILURE() << ss.str();
+            }
+        }
+    }
+};
+
+TEST_F(CBotUT, Test)
+{
+    ExecuteTest("extern void EmptyTest() { }");
+}
+
+TEST_F(CBotUT, DISABLED_TestFail)
+{
+    ExecuteTest("extern void FailingTest() { FAIL(); } extern void AnotherFailingTest() { FAIL(\"This is a message\"); }");
+}
+
+TEST_F(CBotUT, DivideByZero)
+{
+    ExecuteTest("extern void DivideByZero() { float a = 5/0; }", CBotErrZeroDiv);
+}
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 37eed55..cbf6956 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -10,6 +10,7 @@ set(UT_SOURCES
     main.cpp
     app/app_test.cpp
     CBot/CBotToken_test.cpp
+    CBot/CBot.cpp
     common/config_file_test.cpp
     graphics/engine/lightman_test.cpp
     math/func_test.cpp

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list