1
0
mirror of synced 2025-01-18 00:56:49 +01:00

tests: Removed pattern language tests as they are now done in their own repo

This commit is contained in:
WerWolv 2022-04-17 18:11:39 +02:00
parent 17383083fb
commit 1e7ed14810
25 changed files with 2 additions and 1079 deletions

@ -1 +1 @@
Subproject commit 3abaa2a36d833bb3be7a580dff9b89c37c876a18
Subproject commit 956b16fed807615eec144b9ec58d8300749351e0

View File

@ -2,9 +2,8 @@ project(unit_tests)
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
add_custom_target(unit_tests DEPENDS helpers algorithms pattern_language)
add_custom_target(unit_tests DEPENDS helpers algorithms)
add_subdirectory(common)
add_subdirectory(helpers)
add_subdirectory(algorithms)
add_subdirectory(pattern_language)

View File

@ -1,47 +0,0 @@
cmake_minimum_required(VERSION 3.16)
project(pattern_language_tests)
# Add new tests here #
set(AVAILABLE_TESTS
Placement
Structs
Unions
Enums
Literals
Padding
SucceedingAssert
FailingAssert
Bitfields
Math
RValues
Namespaces
ExtraSemicolon
Pointers
Arrays
NestedStructs
)
add_executable(pattern_language_tests
source/main.cpp
source/tests.cpp
)
# ---- No need to change anything from here downwards unless you know what you're doing ---- #
target_include_directories(pattern_language_tests PRIVATE include)
target_link_libraries(pattern_language_tests libimhex)
set_target_properties(pattern_language_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_command(TARGET pattern_language_tests
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/test_data" ${CMAKE_BINARY_DIR})
foreach (test IN LISTS AVAILABLE_TESTS)
add_test(NAME "PatternLanguage/${test}" COMMAND pattern_language_tests "${test}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endforeach ()
add_dependencies(unit_tests ${PROJECT_NAME})

View File

@ -1,65 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <hex/pattern_language/patterns/pattern.hpp>
#define TEST(name) (hex::test::TestPattern *)new hex::test::TestPattern##name()
namespace hex::test {
using namespace pl;
enum class Mode
{
Succeeding,
Failing
};
class TestPattern {
public:
explicit TestPattern(const std::string &name, Mode mode = Mode::Succeeding) : m_mode(mode) {
TestPattern::s_tests.insert({ name, this });
}
virtual ~TestPattern() = default;
template<typename T>
static std::unique_ptr<T> create(const std::string &typeName, const std::string &varName, auto... args) {
auto pattern = std::make_unique<T>(nullptr, args...);
pattern->setTypeName(typeName);
pattern->setVariableName(varName);
return std::move(pattern);
}
[[nodiscard]] virtual std::string getSourceCode() const = 0;
[[nodiscard]] virtual const std::vector<std::unique_ptr<Pattern>> &getPatterns() const final { return this->m_patterns; }
virtual void addPattern(std::unique_ptr<Pattern> &&pattern) final {
this->m_patterns.push_back(std::move(pattern));
}
[[nodiscard]] auto failing() {
this->m_mode = Mode::Failing;
return this;
}
[[nodiscard]] Mode getMode() {
return this->m_mode;
}
[[nodiscard]] static auto &getTests() {
return TestPattern::s_tests;
}
private:
std::vector<std::unique_ptr<Pattern>> m_patterns;
Mode m_mode;
static inline std::map<std::string, TestPattern *> s_tests;
};
}

View File

@ -1,60 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_struct.hpp>
#include <hex/pattern_language/patterns/pattern_array_dynamic.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
#include <vector>
namespace hex::test {
class TestPatternArrays : public TestPattern {
public:
TestPatternArrays() : TestPattern("Arrays") {
auto first = create<PatternArrayStatic>("u8", "first", 0x0, sizeof(u8[4]));
first->setEntries(create<PatternUnsigned>("u8", "", 0x0, sizeof(u8)), 4);
auto second = create<PatternArrayStatic>("u8", "second", 0x4, sizeof(u8[4]));
second->setEntries(create<PatternUnsigned>("u8", "", 0x4, sizeof(u8)), 4);
auto testStruct = create<PatternStruct>("Signature", "sign", 0x0, sizeof(u8[8]));
std::vector<std::shared_ptr<pl::Pattern>> structMembers;
{
structMembers.push_back(std::move(first));
structMembers.push_back(std::move(second));
}
testStruct->setMembers(std::move(structMembers));
addPattern(std::move(testStruct));
}
~TestPatternArrays() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
fn end_of_signature() {
return $ >= 8;
};
struct Signature {
u8 first[4];
u8 second[while(!end_of_signature())];
};
Signature sign @ 0x0;
std::assert(sign.first[0] == 0x89, "Invalid 1st byte of signature");
std::assert(sign.first[1] == 0x50, "Invalid 2nd byte of signature");
std::assert(sign.first[2] == 0x4E, "Invalid 3rd byte of signature");
std::assert(sign.first[3] == 0x47, "Invalid 4th byte of signature");
std::assert(sizeof(sign.second) == 4, "Invalid size of signature");
std::assert(sign.second[0] == 0x0D, "Invalid 5th byte of signature");
std::assert(sign.second[1] == 0x0A, "Invalid 6th byte of signature");
std::assert(sign.second[2] == 0x1A, "Invalid 7th byte of signature");
std::assert(sign.second[3] == 0x0A, "Invalid 8th byte of signature");
)";
}
};
}

View File

@ -1,48 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_bitfield.hpp>
namespace hex::test {
class TestPatternBitfields : public TestPattern {
public:
TestPatternBitfields() : TestPattern("Bitfields") {
auto testBitfield = create<PatternBitfield>("TestBitfield", "testBitfield", 0x12, (4 * 4) / 8);
testBitfield->setEndian(std::endian::big);
std::vector<std::shared_ptr<pl::Pattern>> bitfieldFields;
{
bitfieldFields.push_back(create<PatternBitfieldField>("", "a", 0x12, 0, 4, testBitfield.get()));
bitfieldFields.push_back(create<PatternBitfieldField>("", "b", 0x12, 4, 4, testBitfield.get()));
bitfieldFields.push_back(create<PatternBitfieldField>("", "c", 0x12, 8, 4, testBitfield.get()));
bitfieldFields.push_back(create<PatternBitfieldField>("", "d", 0x12, 12, 4, testBitfield.get()));
}
testBitfield->setFields(std::move(bitfieldFields));
addPattern(std::move(testBitfield));
}
~TestPatternBitfields() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
bitfield TestBitfield {
a : 4;
b : 4;
c : 4;
d : 4;
};
be TestBitfield testBitfield @ 0x12;
std::assert(testBitfield.a == 0x0A, "Field A invalid");
std::assert(testBitfield.b == 0x00, "Field B invalid");
std::assert(testBitfield.c == 0x04, "Field C invalid");
std::assert(testBitfield.d == 0x03, "Field D invalid");
)";
}
};
}

View File

@ -1,41 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_enum.hpp>
namespace hex::test {
class TestPatternEnums : public TestPattern {
public:
TestPatternEnums() : TestPattern("Enums") {
auto testEnum = create<PatternEnum>("TestEnum", "testEnum", 0x08, sizeof(u32));
testEnum->setEnumValues({
{u128(0x00), "A"},
{ i128(0x0C), "B"},
{ u128(0x0D), "C"},
{ u128(0x0E), "D"},
});
testEnum->setEndian(std::endian::big);
addPattern(std::move(testEnum));
}
~TestPatternEnums() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
enum TestEnum : u32 {
A,
B = 0x0C,
C,
D
};
be TestEnum testEnum @ 0x08;
std::assert(testEnum == TestEnum::C, "Invalid enum value");
)";
}
};
}

View File

@ -1,20 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternExample : public TestPattern {
public:
TestPatternExample() : TestPattern("") {
}
~TestPatternExample() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
)";
}
};
}

View File

@ -1,32 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternExtraSemicolon : public TestPattern {
public:
TestPatternExtraSemicolon() : TestPattern("ExtraSemicolon") {
}
~TestPatternExtraSemicolon() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
struct Test {
u32 x;;;
u8 y;
float z;;
};;
struct Test2 {
u32 x;
u32 y;
};
Test test @ 0x00;;;
Test test2 @ 0x10;
)";
}
};
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternFailingAssert : public TestPattern {
public:
TestPatternFailingAssert() : TestPattern("FailingAssert", Mode::Failing) {
}
~TestPatternFailingAssert() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
#define MSG "Error"
std::assert(false, MSG);
)";
}
};
}

View File

@ -1,29 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternLiterals : public TestPattern {
public:
TestPatternLiterals() : TestPattern("Literals") {
}
~TestPatternLiterals() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
#define MSG "Invalid literal"
std::assert(255 == 0xFF, MSG);
std::assert(0xAA == 0b10101010, MSG);
std::assert(12345 != 67890, MSG);
std::assert(100U == 0x64U, MSG);
std::assert(-100 == -0x64, MSG);
std::assert(3.14159F > 1.414D, MSG);
std::assert('A' == 0x41, MSG);
)";
}
};
}

View File

@ -1,73 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternMath : public TestPattern {
public:
TestPatternMath() : TestPattern("Math") {
}
~TestPatternMath() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
// Compare operations
std::assert(123 == 123, "== operation error");
std::assert(123 != 567, "!= operation error");
std::assert(111 < 222, "< operation error");
std::assert(333 > 222, "> operation error");
std::assert(100 >= 100, ">= operation error");
std::assert(200 <= 200, "<= operation error");
// Boolean operations
std::assert(true, "true literal invalid");
std::assert(true && true, "&& operator error");
std::assert(false || true, "|| operator error");
std::assert(true ^^ false, "^^ operator error");
std::assert(!false, "! operator error");
// Bitwise operations
std::assert(0xFF00FF | 0x00AA00 == 0xFFAAFF, "| operator error");
std::assert(0xFFFFFF & 0x00FF00 == 0x00FF00, "& operator error");
std::assert(0xFFFFFF ^ 0x00AA00 == 0xFF55FF, "^ operator error");
std::assert(~0x00U == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "~ operator error");
std::assert(0xAA >> 4 == 0x0A, ">> operator error");
std::assert(0xAA << 4 == 0xAA0, "<< operator error");
// Basic operations
std::assert(100 + 200 == 300, "+ operator error");
std::assert(400 - 200 == 200, "- operator error");
std::assert(10 * 20 == 200, "* operator error");
std::assert(200 / 100 == 2, "/ operator error");
std::assert(100 % 2 == 0, "% operator error");
// Special operators
std::assert($ == 0, "$ operator error");
std::assert(((10 == 20) ? 30 : 40) == 40, "?: operator error");
// Type operators
struct TypeTest { u32 x, y, z; };
TypeTest typeTest @ 0x100;
std::assert(addressof(typeTest) == 0x100, "addressof operator error");
std::assert(sizeof(typeTest) == 3 * 4, "sizeof operator error");
// Properties
std::assert(100 + 200 == 200 + 100, "+ operator commutativity error");
std::assert(100 - 200 != 200 - 100, "- operator commutativity error");
std::assert(100 * 200 == 200 * 100, "* operator commutativity error");
std::assert(100F / 200F != 200F / 100F, "/ operator commutativity error");
std::assert(10 + (20 + 30) == (10 + 20) + 30, "+ operator associativity error");
std::assert(10 - (20 - 30) != (10 - 20) - 30, "- operator associativity error");
std::assert(10 * (20 * 30) == (10 * 20) * 30, "* operator associativity error");
std::assert(10F / (20F / 30F) != (10F / 20F) / 30F, "/ operator associativity error");
std::assert(10 * (20 + 30) == 10 * 20 + 10 * 30, "* operator distributivity error");
std::assert(10F / (20F + 30F) != 10F / 20F + 10F / 30F, "/ operator distributivity error");
)";
}
};
}

View File

@ -1,39 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternNamespaces : public TestPattern {
public:
TestPatternNamespaces() : TestPattern("Namespaces") {
}
~TestPatternNamespaces() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
namespace A {
struct Test {
u32 x;
};
}
namespace B {
struct Test {
u16 x;
};
}
using ATest = A::Test;
A::Test test1 @ 0x10;
ATest test2 @ 0x20;
B::Test test3 @ 0x20;
std::assert(sizeof(test1) == sizeof(test2), "error using namespaced type");
std::assert(sizeof(test2) != sizeof(test3), "error differentiating two namespace types with same name");
)";
}
};
}

View File

@ -1,83 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_struct.hpp>
#include <hex/pattern_language/patterns/pattern_array_dynamic.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
#include <vector>
namespace hex::test {
class TestPatternNestedStructs : public TestPattern {
public:
TestPatternNestedStructs() : TestPattern("NestedStructs") {
const size_t HEADER_START = 0x0;
const size_t HEADER_SIZE = sizeof(u8);
const size_t BODY_START = HEADER_SIZE;
const size_t BODY_SIZE = 0x89 - 1;
auto data = create<PatternStruct>("Data", "data", HEADER_START, HEADER_SIZE + BODY_SIZE);
{
auto hdr = create<PatternStruct>("Header", "hdr", HEADER_START, HEADER_SIZE);
{
std::vector<std::shared_ptr<pl::Pattern>> hdrMembers {
std::shared_ptr(create<PatternUnsigned>("u8", "len", HEADER_START, sizeof(u8)))
};
hdr->setMembers(std::move(hdrMembers));
}
auto body = create<PatternStruct>("Body", "body", BODY_START, BODY_SIZE);
{
auto bodyArray = create<PatternArrayStatic>("u8", "arr", BODY_START, BODY_SIZE);
bodyArray->setEntries(create<PatternUnsigned>("u8", "", BODY_START, sizeof(u8)), BODY_SIZE);
std::vector<std::shared_ptr<pl::Pattern>> bodyMembers {
std::shared_ptr(std::move(bodyArray))
};
body->setMembers(std::move(bodyMembers));
}
std::vector<std::shared_ptr<pl::Pattern>> dataMembers {
std::shared_ptr(std::move(hdr)),
std::shared_ptr(std::move(body))
};
data->setMembers(std::move(dataMembers));
}
addPattern(std::move(data));
}
~TestPatternNestedStructs() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
fn end_of_body() {
u32 start = addressof(parent.parent.hdr);
u32 len = parent.parent.hdr.len;
u32 end = start + len;
return $ >= end;
};
struct Header {
u8 len;
};
struct Body {
u8 arr[while(!end_of_body())];
};
struct Data {
Header hdr;
Body body;
};
Data data @ 0x0;
std::assert(data.hdr.len == 0x89, "Invalid length");
std::assert(sizeof(data.body.arr) == 0x89 - 1, "Invalid size of body");
)";
}
};
}

View File

@ -1,49 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_signed.hpp>
#include <hex/pattern_language/patterns/pattern_struct.hpp>
#include <hex/pattern_language/patterns/pattern_padding.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
namespace hex::test {
class TestPatternPadding : public TestPattern {
public:
TestPatternPadding() : TestPattern("Padding") {
auto testStruct = create<PatternStruct>("TestStruct", "testStruct", 0x100, sizeof(i32) + 20 + sizeof(u8[0x10]));
auto variable = create<PatternSigned>("s32", "variable", 0x100, sizeof(i32));
auto padding = create<PatternPadding>("padding", "", 0x100 + sizeof(i32), 20);
auto array = create<PatternArrayStatic>("u8", "array", 0x100 + sizeof(i32) + 20, sizeof(u8[0x10]));
array->setEntries(create<PatternUnsigned>("u8", "", 0x100 + sizeof(i32) + 20, sizeof(u8)), 0x10);
std::vector<std::shared_ptr<pl::Pattern>> structMembers;
{
structMembers.push_back(std::move(variable));
structMembers.push_back(std::move(padding));
structMembers.push_back(std::move(array));
}
testStruct->setMembers(std::move(structMembers));
addPattern(std::move(testStruct));
}
~TestPatternPadding() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
struct TestStruct {
s32 variable;
padding[20];
u8 array[0x10];
};
TestStruct testStruct @ 0x100;
)";
}
};
}

View File

@ -1,35 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
namespace hex::test {
class TestPatternPlacement : public TestPattern {
public:
TestPatternPlacement() : TestPattern("Placement") {
// placementVar
{
addPattern(create<PatternUnsigned>("u32", "placementVar", 0x00, sizeof(u32)));
}
// placementArray
{
auto placementArray = create<PatternArrayStatic>("u8", "placementArray", 0x10, sizeof(u8) * 10);
placementArray->setEntries(std::move(create<PatternUnsigned>("u8", "", 0x10, sizeof(u8))), 10);
addPattern(std::move(placementArray));
}
}
~TestPatternPlacement() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
u32 placementVar @ 0x00;
u8 placementArray[10] @ 0x10;
)";
}
};
}

View File

@ -1,32 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_pointer.hpp>
namespace hex::test {
class TestPatternPointers : public TestPattern {
public:
TestPatternPointers() : TestPattern("Pointers") {
// placementPointer
{
auto placementPointer = create<PatternPointer>("", "placementPointer", 0x0C, sizeof(u8));
placementPointer->setPointedAtAddress(0x49);
auto pointedTo = create<PatternUnsigned>("u32", "", 0x49, sizeof(u32));
placementPointer->setPointedAtPattern(std::move(pointedTo));
addPattern(std::move(placementPointer));
}
}
~TestPatternPointers() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
u32 *placementPointer : u8 @ 0x0C;
)";
}
};
}

View File

@ -1,37 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternRValues : public TestPattern {
public:
TestPatternRValues() : TestPattern("RValues") {
}
~TestPatternRValues() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
union C {
u8 y;
u8 array[parent.parent.x];
};
struct B {
C *c : u8;
};
struct A {
u8 x;
B b;
};
A a @ 0x00;
std::assert(sizeof(a.b.c) == a.x && a.x != 0x00, "RValue parent test failed!");
std::assert(a.b.c.y == a.b.c.array[0], "RValue array access test failed!");
)";
}
};
}

View File

@ -1,44 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_signed.hpp>
#include <hex/pattern_language/patterns/pattern_struct.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
namespace hex::test {
class TestPatternStructs : public TestPattern {
public:
TestPatternStructs() : TestPattern("Structs") {
auto testStruct = create<PatternStruct>("TestStruct", "testStruct", 0x100, sizeof(i32) + sizeof(u8[0x10]));
auto variable = create<PatternSigned>("s32", "variable", 0x100, sizeof(i32));
auto array = create<PatternArrayStatic>("u8", "array", 0x100 + sizeof(i32), sizeof(u8[0x10]));
array->setEntries(create<PatternUnsigned>("u8", "", 0x100 + sizeof(i32), sizeof(u8)), 0x10);
std::vector<std::shared_ptr<pl::Pattern>> structMembers;
{
structMembers.push_back(std::move(variable));
structMembers.push_back(std::move(array));
}
testStruct->setMembers(std::move(structMembers));
addPattern(std::move(testStruct));
}
~TestPatternStructs() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
struct TestStruct {
s32 variable;
u8 array[0x10];
};
TestStruct testStruct @ 0x100;
)";
}
};
}

View File

@ -1,26 +0,0 @@
#pragma once
#include "test_pattern.hpp"
namespace hex::test {
class TestPatternSucceedingAssert : public TestPattern {
public:
TestPatternSucceedingAssert() : TestPattern("SucceedingAssert") {
}
~TestPatternSucceedingAssert() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
#define MSG "Error"
std::assert(true, MSG);
std::assert(100 == 100, MSG);
std::assert(50 < 100, MSG);
std::assert(1, MSG);
)";
}
};
}

View File

@ -1,45 +0,0 @@
#pragma once
#include "test_pattern.hpp"
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_signed.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
#include <hex/pattern_language/patterns/pattern_union.hpp>
namespace hex::test {
class TestPatternUnions : public TestPattern {
public:
TestPatternUnions() : TestPattern("Unions") {
auto testUnion = create<PatternUnion>("TestUnion", "testUnion", 0x200, sizeof(u128));
auto array = create<PatternArrayStatic>("s32", "array", 0x200, sizeof(i32[2]));
array->setEntries(create<PatternSigned>("s32", "", 0x200, sizeof(i32)), 2);
auto variable = create<PatternUnsigned>("u128", "variable", 0x200, sizeof(u128));
std::vector<std::shared_ptr<pl::Pattern>> unionMembers;
{
unionMembers.push_back(std::move(array));
unionMembers.push_back(std::move(variable));
}
testUnion->setMembers(std::move(unionMembers));
addPattern(std::move(testUnion));
}
~TestPatternUnions() override = default;
[[nodiscard]] std::string getSourceCode() const override {
return R"(
union TestUnion {
s32 array[2];
u128 variable;
};
TestUnion testUnion @ 0x200;
)";
}
};
}

View File

@ -1,55 +0,0 @@
#include <hex/providers/provider.hpp>
#include <hex/helpers/file.hpp>
#include <hex/helpers/logger.hpp>
#include <stdexcept>
namespace hex::test {
using namespace hex::prv;
class TestProvider : public prv::Provider {
public:
TestProvider() : Provider(), m_testFile(fs::File("test_data", fs::File::Mode::Read)) {
if (!this->m_testFile.isValid() || this->m_testFile.getSize() == 0) {
hex::log::fatal("Failed to open test data!");
throw std::runtime_error("");
}
}
~TestProvider() override = default;
[[nodiscard]] bool isAvailable() const override { return true; }
[[nodiscard]] bool isReadable() const override { return true; }
[[nodiscard]] bool isWritable() const override { return false; }
[[nodiscard]] bool isResizable() const override { return false; }
[[nodiscard]] bool isSavable() const override { return false; }
[[nodiscard]] std::string getName() const override {
return "";
}
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override {
return {};
}
void readRaw(u64 offset, void *buffer, size_t size) override {
this->m_testFile.seek(offset);
this->m_testFile.readBuffer(static_cast<u8 *>(buffer), size);
}
void writeRaw(u64 offset, const void *buffer, size_t size) override {
this->m_testFile.seek(offset);
this->m_testFile.write(static_cast<const u8 *>(buffer), size);
}
[[nodiscard]] size_t getActualSize() const override {
return this->m_testFile.getSize();
}
bool open() override { return true; }
void close() override { }
private:
fs::File m_testFile;
};
}

View File

@ -1,156 +0,0 @@
#include <map>
#include <string>
#include <cstdlib>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/pattern_language/pattern_language.hpp>
#include <hex/pattern_language/evaluator.hpp>
#include <hex/pattern_language/ast/ast_node.hpp>
#include <hex/pattern_language/patterns/pattern.hpp>
#include <hex/api/content_registry.hpp>
#include "test_provider.hpp"
#include "test_patterns/test_pattern.hpp"
#include <fmt/args.h>
using namespace hex::test;
static std::string format(pl::Evaluator *ctx, const auto &params) {
auto format = pl::Token::literalToString(params[0], true);
std::string message;
fmt::dynamic_format_arg_store<fmt::format_context> formatArgs;
for (u32 i = 1; i < params.size(); i++) {
auto &param = params[i];
std::visit(hex::overloaded {
[&](pl::Pattern *value) {
formatArgs.push_back(value->toString(ctx->getProvider()));
},
[&](auto &&value) {
formatArgs.push_back(value);
} },
param);
}
try {
return fmt::vformat(format, formatArgs);
} catch (fmt::format_error &error) {
pl::LogConsole::abortEvaluation(hex::format("format error: {}", error.what()));
}
}
void addFunctions() {
using namespace hex::ContentRegistry::PatternLanguage;
Namespace nsStd = { "std" };
hex::ContentRegistry::PatternLanguage::addFunction(nsStd, "assert", ParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> Token::Literal {
auto condition = Token::literalToBoolean(params[0]);
auto message = Token::literalToString(params[1], false);
if (!condition)
LogConsole::abortEvaluation(hex::format("assertion failed \"{0}\"", message));
return {};
});
hex::ContentRegistry::PatternLanguage::addFunction(nsStd, "print", ParameterCount::atLeast(1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ctx->getConsole().log(LogConsole::Level::Info, format(ctx, params));
return std::nullopt;
});
}
int test(int argc, char **argv) {
auto &testPatterns = TestPattern::getTests();
// Check if a test to run has been provided
if (argc != 2) {
hex::log::fatal("Invalid number of arguments specified! {}", argc);
return EXIT_FAILURE;
}
// Check if that test exists
std::string testName = argv[1];
if (!testPatterns.contains(testName)) {
hex::log::fatal("No test with name {} found!", testName);
return EXIT_FAILURE;
}
const auto &currTest = testPatterns[testName];
bool failing = currTest->getMode() == Mode::Failing;
auto provider = new TestProvider();
ON_SCOPE_EXIT { delete provider; };
if (provider->getActualSize() == 0) {
hex::log::fatal("Failed to load Testing Data");
return EXIT_FAILURE;
}
pl::PatternLanguage language;
// Check if compilation succeeded
auto result = language.executeString(provider, testPatterns[testName]->getSourceCode());
if (!result) {
hex::log::fatal("Error during compilation!");
if (auto error = language.getError(); error.has_value())
hex::log::info("Compile error: {} : {}", error->getLineNumber(), error->what());
for (auto &[level, message] : language.getConsoleLog())
hex::log::info("Evaluate error: {}", message);
return failing ? EXIT_SUCCESS : EXIT_FAILURE;
}
if (failing) {
hex::log::fatal("Failing test succeeded!");
return EXIT_FAILURE;
}
// Check if the right number of patterns have been produced
if (language.getPatterns().size() != currTest->getPatterns().size() && !currTest->getPatterns().empty()) {
hex::log::fatal("Source didn't produce expected number of patterns");
return EXIT_FAILURE;
}
// Check if the produced patterns are the ones expected
for (u32 i = 0; i < currTest->getPatterns().size(); i++) {
auto &evaluatedPattern = *language.getPatterns()[i];
auto &controlPattern = *currTest->getPatterns()[i];
if (evaluatedPattern != controlPattern) {
hex::log::fatal("Pattern with name {}:{} didn't match template", evaluatedPattern.getTypeName(), evaluatedPattern.getVariableName());
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
int main(int argc, char **argv) {
int result = EXIT_SUCCESS;
addFunctions();
for (u32 i = 0; i < 16; i++) {
result = test(argc, argv);
if (result != EXIT_SUCCESS)
break;
}
ON_SCOPE_EXIT {
for (auto &[key, value] : TestPattern::getTests())
delete value;
};
if (result == EXIT_SUCCESS)
hex::log::info("Success!");
else
hex::log::info("Failed!");
return result;
}

View File

@ -1,37 +0,0 @@
#include <array>
#include "test_patterns/test_pattern_placement.hpp"
#include "test_patterns/test_pattern_structs.hpp"
#include "test_patterns/test_pattern_unions.hpp"
#include "test_patterns/test_pattern_enums.hpp"
#include "test_patterns/test_pattern_literals.hpp"
#include "test_patterns/test_pattern_padding.hpp"
#include "test_patterns/test_pattern_succeeding_assert.hpp"
#include "test_patterns/test_pattern_failing_assert.hpp"
#include "test_patterns/test_pattern_bitfields.hpp"
#include "test_patterns/test_pattern_math.hpp"
#include "test_patterns/test_pattern_rvalues.hpp"
#include "test_patterns/test_pattern_namespaces.hpp"
#include "test_patterns/test_pattern_extra_semicolon.hpp"
#include "test_patterns/test_pattern_pointers.hpp"
#include "test_patterns/test_pattern_arrays.hpp"
#include "test_patterns/test_pattern_nested_structs.hpp"
std::array Tests = {
TEST(Placement),
TEST(Structs),
TEST(Unions),
TEST(Enums),
TEST(Literals),
TEST(Padding),
TEST(SucceedingAssert),
TEST(FailingAssert),
TEST(Bitfields),
TEST(Math),
TEST(RValues),
TEST(Namespaces),
TEST(ExtraSemicolon),
TEST(Pointers),
TEST(Arrays),
TEST(NestedStructs),
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB