test stuff

This commit is contained in:
Richard Ward
2025-12-18 19:30:38 +00:00
parent a149f5679a
commit 1505415337
5 changed files with 190 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.24)
project(SDL3App LANGUAGES CXX)
option(BUILD_SDL3_APP "Build the SDL3 Vulkan demo" ON)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -9,23 +10,37 @@ if(EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
include("${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
endif()
find_package(SDL3 CONFIG REQUIRED)
find_package(Vulkan REQUIRED)
if(BUILD_SDL3_APP)
find_package(SDL3 CONFIG REQUIRED)
find_package(Vulkan REQUIRED)
endif()
find_package(lua CONFIG REQUIRED)
add_executable(sdl3_app
src/main.cpp
src/app/sdl3_app_core.cpp
src/app/sdl3_app_device.cpp
src/app/sdl3_app_swapchain.cpp
src/app/sdl3_app_pipeline.cpp
src/app/sdl3_app_build.cpp
src/app/sdl3_app_buffers.cpp
src/app/sdl3_app_render.cpp
if(BUILD_SDL3_APP)
add_executable(sdl3_app
src/main.cpp
src/app/sdl3_app_core.cpp
src/app/sdl3_app_device.cpp
src/app/sdl3_app_swapchain.cpp
src/app/sdl3_app_pipeline.cpp
src/app/sdl3_app_build.cpp
src/app/sdl3_app_buffers.cpp
src/app/sdl3_app_render.cpp
src/script/cube_script.cpp
)
target_link_libraries(sdl3_app PRIVATE SDL3::SDL3 Vulkan::Vulkan lua::lua)
target_compile_definitions(sdl3_app PRIVATE SDL_MAIN_HANDLED)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/scripts" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
enable_testing()
add_executable(cube_script_tests
tests/test_cube_script.cpp
src/script/cube_script.cpp
)
target_link_libraries(sdl3_app PRIVATE SDL3::SDL3 Vulkan::Vulkan lua::lua)
target_compile_definitions(sdl3_app PRIVATE SDL_MAIN_HANDLED)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/scripts" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
target_include_directories(cube_script_tests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_link_libraries(cube_script_tests PRIVATE lua::lua)
add_test(NAME cube_script_tests COMMAND cube_script_tests)

20
conanfile.py Normal file
View File

@@ -0,0 +1,20 @@
from conan import ConanFile
class SDL3CppConan(ConanFile):
name = "sdl3cpp"
version = "0.1"
settings = "os", "arch", "compiler", "build_type"
options = {"build_app": [True, False]}
default_options = {
"build_app": True,
"lua/*:shared": False,
"lua/*:fPIC": True,
"lua/*:compile_as_cpp": False,
"lua/*:with_tools": False,
}
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
def requirements(self):
self.requires("lua/5.4.6")
if self.options.build_app:
self.requires("vulkan-loader/1.4.313.0")

View File

@@ -1,14 +0,0 @@
[requires]
lua/5.4.6
vulkan-loader/1.4.313.0
[options]
lua:shared=False
lua:fPIC=True
lua:compile_as_cpp=False
lua:with_tools=False
[generators]
CMakeDeps
CMakeToolchain
VirtualRunEnv

View File

@@ -0,0 +1,42 @@
local function identity_matrix()
return {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}
end
function get_scene_objects()
return {
{
vertices = {
{ position = {0.0, 0.0, 0.0}, color = {1.0, 0.0, 0.0} },
{ position = {1.0, 0.0, 0.0}, color = {0.0, 1.0, 0.0} },
{ position = {0.0, 1.0, 0.0}, color = {0.0, 0.0, 1.0} },
},
indices = {1, 2, 3},
compute_model_matrix = function(time)
return identity_matrix()
end,
shader_key = "test",
},
}
end
function get_shader_paths()
return {
test = {
vertex = "shaders/test.vert.spv",
fragment = "shaders/test.frag.spv",
},
}
end
function get_view_projection(aspect)
return identity_matrix()
end
function compute_model_matrix(time)
return identity_matrix()
end

View File

@@ -0,0 +1,97 @@
#include "script/cube_script.hpp"
#include <array>
#include <cmath>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
namespace {
constexpr std::array<float, 16> kIdentityMatrix = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f,
};
bool ApproximatelyEqual(float a, float b, float eps = 1e-5f) {
return std::fabs(a - b) <= eps;
}
bool ExpectIdentity(const std::array<float, 16>& actual, const std::string& label, int& failures) {
for (size_t i = 0; i < actual.size(); ++i) {
if (!ApproximatelyEqual(actual[i], kIdentityMatrix[i])) {
std::cerr << label << " differs at index " << i << " (" << actual[i] << " vs "
<< kIdentityMatrix[i] << ")\n";
++failures;
return false;
}
}
return true;
}
std::filesystem::path GetTestScriptPath() {
auto testDir = std::filesystem::path(__FILE__).parent_path();
return testDir / "scripts" / "unit_cube_logic.lua";
}
void Assert(bool condition, const std::string& message, int& failures) {
if (!condition) {
std::cerr << "test failure: " << message << '\n';
++failures;
}
}
} // namespace
int main() {
int failures = 0;
auto scriptPath = GetTestScriptPath();
std::cout << "Loading Lua fixture: " << scriptPath << '\n';
try {
sdl3cpp::script::CubeScript cubeScript(scriptPath);
auto objects = cubeScript.LoadSceneObjects();
Assert(objects.size() == 1, "expected exactly one scene object", failures);
if (!objects.empty()) {
const auto& object = objects.front();
Assert(object.vertices.size() == 3, "scene object should yield three vertices", failures);
Assert(object.indices.size() == 3, "scene object should yield three indices", failures);
Assert(object.shaderKey == "test", "shader key should match fixture", failures);
const std::vector<uint16_t> expectedIndices{0, 1, 2};
Assert(object.indices == expectedIndices, "indices should be zero-based", failures);
Assert(object.computeModelMatrixRef != LUA_REFNIL,
"vertex object must keep a Lua reference", failures);
auto objectMatrix = cubeScript.ComputeModelMatrix(object.computeModelMatrixRef, 0.5f);
ExpectIdentity(objectMatrix, "object compute_model_matrix", failures);
}
auto fallbackMatrix = cubeScript.ComputeModelMatrix(LUA_REFNIL, 1.0f);
ExpectIdentity(fallbackMatrix, "global compute_model_matrix", failures);
auto viewProjection = cubeScript.GetViewProjectionMatrix(1.33f);
ExpectIdentity(viewProjection, "view_projection matrix", failures);
auto shaderMap = cubeScript.LoadShaderPathsMap();
Assert(shaderMap.size() == 1, "expected a single shader variant", failures);
auto testEntry = shaderMap.find("test");
Assert(testEntry != shaderMap.end(), "shader map missing "
"test entry", failures);
if (testEntry != shaderMap.end()) {
Assert(testEntry->second.vertex == "shaders/test.vert.spv", "vertex shader path", failures);
Assert(testEntry->second.fragment == "shaders/test.frag.spv", "fragment shader path", failures);
}
} catch (const std::exception& ex) {
std::cerr << "exception during tests: " << ex.what() << '\n';
return 1;
}
if (failures == 0) {
std::cout << "cube_script_tests: PASSED\n";
} else {
std::cerr << "cube_script_tests: FAILED (" << failures << " errors)\n";
}
return failures;
}