165 lines
6.3 KiB
C++
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();
|
|
}
|