Files
Adminive/backend/tests/synchronized_test.cpp
T
2026-08-07 08:39:15 +08:00

76 lines
2.8 KiB
C++

#include "adminive/adapters/nlohmann_json.hpp"
#include "adminive/http.hpp"
#include <cassert>
#include <string>
namespace synchronized_test {
using Json = nlohmann::json;
struct Section_Config {
int first{1};
int second{2};
};
struct Root_Config {
Section_Config section;
int unrelated{3};
};
struct Counting_Lock {
int depth{};
int lock_count{};
int unlock_count{};
void lock() noexcept {
++depth;
++lock_count;
}
void unlock() noexcept {
--depth;
++unlock_count;
}
};
}
namespace adminive {
template <>
struct Type_Descriptor<synchronized_test::Section_Config> {
static auto get() {
using T = synchronized_test::Section_Config;
return object<T>("section", "Section", ADMINIVE_FIELD(T, first).editable(), ADMINIVE_FIELD(T, second).editable());
}
};
template <>
struct Type_Descriptor<synchronized_test::Root_Config> {
static auto get() {
using T = synchronized_test::Root_Config;
return object<T>("root", "Root", ADMINIVE_FIELD(T, section).editable(), ADMINIVE_FIELD(T, unrelated).editable());
}
};
}
int main() {
using namespace synchronized_test;
adminive::Synchronized_Value<Root_Config, Counting_Lock> guarded;
const Json initial = adminive::to_json<Json>(guarded);
assert(initial.at("section").at("first") == 1);
assert(guarded.mutex().depth == 0);
assert(guarded.mutex().lock_count == 1);
auto section = guarded.member<&Root_Config::section>();
const Json form = adminive::to_amis_form_schema<Json>(section, "/section/data", "Apply");
assert(form.at("data").at("first") == 1);
const auto patch_result = adminive::apply_frontend_patch<Json>(section, Json{{"first", 7}, {"second", 8}});
assert(patch_result.success);
assert(section.snapshot().first == 7);
bool commit_saw_lock{};
adminive::Resource_Transaction<Section_Config> transaction;
transaction.commit = [&](const Section_Config& value, const adminive::Request_Context&) {
commit_saw_lock = guarded.mutex().depth == 1 && value.first == 9 && value.second == 8;
};
adminive::Resource_Service<Section_Config, Json, Counting_Lock> service(section, "/section", std::move(transaction));
const auto response = service.update_response(R"({"first":9})");
assert(response.status == 200);
assert(commit_saw_lock);
assert(section.snapshot().first == 9);
assert(guarded.mutex().depth == 0);
adminive::Synchronized_Value<Section_Config, adminive::Empty_Lock> unlocked;
adminive::Resource_Service<Section_Config, Json, adminive::Empty_Lock> unlocked_service(unlocked, "/unlocked");
const auto unlocked_response = unlocked_service.update_response(R"({"second":11})");
assert(unlocked_response.status == 200);
assert(unlocked.snapshot().second == 11);
return 0;
}