Plan new document creation in app core

This commit is contained in:
2026-06-02 23:14:35 +02:00
parent fd1772a417
commit 853307697a
10 changed files with 284 additions and 21 deletions

View File

@@ -411,6 +411,26 @@ if(TARGET pano_cli)
LABELS "app;integration;desktop-fast"
PASS_REGULAR_EXPRESSION "\"command\":\"plan-document-file\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":true.*\"decision\":\"prompt-overwrite\"")
add_test(NAME pano_cli_plan_new_document_smoke
COMMAND pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3)
set_tests_properties(pano_cli_plan_new_document_smoke PROPERTIES
LABELS "app;integration;desktop-fast"
PASS_REGULAR_EXPRESSION "\"command\":\"plan-new-document\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":false.*\"resolution\":2048.*\"decision\":\"save-now\"")
add_test(NAME pano_cli_plan_new_document_overwrite_smoke
COMMAND pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 1 --target-exists)
set_tests_properties(pano_cli_plan_new_document_overwrite_smoke PROPERTIES
LABELS "app;integration;desktop-fast"
PASS_REGULAR_EXPRESSION "\"command\":\"plan-new-document\".*\"path\":\"D:/Paint/demo.ppi\".*\"exists\":true.*\"resolution\":1024.*\"decision\":\"prompt-overwrite\"")
add_test(NAME pano_cli_plan_new_document_rejects_invalid_resolution
COMMAND "${CMAKE_COMMAND}"
-DPANO_CLI=$<TARGET_FILE:pano_cli>
"-DEXPECTED_OUTPUT=document resolution index is out of range"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_new_document_failure.cmake")
set_tests_properties(pano_cli_plan_new_document_rejects_invalid_resolution PROPERTIES
LABELS "app;integration;desktop-fast;fuzz")
add_test(NAME pano_cli_plan_document_version_first_smoke
COMMAND pano_cli plan-document-version --directory D:/Paint --doc-name demo)
set_tests_properties(pano_cli_plan_document_version_first_smoke PROPERTIES

View File

@@ -175,6 +175,72 @@ void document_file_write_prompts_only_for_existing_targets(pp::tests::Harness& h
== pp::app::DocumentFileWriteDecision::prompt_overwrite);
}
void document_resolution_index_maps_legacy_choices(pp::tests::Harness& harness)
{
const auto first = pp::app::document_resolution_from_index(0);
const auto last = pp::app::document_resolution_from_index(5);
PP_EXPECT(harness, first);
PP_EXPECT(harness, first.value() == 512);
PP_EXPECT(harness, last);
PP_EXPECT(harness, last.value() == 8192);
}
void document_resolution_index_rejects_out_of_range(pp::tests::Harness& harness)
{
const auto negative = pp::app::document_resolution_from_index(-1);
const auto too_large = pp::app::document_resolution_from_index(6);
PP_EXPECT(harness, !negative);
PP_EXPECT(harness, negative.status().code == pp::foundation::StatusCode::out_of_range);
PP_EXPECT(harness, !too_large);
PP_EXPECT(harness, too_large.status().code == pp::foundation::StatusCode::out_of_range);
}
void new_document_plan_builds_target_resolution_and_write_decision(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_new_document(
"D:/Paint",
"demo",
2,
[](const std::string&) { return false; });
PP_EXPECT(harness, plan);
PP_EXPECT(harness, plan.value().target.name == "demo");
PP_EXPECT(harness, plan.value().target.path == "D:/Paint/demo.ppi");
PP_EXPECT(harness, plan.value().resolution == 1536);
PP_EXPECT(harness, plan.value().write_decision == pp::app::DocumentFileWriteDecision::save_now);
}
void new_document_plan_prompts_for_existing_target(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_new_document(
"D:/Paint",
"demo",
1,
[](const std::string& path) { return path == "D:/Paint/demo.ppi"; });
PP_EXPECT(harness, plan);
PP_EXPECT(harness, plan.value().resolution == 1024);
PP_EXPECT(
harness,
plan.value().write_decision == pp::app::DocumentFileWriteDecision::prompt_overwrite);
}
void new_document_plan_rejects_invalid_inputs(pp::tests::Harness& harness)
{
const auto missing_name = pp::app::plan_new_document(
"D:/Paint",
"",
0,
[](const std::string&) { return false; });
const auto invalid_resolution = pp::app::plan_new_document(
"D:/Paint",
"demo",
99,
[](const std::string&) { return false; });
PP_EXPECT(harness, !missing_name);
PP_EXPECT(harness, missing_name.status().code == pp::foundation::StatusCode::invalid_argument);
PP_EXPECT(harness, !invalid_resolution);
PP_EXPECT(harness, invalid_resolution.status().code == pp::foundation::StatusCode::out_of_range);
}
void document_version_target_starts_at_first_version(pp::tests::Harness& harness)
{
const auto target = pp::app::find_next_document_version_target(
@@ -254,6 +320,13 @@ int main()
harness.run("document file target rejects empty name", document_file_target_rejects_empty_name);
harness.run("document file target builds legacy ppi path", document_file_target_builds_legacy_ppi_path);
harness.run("document file write prompts only for existing targets", document_file_write_prompts_only_for_existing_targets);
harness.run("document resolution index maps legacy choices", document_resolution_index_maps_legacy_choices);
harness.run("document resolution index rejects out of range", document_resolution_index_rejects_out_of_range);
harness.run(
"new document plan builds target resolution and write decision",
new_document_plan_builds_target_resolution_and_write_decision);
harness.run("new document plan prompts for existing target", new_document_plan_prompts_for_existing_target);
harness.run("new document plan rejects invalid inputs", new_document_plan_rejects_invalid_inputs);
harness.run("document version target starts at first version", document_version_target_starts_at_first_version);
harness.run("document version target increments existing suffix", document_version_target_increments_existing_suffix);
harness.run("document version target skips existing paths", document_version_target_skips_existing_paths);

View File

@@ -0,0 +1,26 @@
if(NOT DEFINED PANO_CLI)
message(FATAL_ERROR "PANO_CLI is required")
endif()
if(NOT DEFINED EXPECTED_OUTPUT)
message(FATAL_ERROR "EXPECTED_OUTPUT is required")
endif()
execute_process(
COMMAND "${PANO_CLI}" plan-new-document
--work-dir D:/Paint
--name demo
--resolution-index 99
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE error)
if(result EQUAL 0)
message(FATAL_ERROR "pano_cli plan-new-document unexpectedly succeeded: ${output}${error}")
endif()
string(FIND "${output}${error}" "${EXPECTED_OUTPUT}" found_at)
if(found_at EQUAL -1)
message(FATAL_ERROR
"pano_cli plan-new-document failure output did not contain expected text.\nExpected: ${EXPECTED_OUTPUT}\nOutput: ${output}${error}")
endif()