Route canvas view execution through app core

This commit is contained in:
2026-06-05 05:47:42 +02:00
parent 9373e07d3e
commit e42afcc83f
15 changed files with 456 additions and 33 deletions

View File

@@ -1,10 +1,46 @@
#include "app_core/canvas_view.h"
#include "test_harness.h"
#include <cmath>
#include <cstddef>
#include <string>
namespace {
class FakeCanvasViewServices final : public pp::app::CanvasViewServices {
public:
void reset_camera(const pp::app::CanvasCameraState& state) override
{
camera_state = state;
reset_calls += 1;
call_order += "reset;";
}
void set_density(const pp::app::CanvasViewDensityPlan& plan) override
{
density = plan.density;
recreates_buffers = plan.recreates_buffers;
density_calls += 1;
call_order += "density;";
}
void set_cursor_mode(const pp::app::CanvasViewCursorModePlan& plan) override
{
cursor_mode = plan.mode;
cursor_calls += 1;
call_order += "cursor;";
}
pp::app::CanvasCameraState camera_state;
float density = 0.0F;
bool recreates_buffers = false;
pp::app::CanvasViewCursorMode cursor_mode = pp::app::CanvasViewCursorMode::never;
int reset_calls = 0;
int density_calls = 0;
int cursor_calls = 0;
std::string call_order;
};
void camera_reset_projects_legacy_defaults(pp::tests::Harness& harness)
{
const auto state = pp::app::plan_canvas_camera_reset();
@@ -22,11 +58,84 @@ void camera_reset_projects_legacy_defaults(pp::tests::Harness& harness)
PP_EXPECT(harness, state.pan[1] == 0.0F);
}
void density_rejects_non_positive_or_non_finite_values(pp::tests::Harness& harness)
{
PP_EXPECT(harness, !pp::app::plan_canvas_view_density(0.0F));
PP_EXPECT(harness, !pp::app::plan_canvas_view_density(-1.0F));
PP_EXPECT(harness, !pp::app::plan_canvas_view_density(std::nanf("")));
}
void density_projects_buffer_recreation(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_canvas_view_density(1.5F);
PP_EXPECT(harness, plan);
if (plan) {
PP_EXPECT(harness, plan.value().density == 1.5F);
PP_EXPECT(harness, plan.value().recreates_buffers);
}
}
void cursor_mode_rejects_out_of_range_values(pp::tests::Harness& harness)
{
PP_EXPECT(harness, !pp::app::plan_canvas_view_cursor_mode(-1));
PP_EXPECT(harness, !pp::app::plan_canvas_view_cursor_mode(4));
}
void cursor_mode_projects_legacy_integer_modes(pp::tests::Harness& harness)
{
PP_EXPECT(
harness,
pp::app::plan_canvas_view_cursor_mode(0).value().mode == pp::app::CanvasViewCursorMode::never);
PP_EXPECT(
harness,
pp::app::plan_canvas_view_cursor_mode(1).value().mode == pp::app::CanvasViewCursorMode::small_brush);
PP_EXPECT(
harness,
pp::app::plan_canvas_view_cursor_mode(2).value().mode == pp::app::CanvasViewCursorMode::not_painting);
PP_EXPECT(
harness,
pp::app::plan_canvas_view_cursor_mode(3).value().mode == pp::app::CanvasViewCursorMode::always);
}
void executor_dispatches_canvas_view_services(pp::tests::Harness& harness)
{
FakeCanvasViewServices services;
PP_EXPECT(harness, pp::app::execute_canvas_camera_reset(services).ok());
PP_EXPECT(harness, pp::app::execute_canvas_view_density(2.0F, services).ok());
PP_EXPECT(harness, pp::app::execute_canvas_view_cursor_mode(3, services).ok());
PP_EXPECT(harness, services.reset_calls == 1);
PP_EXPECT(harness, services.density_calls == 1);
PP_EXPECT(harness, services.cursor_calls == 1);
PP_EXPECT(harness, services.camera_state.field_of_view_degrees == 85.0F);
PP_EXPECT(harness, services.density == 2.0F);
PP_EXPECT(harness, services.recreates_buffers);
PP_EXPECT(harness, services.cursor_mode == pp::app::CanvasViewCursorMode::always);
PP_EXPECT(harness, services.call_order == "reset;density;cursor;");
}
void executor_rejects_invalid_canvas_view_requests(pp::tests::Harness& harness)
{
FakeCanvasViewServices services;
PP_EXPECT(harness, !pp::app::execute_canvas_view_density(0.0F, services).ok());
PP_EXPECT(harness, !pp::app::execute_canvas_view_cursor_mode(99, services).ok());
PP_EXPECT(harness, services.density_calls == 0);
PP_EXPECT(harness, services.cursor_calls == 0);
}
} // namespace
int main()
{
pp::tests::Harness harness;
harness.run("camera reset projects legacy defaults", camera_reset_projects_legacy_defaults);
harness.run("density rejects non-positive or non-finite values", density_rejects_non_positive_or_non_finite_values);
harness.run("density projects buffer recreation", density_projects_buffer_recreation);
harness.run("cursor mode rejects out of range values", cursor_mode_rejects_out_of_range_values);
harness.run("cursor mode projects legacy integer modes", cursor_mode_projects_legacy_integer_modes);
harness.run("executor dispatches canvas view services", executor_dispatches_canvas_view_services);
harness.run("executor rejects invalid canvas view requests", executor_rejects_invalid_canvas_view_requests);
return harness.finish();
}