diff --git a/apps/openmw_test_suite/mwscript/test_scripts.cpp b/apps/openmw_test_suite/mwscript/test_scripts.cpp index 3c0cd477d5..90c7fb53c2 100644 --- a/apps/openmw_test_suite/mwscript/test_scripts.cpp +++ b/apps/openmw_test_suite/mwscript/test_scripts.cpp @@ -1,243 +1,10 @@ #include - -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "test_utils.hpp" namespace { - class TestCompilerContext : public Compiler::Context - { - public: - bool canDeclareLocals() const override { return true; } - char getGlobalType(const std::string& name) const override { return ' '; } - std::pair getMemberType(const std::string& name, const std::string& id) const override { return {' ', false}; } - bool isId(const std::string& name) const override { return false; } - bool isJournalId(const std::string& name) const override { return false; } - }; - - class TestErrorHandler : public Compiler::ErrorHandler - { - std::vector> mErrors; - - void report(const std::string& message, const Compiler::TokenLoc& loc, Compiler::ErrorHandler::Type type) override - { - if(type == Compiler::ErrorHandler::ErrorMessage) - mErrors.emplace_back(message, loc); - } - - void report(const std::string& message, Compiler::ErrorHandler::Type type) override - { - report(message, {}, type); - } - - public: - void reset() override - { - Compiler::ErrorHandler::reset(); - mErrors.clear(); - } - - const std::vector>& getErrors() const { return mErrors; } - }; - - class LocalVariables - { - std::vector mShorts; - std::vector mLongs; - std::vector mFloats; - - template - T getLocal(int index, const std::vector& vector) const - { - if(index < vector.size()) - return vector[index]; - return {}; - } - - template - void setLocal(T value, int index, std::vector& vector) - { - if(index >= vector.size()) - vector.resize(index + 1); - vector[index] = value; - } - public: - void clear() - { - mShorts.clear(); - mLongs.clear(); - mFloats.clear(); - } - - int getShort(int index) const { return getLocal(index, mShorts); }; - - int getLong(int index) const { return getLocal(index, mLongs); }; - - float getFloat(int index) const { return getLocal(index, mFloats); }; - - void setShort(int index, int value) { setLocal(value, index, mShorts); }; - - void setLong(int index, int value) { setLocal(value, index, mLongs); }; - - void setFloat(int index, float value) { setLocal(value, index, mFloats); }; - }; - - class GlobalVariables - { - std::map mShorts; - std::map mLongs; - std::map mFloats; - - template - T getGlobal(const std::string& name, const std::map& map) const - { - auto it = map.find(name); - if(it != map.end()) - return it->second; - return {}; - } - public: - void clear() - { - mShorts.clear(); - mLongs.clear(); - mFloats.clear(); - } - - int getShort(const std::string& name) const { return getGlobal(name, mShorts); }; - - int getLong(const std::string& name) const { return getGlobal(name, mLongs); }; - - float getFloat(const std::string& name) const { return getGlobal(name, mFloats); }; - - void setShort(const std::string& name, int value) { mShorts[name] = value; }; - - void setLong(const std::string& name, int value) { mLongs[name] = value; }; - - void setFloat(const std::string& name, float value) { mFloats[name] = value; }; - }; - - class TestInterpreterContext : public Interpreter::Context - { - LocalVariables mLocals; - std::map mMembers; - public: - std::string getTarget() const override { return {}; }; - - int getLocalShort(int index) const override { return mLocals.getShort(index); }; - - int getLocalLong(int index) const override { return mLocals.getLong(index); }; - - float getLocalFloat(int index) const override { return mLocals.getFloat(index); }; - - void setLocalShort(int index, int value) override { mLocals.setShort(index, value); }; - - void setLocalLong(int index, int value) override { mLocals.setLong(index, value); }; - - void setLocalFloat(int index, float value) override { mLocals.setFloat(index, value); }; - - void messageBox(const std::string& message, const std::vector& buttons) override {}; - - void report(const std::string& message) override { std::cout << message << "\n"; }; - - int getGlobalShort(const std::string& name) const override { return {}; }; - - int getGlobalLong(const std::string& name) const override { return {}; }; - - float getGlobalFloat(const std::string& name) const override { return {}; }; - - void setGlobalShort(const std::string& name, int value) override {}; - - void setGlobalLong(const std::string& name, int value) override {}; - - void setGlobalFloat(const std::string& name, float value) override {}; - - std::vector getGlobals() const override { return {}; }; - - char getGlobalType(const std::string& name) const override { return ' '; }; - - std::string getActionBinding(const std::string& action) const override { return {}; }; - - std::string getActorName() const override { return {}; }; - - std::string getNPCRace() const override { return {}; }; - - std::string getNPCClass() const override { return {}; }; - - std::string getNPCFaction() const override { return {}; }; - - std::string getNPCRank() const override { return {}; }; - - std::string getPCName() const override { return {}; }; - - std::string getPCRace() const override { return {}; }; - - std::string getPCClass() const override { return {}; }; - - std::string getPCRank() const override { return {}; }; - - std::string getPCNextRank() const override { return {}; }; - - int getPCBounty() const override { return {}; }; - - std::string getCurrentCellName() const override { return {}; }; - - int getMemberShort(const std::string& id, const std::string& name, bool global) const override - { - auto it = mMembers.find(id); - if(it != mMembers.end()) - return it->second.getShort(name); - return {}; - }; - - int getMemberLong(const std::string& id, const std::string& name, bool global) const override - { - auto it = mMembers.find(id); - if(it != mMembers.end()) - return it->second.getLong(name); - return {}; - }; - - float getMemberFloat(const std::string& id, const std::string& name, bool global) const override - { - auto it = mMembers.find(id); - if(it != mMembers.end()) - return it->second.getFloat(name); - return {}; - }; - - void setMemberShort(const std::string& id, const std::string& name, int value, bool global) override { mMembers[id].setShort(name, value); }; - - void setMemberLong(const std::string& id, const std::string& name, int value, bool global) override { mMembers[id].setLong(name, value); }; - - void setMemberFloat(const std::string& id, const std::string& name, float value, bool global) override { mMembers[id].setFloat(name, value); }; - }; - - struct CompiledScript - { - std::vector mByteCode; - Compiler::Locals mLocals; - - CompiledScript(const std::vector& code, const Compiler::Locals& locals) : mByteCode(code), mLocals(locals) {} - }; - struct MWScriptTest : public ::testing::Test { MWScriptTest() : mErrorHandler(), mParser(mErrorHandler, mCompilerContext) {} @@ -279,7 +46,7 @@ namespace void run(const CompiledScript& script, TestInterpreterContext& context) { - mInterpreter.run(&script.mByteCode[0], script.mByteCode.size(), context); + mInterpreter.run(&script.mByteCode[0], static_cast(script.mByteCode.size()), context); } void installOpcode(int code, Interpreter::Opcode0* opcode) diff --git a/apps/openmw_test_suite/mwscript/test_utils.hpp b/apps/openmw_test_suite/mwscript/test_utils.hpp new file mode 100644 index 0000000000..58218b7000 --- /dev/null +++ b/apps/openmw_test_suite/mwscript/test_utils.hpp @@ -0,0 +1,242 @@ +#ifndef MWSCRIPT_TESTING_UTIL_H +#define MWSCRIPT_TESTING_UTIL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace +{ + class TestCompilerContext : public Compiler::Context + { + public: + bool canDeclareLocals() const override { return true; } + char getGlobalType(const std::string& name) const override { return ' '; } + std::pair getMemberType(const std::string& name, const std::string& id) const override { return {' ', false}; } + bool isId(const std::string& name) const override { return false; } + bool isJournalId(const std::string& name) const override { return false; } + }; + + class TestErrorHandler : public Compiler::ErrorHandler + { + std::vector> mErrors; + + void report(const std::string& message, const Compiler::TokenLoc& loc, Compiler::ErrorHandler::Type type) override + { + if(type == Compiler::ErrorHandler::ErrorMessage) + mErrors.emplace_back(message, loc); + } + + void report(const std::string& message, Compiler::ErrorHandler::Type type) override + { + report(message, {}, type); + } + + public: + void reset() override + { + Compiler::ErrorHandler::reset(); + mErrors.clear(); + } + + const std::vector>& getErrors() const { return mErrors; } + }; + + class LocalVariables + { + std::vector mShorts; + std::vector mLongs; + std::vector mFloats; + + template + T getLocal(int index, const std::vector& vector) const + { + if(index < vector.size()) + return vector[index]; + return {}; + } + + template + void setLocal(T value, int index, std::vector& vector) + { + if(index >= vector.size()) + vector.resize(index + 1); + vector[index] = value; + } + public: + void clear() + { + mShorts.clear(); + mLongs.clear(); + mFloats.clear(); + } + + int getShort(int index) const { return getLocal(index, mShorts); }; + + int getLong(int index) const { return getLocal(index, mLongs); }; + + float getFloat(int index) const { return getLocal(index, mFloats); }; + + void setShort(int index, int value) { setLocal(value, index, mShorts); }; + + void setLong(int index, int value) { setLocal(value, index, mLongs); }; + + void setFloat(int index, float value) { setLocal(value, index, mFloats); }; + }; + + class GlobalVariables + { + std::map mShorts; + std::map mLongs; + std::map mFloats; + + template + T getGlobal(const std::string& name, const std::map& map) const + { + auto it = map.find(name); + if(it != map.end()) + return it->second; + return {}; + } + public: + void clear() + { + mShorts.clear(); + mLongs.clear(); + mFloats.clear(); + } + + int getShort(const std::string& name) const { return getGlobal(name, mShorts); }; + + int getLong(const std::string& name) const { return getGlobal(name, mLongs); }; + + float getFloat(const std::string& name) const { return getGlobal(name, mFloats); }; + + void setShort(const std::string& name, int value) { mShorts[name] = value; }; + + void setLong(const std::string& name, int value) { mLongs[name] = value; }; + + void setFloat(const std::string& name, float value) { mFloats[name] = value; }; + }; + + class TestInterpreterContext : public Interpreter::Context + { + LocalVariables mLocals; + std::map mMembers; + public: + std::string getTarget() const override { return {}; }; + + int getLocalShort(int index) const override { return mLocals.getShort(index); }; + + int getLocalLong(int index) const override { return mLocals.getLong(index); }; + + float getLocalFloat(int index) const override { return mLocals.getFloat(index); }; + + void setLocalShort(int index, int value) override { mLocals.setShort(index, value); }; + + void setLocalLong(int index, int value) override { mLocals.setLong(index, value); }; + + void setLocalFloat(int index, float value) override { mLocals.setFloat(index, value); }; + + void messageBox(const std::string& message, const std::vector& buttons) override {}; + + void report(const std::string& message) override {}; + + int getGlobalShort(const std::string& name) const override { return {}; }; + + int getGlobalLong(const std::string& name) const override { return {}; }; + + float getGlobalFloat(const std::string& name) const override { return {}; }; + + void setGlobalShort(const std::string& name, int value) override {}; + + void setGlobalLong(const std::string& name, int value) override {}; + + void setGlobalFloat(const std::string& name, float value) override {}; + + std::vector getGlobals() const override { return {}; }; + + char getGlobalType(const std::string& name) const override { return ' '; }; + + std::string getActionBinding(const std::string& action) const override { return {}; }; + + std::string getActorName() const override { return {}; }; + + std::string getNPCRace() const override { return {}; }; + + std::string getNPCClass() const override { return {}; }; + + std::string getNPCFaction() const override { return {}; }; + + std::string getNPCRank() const override { return {}; }; + + std::string getPCName() const override { return {}; }; + + std::string getPCRace() const override { return {}; }; + + std::string getPCClass() const override { return {}; }; + + std::string getPCRank() const override { return {}; }; + + std::string getPCNextRank() const override { return {}; }; + + int getPCBounty() const override { return {}; }; + + std::string getCurrentCellName() const override { return {}; }; + + int getMemberShort(const std::string& id, const std::string& name, bool global) const override + { + auto it = mMembers.find(id); + if(it != mMembers.end()) + return it->second.getShort(name); + return {}; + }; + + int getMemberLong(const std::string& id, const std::string& name, bool global) const override + { + auto it = mMembers.find(id); + if(it != mMembers.end()) + return it->second.getLong(name); + return {}; + }; + + float getMemberFloat(const std::string& id, const std::string& name, bool global) const override + { + auto it = mMembers.find(id); + if(it != mMembers.end()) + return it->second.getFloat(name); + return {}; + }; + + void setMemberShort(const std::string& id, const std::string& name, int value, bool global) override { mMembers[id].setShort(name, value); }; + + void setMemberLong(const std::string& id, const std::string& name, int value, bool global) override { mMembers[id].setLong(name, value); }; + + void setMemberFloat(const std::string& id, const std::string& name, float value, bool global) override { mMembers[id].setFloat(name, value); }; + }; + + struct CompiledScript + { + std::vector mByteCode; + Compiler::Locals mLocals; + + CompiledScript(const std::vector& code, const Compiler::Locals& locals) : mByteCode(code), mLocals(locals) {} + }; +} + +#endif \ No newline at end of file