Extract PPBR package path validation
This commit is contained in:
@@ -76,6 +76,16 @@ add_test(NAME pp_assets_image_format_tests COMMAND pp_assets_image_format_tests)
|
||||
set_tests_properties(pp_assets_image_format_tests PROPERTIES
|
||||
LABELS "assets;desktop-fast")
|
||||
|
||||
add_executable(pp_assets_brush_package_tests
|
||||
assets/brush_package_tests.cpp)
|
||||
target_link_libraries(pp_assets_brush_package_tests PRIVATE
|
||||
pp_assets
|
||||
pp_test_harness)
|
||||
|
||||
add_test(NAME pp_assets_brush_package_tests COMMAND pp_assets_brush_package_tests)
|
||||
set_tests_properties(pp_assets_brush_package_tests PROPERTIES
|
||||
LABELS "assets;paint;desktop-fast;fuzz")
|
||||
|
||||
add_executable(pp_assets_image_metadata_tests
|
||||
assets/image_metadata_tests.cpp)
|
||||
target_link_libraries(pp_assets_image_metadata_tests PRIVATE
|
||||
@@ -942,7 +952,7 @@ if(TARGET pano_cli)
|
||||
--header-image)
|
||||
set_tests_properties(pano_cli_plan_brush_package_export_smoke PROPERTIES
|
||||
LABELS "app;paint;assets;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"path\":\"D:/Paint/clouds.ppbr\".*\"author\":\"Artist\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":true.*\"hasHeaderImage\":true.*\"dispatches\":1")
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"path\":\"D:/Paint/clouds.ppbr\".*\"author\":\"Artist\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":true.*\"hasHeaderImage\":true.*\"paths\":\\{\"package\":\"D:/Paint/clouds.ppbr\".*\"dataDirectory\":\"D:/Paint/BrushPreviews/clouds_data\".*\"dataDirectoryEnabled\":true.*\"dispatches\":1")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_package_export_rejects_empty_path
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
@@ -952,6 +962,15 @@ if(TARGET pano_cli)
|
||||
set_tests_properties(pano_cli_plan_brush_package_export_rejects_empty_path PROPERTIES
|
||||
LABELS "app;paint;assets;integration;desktop-fast;fuzz")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_package_export_rejects_path_without_directory
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-DPANO_CLI=$<TARGET_FILE:pano_cli>
|
||||
-DEXPECT_NO_DIRECTORY=ON
|
||||
"-DEXPECTED_OUTPUT=PPBR export path must include a directory and file name"
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/expect_pano_cli_plan_brush_package_export_failure.cmake")
|
||||
set_tests_properties(pano_cli_plan_brush_package_export_rejects_path_without_directory PROPERTIES
|
||||
LABELS "app;paint;assets;integration;desktop-fast;fuzz")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_package_export_dest_without_data_smoke
|
||||
COMMAND pano_cli plan-brush-package-export
|
||||
--path D:/Paint/clouds.ppbr
|
||||
@@ -959,7 +978,7 @@ if(TARGET pano_cli)
|
||||
--no-export-data)
|
||||
set_tests_properties(pano_cli_plan_brush_package_export_dest_without_data_smoke PROPERTIES
|
||||
LABELS "app;paint;assets;integration;desktop-fast;fuzz"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":false.*\"dispatches\":1")
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-package-export\".*\"destPath\":\"D:/Paint/BrushPreviews\".*\"exportData\":false.*\"dataDirectory\":\"D:/Paint/BrushPreviews/clouds_data\".*\"dataDirectoryEnabled\":false.*\"dispatches\":1")
|
||||
|
||||
add_test(NAME pano_cli_plan_tools_menu_shortcuts_smoke
|
||||
COMMAND pano_cli plan-tools-menu --command shortcuts)
|
||||
|
||||
155
tests/assets/brush_package_tests.cpp
Normal file
155
tests/assets/brush_package_tests.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "assets/brush_package.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace {
|
||||
|
||||
std::array<std::byte, pp::assets::ppbr_header_size> ppbr_header(std::uint16_t major, std::uint16_t minor)
|
||||
{
|
||||
return {
|
||||
std::byte { 'P' },
|
||||
std::byte { 'P' },
|
||||
std::byte { 'B' },
|
||||
std::byte { 'R' },
|
||||
static_cast<std::byte>(major & 0xffU),
|
||||
static_cast<std::byte>((major >> 8U) & 0xffU),
|
||||
static_cast<std::byte>(minor & 0xffU),
|
||||
static_cast<std::byte>((minor >> 8U) & 0xffU),
|
||||
};
|
||||
}
|
||||
|
||||
void parses_ppbr_header_and_legacy_version_tolerance(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto canonical_bytes = ppbr_header(0, 1);
|
||||
const auto canonical = pp::assets::parse_ppbr_header(canonical_bytes);
|
||||
|
||||
PP_EXPECT(harness, canonical);
|
||||
PP_EXPECT(harness, canonical.value().major == 0U);
|
||||
PP_EXPECT(harness, canonical.value().minor == 1U);
|
||||
|
||||
const auto minor_tolerated_bytes = ppbr_header(0, 2);
|
||||
const auto major_tolerated_bytes = ppbr_header(1, 1);
|
||||
const auto rejected_bytes = ppbr_header(1, 2);
|
||||
const auto legacy_minor_tolerated = pp::assets::parse_ppbr_header(minor_tolerated_bytes);
|
||||
const auto legacy_major_tolerated = pp::assets::parse_ppbr_header(major_tolerated_bytes);
|
||||
const auto rejected = pp::assets::parse_ppbr_header(rejected_bytes);
|
||||
PP_EXPECT(harness, legacy_minor_tolerated);
|
||||
PP_EXPECT(harness, legacy_major_tolerated);
|
||||
PP_EXPECT(harness, !rejected);
|
||||
}
|
||||
|
||||
void rejects_truncated_and_bad_magic_headers(pp::tests::Harness& harness)
|
||||
{
|
||||
const std::array<std::byte, 4> truncated {
|
||||
std::byte { 'P' },
|
||||
std::byte { 'P' },
|
||||
std::byte { 'B' },
|
||||
std::byte { 'R' },
|
||||
};
|
||||
auto bad_magic = ppbr_header(0, 1);
|
||||
bad_magic[2] = std::byte { 'X' };
|
||||
|
||||
const auto truncated_result = pp::assets::parse_ppbr_header(truncated);
|
||||
const auto magic_result = pp::assets::parse_ppbr_header(bad_magic);
|
||||
|
||||
PP_EXPECT(harness, !truncated_result);
|
||||
PP_EXPECT(harness, truncated_result.status().code == pp::foundation::StatusCode::out_of_range);
|
||||
PP_EXPECT(harness, !magic_result);
|
||||
PP_EXPECT(harness, magic_result.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void plans_export_package_and_data_paths(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto regular = pp::assets::plan_ppbr_export_paths(
|
||||
"D:/Paint/clouds",
|
||||
"",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package);
|
||||
PP_EXPECT(harness, regular);
|
||||
if (regular) {
|
||||
PP_EXPECT(harness, regular.value().package_path == "D:/Paint/clouds.ppbr");
|
||||
PP_EXPECT(harness, regular.value().directory == "D:/Paint");
|
||||
PP_EXPECT(harness, regular.value().stem == "clouds");
|
||||
PP_EXPECT(harness, regular.value().extension == "ppbr");
|
||||
PP_EXPECT(harness, regular.value().data_directory == "D:/Paint/clouds_data");
|
||||
PP_EXPECT(harness, regular.value().data_directory_enabled);
|
||||
}
|
||||
|
||||
const auto override = pp::assets::plan_ppbr_export_paths(
|
||||
"/brushes/clouds.ppbr",
|
||||
"/Users/artist/Exports",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::override_directory);
|
||||
PP_EXPECT(harness, override);
|
||||
if (override) {
|
||||
PP_EXPECT(harness, override.value().data_directory == "/Users/artist/Exports/clouds_data");
|
||||
PP_EXPECT(harness, override.value().data_directory_enabled);
|
||||
}
|
||||
|
||||
const auto no_data = pp::assets::plan_ppbr_export_paths(
|
||||
"D:/Paint/clouds.ppbr",
|
||||
"",
|
||||
false,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package);
|
||||
PP_EXPECT(harness, no_data);
|
||||
if (no_data) {
|
||||
PP_EXPECT(harness, !no_data.value().data_directory_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void preserves_legacy_extension_containment_rule(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto path = pp::assets::normalize_ppbr_export_path("D:/Paint/clouds.ppbr.tmp");
|
||||
|
||||
PP_EXPECT(harness, path);
|
||||
PP_EXPECT(harness, path.value() == "D:/Paint/clouds.ppbr.tmp");
|
||||
}
|
||||
|
||||
void rejects_export_paths_that_legacy_regex_could_not_match(pp::tests::Harness& harness)
|
||||
{
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
!pp::assets::plan_ppbr_export_paths(
|
||||
"",
|
||||
"",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package));
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
!pp::assets::plan_ppbr_export_paths(
|
||||
"clouds",
|
||||
"",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package));
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
!pp::assets::plan_ppbr_export_paths(
|
||||
"D:/Paint/.ppbr",
|
||||
"",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package));
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
!pp::assets::plan_ppbr_export_paths(
|
||||
"D:/Paint/clouds.ppbr!",
|
||||
"",
|
||||
true,
|
||||
pp::assets::PpbrDataDirectoryPolicy::next_to_package));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("parses PPBR header and legacy version tolerance", parses_ppbr_header_and_legacy_version_tolerance);
|
||||
harness.run("rejects truncated and bad magic headers", rejects_truncated_and_bad_magic_headers);
|
||||
harness.run("plans export package and data paths", plans_export_package_and_data_paths);
|
||||
harness.run("preserves legacy extension containment rule", preserves_legacy_extension_containment_rule);
|
||||
harness.run("rejects export paths that legacy regex could not match", rejects_export_paths_that_legacy_regex_could_not_match);
|
||||
return harness.finish();
|
||||
}
|
||||
@@ -6,11 +6,24 @@ if(NOT DEFINED EXPECTED_OUTPUT)
|
||||
message(FATAL_ERROR "EXPECTED_OUTPUT must be set")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PANO_CLI}" plan-brush-package-export
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE error)
|
||||
if(NOT DEFINED EXPECT_NO_DIRECTORY)
|
||||
set(EXPECT_NO_DIRECTORY OFF)
|
||||
endif()
|
||||
|
||||
if(EXPECT_NO_DIRECTORY)
|
||||
execute_process(
|
||||
COMMAND "${PANO_CLI}" plan-brush-package-export
|
||||
--path clouds
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE error)
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND "${PANO_CLI}" plan-brush-package-export
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE error)
|
||||
endif()
|
||||
|
||||
if(result EQUAL 0)
|
||||
message(FATAL_ERROR "Expected pano_cli plan-brush-package-export to fail, but it exited 0")
|
||||
|
||||
Reference in New Issue
Block a user