feat(results-and-pipeline): step 0 — result-database
This commit is contained in:
@@ -375,3 +375,34 @@ set_property(
|
||||
PROPERTY ENVIRONMENT_MODIFICATION
|
||||
${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}
|
||||
)
|
||||
|
||||
add_executable(fesa_result_database_tests
|
||||
unit/results/result_database_test.cpp
|
||||
)
|
||||
|
||||
target_compile_features(fesa_result_database_tests PRIVATE cxx_std_20)
|
||||
target_compile_options(
|
||||
fesa_result_database_tests
|
||||
PRIVATE
|
||||
/W4
|
||||
/permissive-
|
||||
/EHsc
|
||||
)
|
||||
|
||||
target_link_libraries(fesa_result_database_tests
|
||||
PRIVATE
|
||||
fesa_core
|
||||
GTest::gtest_main
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME NodalFrame
|
||||
COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
|
||||
--gtest_filter=NodalFrame.*
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME ResultDatabase
|
||||
COMMAND "$<TARGET_FILE:fesa_result_database_tests>"
|
||||
--gtest_filter=ResultDatabase.*
|
||||
)
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <fesa/results/result_database.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
std::array<double, 6> zeros() {
|
||||
return {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
fesa::ResultDatabase valid_database() {
|
||||
fesa::NodalFrame nodal{
|
||||
{fesa::NodeId{0}, fesa::NodeId{1}},
|
||||
{
|
||||
zeros(),
|
||||
{1.0, 2.0, 3.0, 0.1, 0.2, 0.3},
|
||||
},
|
||||
{
|
||||
{-10.0, -20.0, -30.0, -1.0, -2.0, -3.0},
|
||||
zeros(),
|
||||
},
|
||||
};
|
||||
fesa::ResultFrame frame{1.0, std::move(nodal), {}};
|
||||
fesa::ResultStep step{"Load", {std::move(frame)}};
|
||||
return {"1.0.0", {std::move(step)}};
|
||||
}
|
||||
|
||||
bool has_diagnostic(
|
||||
const fesa::Status& status,
|
||||
const std::string_view code) {
|
||||
return std::ranges::any_of(
|
||||
status.diagnostics,
|
||||
[code](const fesa::Diagnostic& diagnostic) {
|
||||
return diagnostic.code == code &&
|
||||
diagnostic.stage == fesa::DiagnosticStage::results &&
|
||||
diagnostic.severity == fesa::Severity::error;
|
||||
});
|
||||
}
|
||||
|
||||
TEST(NodalFrame, AcceptsFiniteSixComponentFieldsWithMatchingNodeIds) {
|
||||
const auto database = valid_database();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_TRUE(status.succeeded);
|
||||
EXPECT_TRUE(status.diagnostics.empty());
|
||||
}
|
||||
|
||||
TEST(NodalFrame, RejectsDisplacementSizeMismatch) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].nodal.displacement.pop_back();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.nodal_size_mismatch"));
|
||||
}
|
||||
|
||||
TEST(NodalFrame, RejectsReactionSizeMismatch) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].nodal.reaction.pop_back();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.nodal_size_mismatch"));
|
||||
}
|
||||
|
||||
TEST(NodalFrame, RejectsDuplicateNodeId) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].nodal.node_ids[1] = fesa::NodeId{0};
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.duplicate_node_id"));
|
||||
}
|
||||
|
||||
TEST(NodalFrame, RejectsNonfiniteDisplacement) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].nodal.displacement[1][2] =
|
||||
std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.nonfinite_value"));
|
||||
}
|
||||
|
||||
TEST(NodalFrame, RejectsNonfiniteReaction) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].nodal.reaction[0][4] =
|
||||
std::numeric_limits<double>::infinity();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.nonfinite_value"));
|
||||
}
|
||||
|
||||
TEST(ResultDatabase, RejectsDuplicateStepName) {
|
||||
auto database = valid_database();
|
||||
database.steps.push_back(database.steps[0]);
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.duplicate_step_name"));
|
||||
}
|
||||
|
||||
TEST(ResultDatabase, RejectsDuplicateFrameTimeWithinStep) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames.push_back(database.steps[0].frames[0]);
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.duplicate_frame_time"));
|
||||
}
|
||||
|
||||
TEST(ResultDatabase, RejectsNonfiniteFrameTime) {
|
||||
auto database = valid_database();
|
||||
database.steps[0].frames[0].step_time =
|
||||
std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
const auto status = fesa::validate_result_database(database);
|
||||
|
||||
EXPECT_FALSE(status.succeeded);
|
||||
EXPECT_TRUE(has_diagnostic(status, "results.nonfinite_value"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user