Centralize legacy document open bridge

This commit is contained in:
2026-06-04 13:20:14 +02:00
parent 1984b71a0a
commit d980b81bd7
9 changed files with 336 additions and 64 deletions

View File

@@ -1,8 +1,81 @@
#include "app_core/document_session.h"
#include "test_harness.h"
#include <string>
namespace {
class FakeDocumentOpenServices final : public pp::app::DocumentOpenServices {
public:
void prompt_import_abr(const pp::app::DocumentOpenRoute& route) override
{
abr_prompts += 1;
last_path = route.path;
call_order += "abr;";
}
void prompt_import_ppbr(const pp::app::DocumentOpenRoute& route) override
{
ppbr_prompts += 1;
last_path = route.path;
call_order += "ppbr;";
}
void open_project_now(const pp::app::DocumentOpenRoute& route) override
{
project_opens += 1;
last_path = route.path;
call_order += "open;";
}
void prompt_discard_unsaved_project(const pp::app::DocumentOpenRoute& route) override
{
discard_prompts += 1;
last_path = route.path;
call_order += "discard;";
}
int abr_prompts = 0;
int ppbr_prompts = 0;
int project_opens = 0;
int discard_prompts = 0;
std::string last_path;
std::string call_order;
};
[[nodiscard]] pp::app::DocumentOpenRoute project_route()
{
return {
.kind = pp::app::DocumentOpenKind::open_project,
.path = "D:/Paint/demo.ppi",
.directory = "D:/Paint",
.name = "demo",
.extension = "ppi",
};
}
[[nodiscard]] pp::app::DocumentOpenRoute abr_route()
{
return {
.kind = pp::app::DocumentOpenKind::import_abr,
.path = "D:/Paint/clouds.abr",
.directory = "D:/Paint",
.name = "clouds",
.extension = "abr",
};
}
[[nodiscard]] pp::app::DocumentOpenRoute ppbr_route()
{
return {
.kind = pp::app::DocumentOpenKind::import_ppbr,
.path = "D:/Paint/brush.ppbr",
.directory = "D:/Paint",
.name = "brush",
.extension = "ppbr",
};
}
void project_open_clean_document_executes_immediately(pp::tests::Harness& harness)
{
PP_EXPECT(harness, pp::app::plan_project_open(false) == pp::app::ProjectOpenDecision::open_now);
@@ -47,6 +120,78 @@ void document_open_brush_imports_prompt_regardless_of_unsaved_state(pp::tests::H
== pp::app::DocumentOpenPlanAction::prompt_import_ppbr);
}
void document_open_executor_dispatches_all_actions(pp::tests::Harness& harness)
{
FakeDocumentOpenServices services;
const auto project = project_route();
const auto abr = abr_route();
const auto ppbr = ppbr_route();
PP_EXPECT(
harness,
pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::open_project_now,
project,
services)
.ok());
PP_EXPECT(
harness,
pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::prompt_discard_unsaved_project,
project,
services)
.ok());
PP_EXPECT(
harness,
pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::prompt_import_abr,
abr,
services)
.ok());
PP_EXPECT(
harness,
pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::prompt_import_ppbr,
ppbr,
services)
.ok());
PP_EXPECT(harness, services.project_opens == 1);
PP_EXPECT(harness, services.discard_prompts == 1);
PP_EXPECT(harness, services.abr_prompts == 1);
PP_EXPECT(harness, services.ppbr_prompts == 1);
PP_EXPECT(harness, services.last_path == "D:/Paint/brush.ppbr");
PP_EXPECT(harness, services.call_order == "open;discard;abr;ppbr;");
}
void document_open_executor_rejects_mismatched_routes(pp::tests::Harness& harness)
{
FakeDocumentOpenServices services;
PP_EXPECT(
harness,
!pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::open_project_now,
abr_route(),
services)
.ok());
PP_EXPECT(
harness,
!pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::prompt_import_abr,
project_route(),
services)
.ok());
PP_EXPECT(
harness,
!pp::app::execute_document_open_plan(
pp::app::DocumentOpenPlanAction::prompt_import_ppbr,
abr_route(),
services)
.ok());
PP_EXPECT(harness, services.call_order.empty());
}
void close_clean_document_executes_immediately(pp::tests::Harness& harness)
{
PP_EXPECT(
@@ -335,6 +480,8 @@ int main()
harness.run(
"document open brush imports prompt regardless of unsaved state",
document_open_brush_imports_prompt_regardless_of_unsaved_state);
harness.run("document open executor dispatches all actions", document_open_executor_dispatches_all_actions);
harness.run("document open executor rejects mismatched routes", document_open_executor_rejects_mismatched_routes);
harness.run("close clean document executes immediately", close_clean_document_executes_immediately);
harness.run("close dirty document opens one prompt", close_dirty_document_opens_one_prompt);
harness.run("save clean existing document is no op", save_clean_existing_document_is_no_op);