Start UI core layout value tests
This commit is contained in:
@@ -114,6 +114,18 @@ target_link_libraries(pp_renderer_api
|
||||
PRIVATE
|
||||
pp_project_warnings)
|
||||
|
||||
add_library(pp_ui_core STATIC
|
||||
src/ui_core/layout_value.cpp)
|
||||
target_include_directories(pp_ui_core
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
target_link_libraries(pp_ui_core
|
||||
PUBLIC
|
||||
pp_foundation
|
||||
pp_project_options
|
||||
PRIVATE
|
||||
pp_project_warnings)
|
||||
|
||||
if(PP_BUILD_TOOLS)
|
||||
add_subdirectory(tools/pano_cli)
|
||||
endif()
|
||||
|
||||
@@ -75,8 +75,8 @@ Known local toolchain state:
|
||||
- Android NDK: `C:\Users\omara\AppData\Local\Android\Sdk\ndk\29.0.14206865`
|
||||
- Android arm64 headless configure/build passes through root CMake and the
|
||||
`platform-build` automation wrapper for `pp_foundation`, `pp_assets`,
|
||||
`pp_paint`, `pp_document`, `pp_renderer_api`, `pano_cli`, and their current
|
||||
headless test binaries.
|
||||
`pp_paint`, `pp_document`, `pp_renderer_api`, `pp_ui_core`, `pano_cli`, and
|
||||
their current headless test binaries.
|
||||
- `vcpkg` is not on PATH yet; see DEBT-0007.
|
||||
|
||||
Known warnings after the current CMake app build:
|
||||
|
||||
@@ -307,9 +307,10 @@ PNG/JPEG signature detection and corrupt/truncated/unsupported tests.
|
||||
`pp_paint` has started with CPU reference math for the five current shader
|
||||
blend modes. `pp_document` has started with a pure canvas/layer model and
|
||||
layer invariant tests. `pp_renderer_api` has started with renderer-neutral
|
||||
texture/readback descriptors and validation tests. Continue expanding document
|
||||
behavior toward legacy Canvas parity and then port OpenGL classes behind the
|
||||
renderer boundary.
|
||||
texture/readback descriptors and validation tests. `pp_ui_core` has started
|
||||
with XML-layout-facing length parsing and invalid input tests. Continue
|
||||
expanding document behavior toward legacy Canvas parity and then port OpenGL
|
||||
classes behind the renderer boundary.
|
||||
|
||||
Implementation tasks:
|
||||
|
||||
@@ -513,7 +514,7 @@ Last verified on 2026-05-31:
|
||||
|
||||
```powershell
|
||||
cmake --preset windows-msvc-default
|
||||
cmake --build --preset windows-msvc-default --config Debug --target pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests pp_assets_image_format_tests pp_paint_blend_tests pp_document_tests pp_renderer_api_tests pano_cli PanoPainter
|
||||
cmake --build --preset windows-msvc-default --config Debug --target pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests pp_assets_image_format_tests pp_paint_blend_tests pp_document_tests pp_renderer_api_tests pp_ui_core_layout_value_tests pano_cli PanoPainter
|
||||
ctest --preset desktop-fast --build-config Debug
|
||||
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
|
||||
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
|
||||
@@ -530,6 +531,7 @@ Results:
|
||||
- `pp_paint_blend_tests` passed.
|
||||
- `pp_document_tests` passed.
|
||||
- `pp_renderer_api_tests` passed.
|
||||
- `pp_ui_core_layout_value_tests` passed.
|
||||
- `pano_cli_create_document_smoke` passed.
|
||||
- `pano_cli_inspect_image_rejects_unsupported` passed as an expected failure
|
||||
test.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string[]]$Presets = @("android-arm64"),
|
||||
[string[]]$Targets = @("pp_foundation", "pp_assets", "pp_paint", "pp_document", "pp_renderer_api", "pano_cli", "pp_foundation_binary_stream_tests", "pp_foundation_parse_tests", "pp_foundation_trace_tests", "pp_assets_image_format_tests", "pp_paint_blend_tests", "pp_document_tests", "pp_renderer_api_tests")
|
||||
[string[]]$Targets = @("pp_foundation", "pp_assets", "pp_paint", "pp_document", "pp_renderer_api", "pp_ui_core", "pano_cli", "pp_foundation_binary_stream_tests", "pp_foundation_parse_tests", "pp_foundation_trace_tests", "pp_assets_image_format_tests", "pp_paint_blend_tests", "pp_document_tests", "pp_renderer_api_tests", "pp_ui_core_layout_value_tests")
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
@@ -3,7 +3,7 @@ set -u
|
||||
|
||||
preset="${1:-android-arm64}"
|
||||
shift || true
|
||||
targets="${*:-pp_foundation pp_assets pp_paint pp_document pp_renderer_api pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests pp_assets_image_format_tests pp_paint_blend_tests pp_document_tests pp_renderer_api_tests}"
|
||||
targets="${*:-pp_foundation pp_assets pp_paint pp_document pp_renderer_api pp_ui_core pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests pp_assets_image_format_tests pp_paint_blend_tests pp_document_tests pp_renderer_api_tests pp_ui_core_layout_value_tests}"
|
||||
start="$(date +%s)"
|
||||
|
||||
cmake --preset "$preset"
|
||||
|
||||
57
src/ui_core/layout_value.cpp
Normal file
57
src/ui_core/layout_value.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "ui_core/layout_value.h"
|
||||
|
||||
#include "foundation/parse.h"
|
||||
|
||||
namespace pp::ui {
|
||||
|
||||
pp::foundation::Result<LayoutLength> parse_layout_length(std::string_view text) noexcept
|
||||
{
|
||||
if (text == "auto") {
|
||||
return pp::foundation::Result<LayoutLength>::success(
|
||||
LayoutLength { .kind = LayoutLengthKind::auto_value, .value = 0 });
|
||||
}
|
||||
|
||||
if (text.empty()) {
|
||||
return pp::foundation::Result<LayoutLength>::failure(
|
||||
pp::foundation::Status::invalid_argument("layout length must not be empty"));
|
||||
}
|
||||
|
||||
if (text.back() == '%') {
|
||||
const auto number = pp::foundation::parse_u32(text.substr(0, text.size() - 1U));
|
||||
if (!number) {
|
||||
return pp::foundation::Result<LayoutLength>::failure(number.status());
|
||||
}
|
||||
|
||||
if (number.value() > 100U) {
|
||||
return pp::foundation::Result<LayoutLength>::failure(
|
||||
pp::foundation::Status::out_of_range("layout percent must be between 0 and 100"));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<LayoutLength>::success(
|
||||
LayoutLength { .kind = LayoutLengthKind::percent, .value = number.value() });
|
||||
}
|
||||
|
||||
const auto pixels = pp::foundation::parse_u32(text);
|
||||
if (!pixels) {
|
||||
return pp::foundation::Result<LayoutLength>::failure(pixels.status());
|
||||
}
|
||||
|
||||
return pp::foundation::Result<LayoutLength>::success(
|
||||
LayoutLength { .kind = LayoutLengthKind::pixels, .value = pixels.value() });
|
||||
}
|
||||
|
||||
const char* layout_length_kind_name(LayoutLengthKind kind) noexcept
|
||||
{
|
||||
switch (kind) {
|
||||
case LayoutLengthKind::auto_value:
|
||||
return "auto";
|
||||
case LayoutLengthKind::pixels:
|
||||
return "pixels";
|
||||
case LayoutLengthKind::percent:
|
||||
return "percent";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
}
|
||||
24
src/ui_core/layout_value.h
Normal file
24
src/ui_core/layout_value.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "foundation/result.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
namespace pp::ui {
|
||||
|
||||
enum class LayoutLengthKind : std::uint8_t {
|
||||
auto_value,
|
||||
pixels,
|
||||
percent,
|
||||
};
|
||||
|
||||
struct LayoutLength {
|
||||
LayoutLengthKind kind = LayoutLengthKind::auto_value;
|
||||
std::uint32_t value = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] pp::foundation::Result<LayoutLength> parse_layout_length(std::string_view text) noexcept;
|
||||
[[nodiscard]] const char* layout_length_kind_name(LayoutLengthKind kind) noexcept;
|
||||
|
||||
}
|
||||
@@ -76,6 +76,16 @@ add_test(NAME pp_renderer_api_tests COMMAND pp_renderer_api_tests)
|
||||
set_tests_properties(pp_renderer_api_tests PROPERTIES
|
||||
LABELS "renderer;desktop-fast")
|
||||
|
||||
add_executable(pp_ui_core_layout_value_tests
|
||||
ui_core/layout_value_tests.cpp)
|
||||
target_link_libraries(pp_ui_core_layout_value_tests PRIVATE
|
||||
pp_ui_core
|
||||
pp_test_harness)
|
||||
|
||||
add_test(NAME pp_ui_core_layout_value_tests COMMAND pp_ui_core_layout_value_tests)
|
||||
set_tests_properties(pp_ui_core_layout_value_tests PROPERTIES
|
||||
LABELS "ui;desktop-fast")
|
||||
|
||||
if(TARGET pano_cli)
|
||||
add_test(NAME pano_cli_create_document_smoke
|
||||
COMMAND pano_cli create-document --width 64 --height 32 --layers 2)
|
||||
|
||||
58
tests/ui_core/layout_value_tests.cpp
Normal file
58
tests/ui_core/layout_value_tests.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "ui_core/layout_value.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
using pp::foundation::StatusCode;
|
||||
using pp::ui::LayoutLengthKind;
|
||||
using pp::ui::layout_length_kind_name;
|
||||
using pp::ui::parse_layout_length;
|
||||
|
||||
namespace {
|
||||
|
||||
void parses_auto_pixels_and_percent(pp::tests::Harness& h)
|
||||
{
|
||||
const auto auto_value = parse_layout_length("auto");
|
||||
const auto pixels = parse_layout_length("28");
|
||||
const auto percent = parse_layout_length("100%");
|
||||
|
||||
PP_EXPECT(h, auto_value.ok());
|
||||
PP_EXPECT(h, auto_value.value().kind == LayoutLengthKind::auto_value);
|
||||
PP_EXPECT(h, pixels.ok());
|
||||
PP_EXPECT(h, pixels.value().kind == LayoutLengthKind::pixels);
|
||||
PP_EXPECT(h, pixels.value().value == 28U);
|
||||
PP_EXPECT(h, percent.ok());
|
||||
PP_EXPECT(h, percent.value().kind == LayoutLengthKind::percent);
|
||||
PP_EXPECT(h, percent.value().value == 100U);
|
||||
PP_EXPECT(h, layout_length_kind_name(LayoutLengthKind::percent) == std::string_view("percent"));
|
||||
}
|
||||
|
||||
void rejects_invalid_layout_lengths(pp::tests::Harness& h)
|
||||
{
|
||||
const auto empty = parse_layout_length("");
|
||||
const auto negative = parse_layout_length("-1");
|
||||
const auto trailing = parse_layout_length("28px");
|
||||
const auto too_large_percent = parse_layout_length("101%");
|
||||
const auto bare_percent = parse_layout_length("%");
|
||||
|
||||
PP_EXPECT(h, !empty.ok());
|
||||
PP_EXPECT(h, empty.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !negative.ok());
|
||||
PP_EXPECT(h, negative.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !trailing.ok());
|
||||
PP_EXPECT(h, trailing.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !too_large_percent.ok());
|
||||
PP_EXPECT(h, too_large_percent.status().code == StatusCode::out_of_range);
|
||||
PP_EXPECT(h, !bare_percent.ok());
|
||||
PP_EXPECT(h, bare_percent.status().code == StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("parses_auto_pixels_and_percent", parses_auto_pixels_and_percent);
|
||||
harness.run("rejects_invalid_layout_lengths", rejects_invalid_layout_lengths);
|
||||
return harness.finish();
|
||||
}
|
||||
Reference in New Issue
Block a user