Initial commit.
This commit is contained in:
commit
a6013437b2
|
@ -0,0 +1,124 @@
|
|||
# ClangFormatConfigureSource: 'LLVM'
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Merge
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 1
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
- Ensure
|
||||
- EnsureNotNull
|
||||
- Try
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
...
|
|
@ -0,0 +1,11 @@
|
|||
Checks: 'readability-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*,performance-*,cppcoreguidelines-*,
|
||||
bugprone-*,modernize-*,-modernize-use-trailing-return-type,-cppcoreguidelines-non-private-member-variables-in-classes'
|
||||
HeaderFilterRegex: ''
|
||||
AnalyzeTemporaryDtors: false
|
||||
CheckOptions:
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.PrivateMemberCase
|
||||
value: camelBack
|
||||
- key: readability-identifier-naming.PrivateMemberPrefix
|
||||
value: '_'
|
|
@ -0,0 +1,3 @@
|
|||
/cmake-build-debug/
|
||||
/cmake-build-release/
|
||||
/.idea/
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "src/BuildData"]
|
||||
path = src/BuildData
|
||||
url = git@ssh.p-epsilon.com:Deukhoofd/BuildData.git
|
|
@ -0,0 +1,21 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
project(PokemonScriptTester)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")
|
||||
|
||||
|
||||
option(WINDOWS "Whether the build target is Windows or not." OFF)
|
||||
set(STATICC TRUE)
|
||||
|
||||
include(CMakeLists.txt.in)
|
||||
include_pkmnlib()
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp src/*.hpp)
|
||||
add_executable(PokemonScriptTester ${SRC_FILES})
|
||||
target_precompile_headers(PokemonScriptTester PUBLIC src/Precompiled.hxx)
|
||||
add_definitions(-DLEVEL_U8)
|
||||
|
||||
SET(_LINKS Arbutils CreatureLib pkmnLib -lpthread)
|
||||
target_link_libraries(PokemonScriptTester PUBLIC ${_LINKS})
|
||||
target_compile_options(PokemonScriptTester PRIVATE -Wall -Wextra -Werror)
|
|
@ -0,0 +1,52 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
project(PokemonScriptTester NONE)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(pkmnlib
|
||||
GIT_REPOSITORY https://git.p-epsilon.com/Deukhoofd/PkmnLib
|
||||
GIT_TAG master
|
||||
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/PkmnLib"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
CMAKE_ARGS "-DSHARED=${SHARED} -DWINDOWS=${WINDOWS} -DSTATICC=${STATICC}"
|
||||
)
|
||||
|
||||
|
||||
function(include_pkmnlib)
|
||||
# Download and unpack googletest at configure time
|
||||
configure_file(CMakeLists.txt.in PkmnLib/download/CMakeLists.txt)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/download)
|
||||
if (result)
|
||||
message(FATAL_ERROR "CMake step for pkmnlib failed: ${result}")
|
||||
endif ()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/download)
|
||||
if (result)
|
||||
message(FATAL_ERROR "Build step for pkmnlib failed: ${result}")
|
||||
endif ()
|
||||
|
||||
# Add googletest directly to our build. This defines
|
||||
# the gtest and gtest_main targets.
|
||||
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/src/pkmnlib
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/bin
|
||||
EXCLUDE_FROM_ALL)
|
||||
|
||||
execute_process(COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/include)
|
||||
execute_process(COMMAND ln -s ${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/src/pkmnlib/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/include/PkmnLib)
|
||||
execute_process(COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/src/pkmnlib/extern
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/include/PkmnLib/extern)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/bin/CreatureLib/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/bin/Angelscript/src/AngelscriptProj/angelscript/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/PkmnLib/bin/CreatureLib/bin/Arbutils/include)
|
||||
|
||||
|
||||
endfunction()
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
Subproject commit 069eadf7c9f94ca4b8616dca8eb7562c9ecf26e0
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_PRECOMPILED_HXX
|
||||
#define POKEMONSCRIPTTESTER_PRECOMPILED_HXX
|
||||
|
||||
#include <PkmnLib/Precompiled.hxx>
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_PRECOMPILED_HXX
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
||||
#define POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
|
||||
class AssertionFailed : public std::exception {
|
||||
static inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
|
||||
s.erase(0, s.find_first_not_of(t));
|
||||
return s;
|
||||
}
|
||||
static std::string GetLine(const std::string& path, size_t num) {
|
||||
std::ifstream file;
|
||||
file.open(path);
|
||||
|
||||
file.seekg(std::ios::beg);
|
||||
for (size_t i = 0; i < num - 1; ++i) {
|
||||
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
}
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
file.close();
|
||||
line = ltrim(line);
|
||||
return line;
|
||||
}
|
||||
|
||||
char* _msg;
|
||||
|
||||
public:
|
||||
AssertionFailed(const std::string& path, size_t line, const std::string& message = "") {
|
||||
auto l = GetLine(path, line);
|
||||
std::stringstream ss;
|
||||
ss << "Assertion failed at: " << path << ":" << line << std::endl;
|
||||
ss << l;
|
||||
if (message.length() > 0) {
|
||||
ss << std::endl << message;
|
||||
}
|
||||
auto str = ss.str();
|
||||
_msg = new char[str.length() + 1];
|
||||
str.copy(_msg, str.length(), 0);
|
||||
_msg[str.length()] = 0;
|
||||
}
|
||||
|
||||
~AssertionFailed() { delete[] _msg; }
|
||||
|
||||
const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override { return _msg; }
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_ASSERTIONFAILED_HPP
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_TEST_HPP
|
||||
#define POKEMONSCRIPTTESTER_TEST_HPP
|
||||
|
||||
#include <angelscript.h>
|
||||
#include "TestEnvironment.hpp"
|
||||
#include "TestResult.hpp"
|
||||
|
||||
class Test {
|
||||
public:
|
||||
Test(const std::string name, asIScriptFunction* function)
|
||||
: _name(name), _function(function), _env(new TestEnvironment()) {}
|
||||
|
||||
void Run(asIScriptContext* ctx) {
|
||||
ctx->Prepare(_function);
|
||||
ctx->SetUserData(_env);
|
||||
auto e = ctx->Execute();
|
||||
if (e == asEXECUTION_EXCEPTION) {
|
||||
_errorMessage = ctx->GetExceptionString();
|
||||
_result = TestResult::Failed;
|
||||
ctx->Release();
|
||||
return;
|
||||
}
|
||||
ctx->Release();
|
||||
Ensure(e == asEXECUTION_FINISHED);
|
||||
_result = TestResult::Success;
|
||||
}
|
||||
|
||||
inline TestResult GetResult() const noexcept { return _result; }
|
||||
inline const std::string& GetErrorMessage() const noexcept { return _errorMessage; }
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
asIScriptFunction* _function;
|
||||
TestEnvironment* _env;
|
||||
|
||||
TestResult _result = TestResult::NotRan;
|
||||
std::string _errorMessage = "";
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TEST_HPP
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_TESTENVIRONMENT_HPP
|
||||
#define POKEMONSCRIPTTESTER_TESTENVIRONMENT_HPP
|
||||
|
||||
struct TestEnvironment{
|
||||
size_t AssertionCount = 0;
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TESTENVIRONMENT_HPP
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_TESTFUNCTIONS_HPP
|
||||
#define POKEMONSCRIPTTESTER_TESTFUNCTIONS_HPP
|
||||
|
||||
#include <angelscript.h>
|
||||
#include "AssertionFailed.hpp"
|
||||
#include "TestEnvironment.hpp"
|
||||
|
||||
class TestFunctions {
|
||||
private:
|
||||
struct AssertionData {
|
||||
std::string FileName;
|
||||
size_t Line;
|
||||
};
|
||||
|
||||
static AssertionData GetAssertionData() {
|
||||
auto* ctx = asGetActiveContext();
|
||||
TestEnvironment* env = static_cast<TestEnvironment*>(ctx->GetUserData());
|
||||
env->AssertionCount += 1;
|
||||
auto filename = ctx->GetFunction()->GetScriptSectionName();
|
||||
auto line = ctx->GetLineNumber();
|
||||
return AssertionData{
|
||||
.FileName = filename,
|
||||
.Line = (size_t)line,
|
||||
};
|
||||
}
|
||||
|
||||
static bool Assert(bool value) {
|
||||
if (!value) {
|
||||
auto data = GetAssertionData();
|
||||
throw AssertionFailed(data.FileName, data.Line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GetEqualityMessage(expected, actual) \
|
||||
std::string eqMsg; \
|
||||
{ \
|
||||
std::ostringstream ss; \
|
||||
ss << "Expected: '" << std::to_string(expected) << "', but was: '" << std::to_string(actual) << "'"; \
|
||||
eqMsg = ss.str(); \
|
||||
}
|
||||
|
||||
static bool AssertEquals(i32 expected, i32 actual) {
|
||||
if (expected != actual) {
|
||||
auto data = GetAssertionData();
|
||||
GetEqualityMessage(expected, actual);
|
||||
throw AssertionFailed(data.FileName, data.Line, eqMsg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Register(AngelScriptResolver* scriptResolver) {
|
||||
auto engine = scriptResolver->GetBuilder().GetEngine();
|
||||
Ensure(engine->RegisterGlobalFunction("bool Assert(bool expression)", asFUNCTION(Assert), asCALL_CDECL) >= 0);
|
||||
Ensure(engine->RegisterGlobalFunction("bool AssertEquals(int expected, int actual)", asFUNCTION(AssertEquals),
|
||||
asCALL_CDECL) >= 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TESTFUNCTIONS_HPP
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_TESTRESULT_HPP
|
||||
#define POKEMONSCRIPTTESTER_TESTRESULT_HPP
|
||||
|
||||
ENUM(TestResult, u8, NotRan, Success, Failed)
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TESTRESULT_HPP
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef POKEMONSCRIPTTESTER_TESTRUNNER_HPP
|
||||
#define POKEMONSCRIPTTESTER_TESTRUNNER_HPP
|
||||
|
||||
#include <PkmnLib/ScriptResolving/AngelScript/AngelScriptMetadata.hpp>
|
||||
#include "Test.hpp"
|
||||
|
||||
class TestRunner {
|
||||
ArbUt::Dictionary<std::string, Test> _tests;
|
||||
|
||||
public:
|
||||
TestRunner(AngelScriptResolver* scriptResolver) {
|
||||
const auto* module = scriptResolver->GetMainModule();
|
||||
auto builder = scriptResolver->GetBuilder();
|
||||
for (u32 i = 0; i < module->GetFunctionCount(); ++i) {
|
||||
auto* func = module->GetFunctionByIndex(i);
|
||||
auto metaData = builder.GetMetadataForFunc(func);
|
||||
for (const auto& m : metaData) {
|
||||
auto meta = AngelscriptMetadata(m);
|
||||
if (meta.GetIdentifier() == "Test"_cnc) {
|
||||
auto name = meta.GetParameter("name"_cnc);
|
||||
_tests.Insert(name, Test(name, func));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunAll(asIScriptEngine* engine) {
|
||||
auto ctx = engine->CreateContext();
|
||||
for (auto& test : _tests) {
|
||||
test.second.Run(ctx);
|
||||
}
|
||||
|
||||
for (auto& test : _tests) {
|
||||
if (test.second.GetResult() == TestResult::Failed) {
|
||||
std::cout << "Test '" << test.first << "' failed with message: " << std::endl;
|
||||
std::cout << test.second.GetErrorMessage() << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // POKEMONSCRIPTTESTER_TESTRUNNER_HPP
|
|
@ -0,0 +1,56 @@
|
|||
#include <PkmnLib/ScriptResolving/AngelScript/AngelScriptResolver.hpp>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include "../extern/args.hpp"
|
||||
#include "BuildData/BuildLibrary.hpp"
|
||||
#include "Tester/TestFunctions.hpp"
|
||||
#include "Tester/TestRunner.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
args::ArgumentParser parser("PkmnLib Script Tester.", "");
|
||||
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
|
||||
|
||||
std::string workingDirectory;
|
||||
|
||||
args::HelpFlag helpFlag(parser, "help", "Display this help menu", {'h', "help"});
|
||||
args::ValueFlag<std::string> workingDirFlag(parser, "Working Directory", "Which work directory to use.",
|
||||
{"workdir"});
|
||||
try {
|
||||
parser.ParseCLI(argc, argv);
|
||||
} catch (args::Help&) {
|
||||
std::cout << parser;
|
||||
return 0;
|
||||
} catch (args::ParseError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser;
|
||||
return 1;
|
||||
} catch (args::ValidationError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser;
|
||||
return 1;
|
||||
}
|
||||
if (workingDirFlag) {
|
||||
workingDirectory = args::get(workingDirFlag);
|
||||
}
|
||||
if (!workingDirectory.empty()) {
|
||||
chdir(std::filesystem::path(workingDirectory).c_str());
|
||||
}
|
||||
|
||||
std::function<void(PkmnLib::Battling::ScriptResolver*)> initialize =
|
||||
[](PkmnLib::Battling::ScriptResolver* resolver) {
|
||||
auto* scriptResolver = dynamic_cast<AngelScriptResolver*>(resolver);
|
||||
scriptResolver->DefineWord("TEST");
|
||||
TestFunctions::Register(scriptResolver);
|
||||
};
|
||||
|
||||
auto battleLib = ArbUt::OptionalScopedPtr(BuildLibrary::Build("", initialize));
|
||||
if (!battleLib.HasValue()) {
|
||||
return 1;
|
||||
}
|
||||
auto* scriptResolver = dynamic_cast<AngelScriptResolver*>(battleLib.GetValue()->GetScriptResolver().get());
|
||||
auto testRunner = TestRunner(scriptResolver);
|
||||
auto engine = scriptResolver->GetBuilder().GetEngine();
|
||||
testRunner.RunAll(engine);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue