Files
panopainter/tests/app_core/app_startup_tests.cpp

165 lines
6.3 KiB
C++

#include "app_core/app_startup.h"
#include "test_harness.h"
#include <limits>
#include <string>
namespace {
class FakeAppStartupServices final : public pp::app::AppStartupServices {
public:
void store_run_counter(int value) override
{
stored_run_counter = value;
call_order += "store-counter;";
}
void save_preferences() override
{
save_calls += 1;
call_order += "save;";
}
void start_timelapse_recording() override
{
timelapse_starts += 1;
call_order += "timelapse;";
}
void apply_vr_controllers_enabled(bool enabled) override
{
vr_controllers_enabled = enabled;
call_order += "vr-controllers;";
}
void show_license_warning() override
{
license_warnings += 1;
call_order += "license;";
}
int stored_run_counter = 0;
int save_calls = 0;
int timelapse_starts = 0;
bool vr_controllers_enabled = false;
int license_warnings = 0;
std::string call_order;
};
void startup_plan_increments_counter_and_enables_requested_side_effects(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_app_startup(7, true, false, false);
PP_EXPECT(harness, plan);
PP_EXPECT(harness, plan.value().previous_run_counter == 7);
PP_EXPECT(harness, plan.value().next_run_counter == 8);
PP_EXPECT(harness, plan.value().save_preferences);
PP_EXPECT(harness, plan.value().start_timelapse);
PP_EXPECT(harness, !plan.value().vr_controllers_enabled);
PP_EXPECT(harness, plan.value().show_license_warning);
}
void startup_plan_preserves_disabled_optional_work(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_app_startup(0, false, true, true);
PP_EXPECT(harness, plan);
PP_EXPECT(harness, plan.value().next_run_counter == 1);
PP_EXPECT(harness, !plan.value().start_timelapse);
PP_EXPECT(harness, plan.value().vr_controllers_enabled);
PP_EXPECT(harness, !plan.value().show_license_warning);
}
void startup_plan_rejects_invalid_counters(pp::tests::Harness& harness)
{
const auto negative = pp::app::plan_app_startup(-1, true, true, true);
const auto overflow = pp::app::plan_app_startup(std::numeric_limits<int>::max(), true, true, true);
PP_EXPECT(harness, !negative);
PP_EXPECT(harness, negative.status().code == pp::foundation::StatusCode::invalid_argument);
PP_EXPECT(harness, !overflow);
PP_EXPECT(harness, overflow.status().code == pp::foundation::StatusCode::out_of_range);
}
void startup_executor_dispatches_in_stable_order(pp::tests::Harness& harness)
{
FakeAppStartupServices services;
const auto plan = pp::app::plan_app_startup(2, true, true, false);
PP_EXPECT(harness, plan);
PP_EXPECT(harness, pp::app::execute_app_startup_plan(plan.value(), services).ok());
PP_EXPECT(harness, services.stored_run_counter == 3);
PP_EXPECT(harness, services.save_calls == 1);
PP_EXPECT(harness, services.timelapse_starts == 1);
PP_EXPECT(harness, services.vr_controllers_enabled);
PP_EXPECT(harness, services.license_warnings == 1);
PP_EXPECT(harness, services.call_order == "store-counter;save;timelapse;vr-controllers;license;");
}
void startup_executor_preserves_no_op_side_effects(pp::tests::Harness& harness)
{
FakeAppStartupServices services;
auto plan = pp::app::plan_app_startup(4, false, false, true).value();
PP_EXPECT(harness, pp::app::execute_app_startup_plan(plan, services).ok());
PP_EXPECT(harness, services.stored_run_counter == 5);
PP_EXPECT(harness, services.save_calls == 1);
PP_EXPECT(harness, services.timelapse_starts == 0);
PP_EXPECT(harness, !services.vr_controllers_enabled);
PP_EXPECT(harness, services.license_warnings == 0);
PP_EXPECT(harness, services.call_order == "store-counter;save;vr-controllers;");
}
void startup_split_executors_keep_persistence_and_runtime_separate(pp::tests::Harness& harness)
{
FakeAppStartupServices persistence_services;
FakeAppStartupServices runtime_services;
const auto plan = pp::app::plan_app_startup(5, true, false, false);
PP_EXPECT(harness, plan);
PP_EXPECT(harness, pp::app::execute_app_startup_persistence_plan(plan.value(), persistence_services).ok());
PP_EXPECT(harness, persistence_services.stored_run_counter == 6);
PP_EXPECT(harness, persistence_services.save_calls == 1);
PP_EXPECT(harness, persistence_services.timelapse_starts == 0);
PP_EXPECT(harness, persistence_services.license_warnings == 0);
PP_EXPECT(harness, persistence_services.call_order == "store-counter;save;");
PP_EXPECT(harness, pp::app::execute_app_startup_runtime_plan(plan.value(), runtime_services).ok());
PP_EXPECT(harness, runtime_services.stored_run_counter == 0);
PP_EXPECT(harness, runtime_services.save_calls == 0);
PP_EXPECT(harness, runtime_services.timelapse_starts == 1);
PP_EXPECT(harness, !runtime_services.vr_controllers_enabled);
PP_EXPECT(harness, runtime_services.license_warnings == 1);
PP_EXPECT(harness, runtime_services.call_order == "timelapse;vr-controllers;license;");
}
void startup_executor_rejects_malformed_counter_state(pp::tests::Harness& harness)
{
FakeAppStartupServices services;
pp::app::AppStartupPlan plan;
plan.previous_run_counter = 3;
plan.next_run_counter = 3;
PP_EXPECT(harness, !pp::app::execute_app_startup_plan(plan, services).ok());
PP_EXPECT(harness, services.call_order.empty());
}
}
int main()
{
pp::tests::Harness harness;
harness.run(
"startup plan increments counter and enables requested side effects",
startup_plan_increments_counter_and_enables_requested_side_effects);
harness.run("startup plan preserves disabled optional work", startup_plan_preserves_disabled_optional_work);
harness.run("startup plan rejects invalid counters", startup_plan_rejects_invalid_counters);
harness.run("startup executor dispatches in stable order", startup_executor_dispatches_in_stable_order);
harness.run("startup executor preserves no-op side effects", startup_executor_preserves_no_op_side_effects);
harness.run(
"startup split executors keep persistence and runtime separate",
startup_split_executors_keep_persistence_and_runtime_separate);
harness.run("startup executor rejects malformed counter state", startup_executor_rejects_malformed_counter_state);
return harness.finish();
}