Add PPI dirty-face payload save automation
This commit is contained in:
@@ -291,6 +291,14 @@ if(TARGET pano_cli)
|
||||
set_tests_properties(pano_cli_save_project_roundtrip_smoke PROPERTIES
|
||||
LABELS "assets;document;integration;desktop-fast")
|
||||
|
||||
add_test(NAME pano_cli_save_project_payload_roundtrip_smoke
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DPANO_CLI=$<TARGET_FILE:pano_cli>
|
||||
-DOUTPUT_PATH=${CMAKE_CURRENT_BINARY_DIR}/data/generated/payload-roundtrip.ppi
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pano_cli_save_project_payload_roundtrip.cmake")
|
||||
set_tests_properties(pano_cli_save_project_payload_roundtrip_smoke PROPERTIES
|
||||
LABELS "assets;document;integration;desktop-fast")
|
||||
|
||||
add_test(NAME pano_cli_parse_layout_smoke
|
||||
COMMAND pano_cli parse-layout --path "${CMAKE_CURRENT_SOURCE_DIR}/data/layouts/simple-layout.xml")
|
||||
set_tests_properties(pano_cli_parse_layout_smoke PROPERTIES
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <bit>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
@@ -392,6 +393,7 @@ void creates_minimal_project_for_roundtrip_load(pp::tests::Harness& h)
|
||||
.height = 128,
|
||||
.layer_name = "Roundtrip",
|
||||
.frame_duration_ms = 333,
|
||||
.dirty_faces = {},
|
||||
});
|
||||
|
||||
PP_EXPECT(h, project.ok());
|
||||
@@ -409,25 +411,90 @@ void creates_minimal_project_for_roundtrip_load(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, index.value().body.layers[0].frames[0].duration_ms == 333U);
|
||||
}
|
||||
|
||||
void creates_minimal_project_with_dirty_face_payload(pp::tests::Harness& h)
|
||||
{
|
||||
const auto png_payload = transparent_png_1x1();
|
||||
const pp::assets::PpiDirtyFacePayloadConfig dirty_faces[] {
|
||||
{
|
||||
.face_index = 2,
|
||||
.x = 4,
|
||||
.y = 5,
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.png_rgba8 = std::span<const std::byte>(png_payload.data(), png_payload.size()),
|
||||
},
|
||||
};
|
||||
const auto project = create_minimal_ppi_project(pp::assets::PpiMinimalProjectConfig {
|
||||
.width = 256,
|
||||
.height = 128,
|
||||
.layer_name = "Payload",
|
||||
.frame_duration_ms = 333,
|
||||
.dirty_faces = std::span<const pp::assets::PpiDirtyFacePayloadConfig>(dirty_faces, 1),
|
||||
});
|
||||
|
||||
PP_EXPECT(h, project.ok());
|
||||
const auto decoded = decode_ppi_project_images(project.value());
|
||||
PP_EXPECT(h, decoded.ok());
|
||||
PP_EXPECT(h, decoded.value().project.body.summary.dirty_face_count == 1U);
|
||||
PP_EXPECT(h, decoded.value().project.body.summary.rgba_face_payload_count == 1U);
|
||||
PP_EXPECT(h, decoded.value().project.body.summary.compressed_face_bytes == png_payload.size());
|
||||
PP_EXPECT(h, decoded.value().faces.size() == 1U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].face_index == 2U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].descriptor.x0 == 4U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].descriptor.y0 == 5U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].image.width == 1U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].image.height == 1U);
|
||||
PP_EXPECT(h, decoded.value().faces[0].image.pixels.size() == 4U);
|
||||
}
|
||||
|
||||
void rejects_invalid_minimal_project_writer_inputs(pp::tests::Harness& h)
|
||||
{
|
||||
const auto png_payload = transparent_png_1x1();
|
||||
const pp::assets::PpiDirtyFacePayloadConfig duplicate_faces[] {
|
||||
{
|
||||
.face_index = 0,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.png_rgba8 = std::span<const std::byte>(png_payload.data(), png_payload.size()),
|
||||
},
|
||||
{
|
||||
.face_index = 0,
|
||||
.x = 1,
|
||||
.y = 1,
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.png_rgba8 = std::span<const std::byte>(png_payload.data(), png_payload.size()),
|
||||
},
|
||||
};
|
||||
const auto no_size = create_minimal_ppi_project(pp::assets::PpiMinimalProjectConfig {
|
||||
.width = 0,
|
||||
.height = 128,
|
||||
.layer_name = "Ink",
|
||||
.frame_duration_ms = 100,
|
||||
.dirty_faces = {},
|
||||
});
|
||||
const auto no_name = create_minimal_ppi_project(pp::assets::PpiMinimalProjectConfig {
|
||||
.width = 128,
|
||||
.height = 128,
|
||||
.layer_name = "",
|
||||
.frame_duration_ms = 100,
|
||||
.dirty_faces = {},
|
||||
});
|
||||
const auto no_duration = create_minimal_ppi_project(pp::assets::PpiMinimalProjectConfig {
|
||||
.width = 128,
|
||||
.height = 128,
|
||||
.layer_name = "Ink",
|
||||
.frame_duration_ms = 0,
|
||||
.dirty_faces = {},
|
||||
});
|
||||
const auto duplicate_dirty_face = create_minimal_ppi_project(pp::assets::PpiMinimalProjectConfig {
|
||||
.width = 128,
|
||||
.height = 128,
|
||||
.layer_name = "Ink",
|
||||
.frame_duration_ms = 100,
|
||||
.dirty_faces = std::span<const pp::assets::PpiDirtyFacePayloadConfig>(duplicate_faces, 2),
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !no_size.ok());
|
||||
@@ -436,6 +503,8 @@ void rejects_invalid_minimal_project_writer_inputs(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, no_name.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !no_duration.ok());
|
||||
PP_EXPECT(h, no_duration.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !duplicate_dirty_face.ok());
|
||||
PP_EXPECT(h, duplicate_dirty_face.status().code == StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -456,6 +525,7 @@ int main()
|
||||
harness.run("rejects_invalid_dirty_face_png_payloads", rejects_invalid_dirty_face_png_payloads);
|
||||
harness.run("rejects_invalid_project_body_summaries", rejects_invalid_project_body_summaries);
|
||||
harness.run("creates_minimal_project_for_roundtrip_load", creates_minimal_project_for_roundtrip_load);
|
||||
harness.run("creates_minimal_project_with_dirty_face_payload", creates_minimal_project_with_dirty_face_payload);
|
||||
harness.run("rejects_invalid_minimal_project_writer_inputs", rejects_invalid_minimal_project_writer_inputs);
|
||||
return harness.finish();
|
||||
}
|
||||
|
||||
62
tests/cmake/pano_cli_save_project_payload_roundtrip.cmake
Normal file
62
tests/cmake/pano_cli_save_project_payload_roundtrip.cmake
Normal file
@@ -0,0 +1,62 @@
|
||||
if(NOT DEFINED PANO_CLI)
|
||||
message(FATAL_ERROR "PANO_CLI must be set")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED OUTPUT_PATH)
|
||||
message(FATAL_ERROR "OUTPUT_PATH must be set")
|
||||
endif()
|
||||
|
||||
get_filename_component(output_dir "${OUTPUT_PATH}" DIRECTORY)
|
||||
file(MAKE_DIRECTORY "${output_dir}")
|
||||
file(REMOVE "${OUTPUT_PATH}")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PANO_CLI}" save-project
|
||||
--path "${OUTPUT_PATH}"
|
||||
--width 96
|
||||
--height 48
|
||||
--layer-name Payload
|
||||
--frame-duration-ms 321
|
||||
--include-test-face-payload
|
||||
RESULT_VARIABLE save_result
|
||||
OUTPUT_VARIABLE save_output
|
||||
ERROR_VARIABLE save_error)
|
||||
|
||||
if(NOT save_result EQUAL 0)
|
||||
message(FATAL_ERROR "save-project with payload failed: ${save_output}${save_error}")
|
||||
endif()
|
||||
|
||||
string(FIND "${save_output}" "\"command\":\"save-project\"" save_command_index)
|
||||
string(FIND "${save_output}" "\"facePayloads\":1" save_payload_index)
|
||||
if(save_command_index LESS 0 OR save_payload_index LESS 0)
|
||||
message(FATAL_ERROR "save-project payload output did not contain expected summary: ${save_output}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${OUTPUT_PATH}")
|
||||
message(FATAL_ERROR "save-project did not create ${OUTPUT_PATH}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PANO_CLI}" load-project --path "${OUTPUT_PATH}"
|
||||
RESULT_VARIABLE load_result
|
||||
OUTPUT_VARIABLE load_output
|
||||
ERROR_VARIABLE load_error)
|
||||
|
||||
if(NOT load_result EQUAL 0)
|
||||
message(FATAL_ERROR "load-project failed after payload save-project: ${load_output}${load_error}")
|
||||
endif()
|
||||
|
||||
string(FIND "${load_output}" "\"command\":\"load-project\"" load_command_index)
|
||||
string(FIND "${load_output}" "\"pixelDataLoaded\":true" load_pixels_index)
|
||||
string(FIND "${load_output}" "\"facePayloads\":1" load_payload_index)
|
||||
string(FIND "${load_output}" "\"width\":96" load_width_index)
|
||||
string(FIND "${load_output}" "\"height\":48" load_height_index)
|
||||
string(FIND "${load_output}" "\"layerNames\":[\"Payload\"]" load_layer_index)
|
||||
if(load_command_index LESS 0
|
||||
OR load_pixels_index LESS 0
|
||||
OR load_payload_index LESS 0
|
||||
OR load_width_index LESS 0
|
||||
OR load_height_index LESS 0
|
||||
OR load_layer_index LESS 0)
|
||||
message(FATAL_ERROR "load-project output did not contain expected payload summary: ${load_output}")
|
||||
endif()
|
||||
Reference in New Issue
Block a user