Add brush preset list executor bridge

This commit is contained in:
2026-06-04 15:25:54 +02:00
parent 47c35fb859
commit 0c7bc98d5b
7 changed files with 356 additions and 54 deletions

View File

@@ -135,6 +135,87 @@ public:
std::string call_order;
};
class FakeBrushPresetListServices final : public pp::app::BrushPresetListServices {
public:
pp::foundation::Status add_current_brush_preset(int target_index) override
{
if (fail_add) {
call_order += "add-failed;";
return pp::foundation::Status::invalid_argument("fake preset add failure");
}
adds += 1;
last_target_index = target_index;
call_order += "add;";
return pp::foundation::Status::success();
}
void remove_brush_preset(
int current_index,
int target_index,
bool selects_target,
bool clears_selection) override
{
removes += 1;
last_index = current_index;
last_target_index = target_index;
last_selects_target = selects_target;
last_remove_clears_selection = clears_selection;
call_order += "remove;";
}
void move_brush_preset(int from_index, int to_index) override
{
moves += 1;
last_index = from_index;
last_target_index = to_index;
call_order += "move;";
}
void select_brush_preset(int index, bool notify_brush_changed) override
{
selections += 1;
last_target_index = index;
last_notifies_brush_changed = notify_brush_changed;
call_order += "select;";
}
void clear_brush_presets(bool clears_selection) override
{
clears += 1;
last_clear_clears_selection = clears_selection;
call_order += "clear;";
}
void update_preset_empty_notification() override
{
notification_updates += 1;
call_order += "notification;";
}
void save_preset_list() override
{
saves += 1;
call_order += "save;";
}
int adds = 0;
int removes = 0;
int moves = 0;
int selections = 0;
int clears = 0;
int notification_updates = 0;
int saves = 0;
int last_index = -1;
int last_target_index = -1;
bool last_selects_target = false;
bool last_remove_clears_selection = false;
bool last_clear_clears_selection = false;
bool last_notifies_brush_changed = false;
bool fail_add = false;
std::string call_order;
};
class FakeBrushStrokeControlServices final : public pp::app::BrushStrokeControlServices {
public:
void set_float_setting(pp::app::BrushStrokeFloatSetting setting, float value) override
@@ -592,6 +673,68 @@ void texture_list_executor_dispatches_and_preserves_failure(pp::tests::Harness&
PP_EXPECT(harness, failing_services.call_order == "add-failed;");
}
void preset_list_executor_dispatches_and_preserves_failure(pp::tests::Harness& harness)
{
FakeBrushPresetListServices services;
const auto add = pp::app::plan_brush_preset_list_add(2, true);
PP_EXPECT(harness, add);
if (add) {
PP_EXPECT(harness, pp::app::execute_brush_preset_list_plan(add.value(), services).ok());
}
const auto select = pp::app::plan_brush_preset_list_select(3, 1);
PP_EXPECT(harness, select);
if (select) {
PP_EXPECT(harness, pp::app::execute_brush_preset_list_plan(select.value(), services).ok());
}
const auto move = pp::app::plan_brush_preset_list_move(3, 2, -1);
PP_EXPECT(harness, move);
if (move) {
PP_EXPECT(harness, pp::app::execute_brush_preset_list_plan(move.value(), services).ok());
}
const auto remove = pp::app::plan_brush_preset_list_remove(3, 1);
PP_EXPECT(harness, remove);
if (remove) {
PP_EXPECT(harness, pp::app::execute_brush_preset_list_plan(remove.value(), services).ok());
}
const auto clear = pp::app::plan_brush_preset_list_clear(0);
PP_EXPECT(harness, clear);
if (clear) {
PP_EXPECT(harness, pp::app::execute_brush_preset_list_plan(clear.value(), services).ok());
}
PP_EXPECT(harness, services.adds == 1);
PP_EXPECT(harness, services.selections == 1);
PP_EXPECT(harness, services.moves == 1);
PP_EXPECT(harness, services.removes == 1);
PP_EXPECT(harness, services.clears == 1);
PP_EXPECT(harness, services.notification_updates == 3);
PP_EXPECT(harness, services.saves == 4);
PP_EXPECT(harness, services.last_index == 1);
PP_EXPECT(harness, services.last_target_index == 1);
PP_EXPECT(harness, services.last_selects_target);
PP_EXPECT(harness, !services.last_remove_clears_selection);
PP_EXPECT(harness, services.last_clear_clears_selection);
PP_EXPECT(harness, services.last_notifies_brush_changed);
PP_EXPECT(
harness,
services.call_order == "add;notification;save;select;move;save;remove;notification;save;clear;"
"notification;save;");
FakeBrushPresetListServices failing_services;
failing_services.fail_add = true;
PP_EXPECT(harness, add);
if (add) {
PP_EXPECT(harness, !pp::app::execute_brush_preset_list_plan(add.value(), failing_services).ok());
}
PP_EXPECT(harness, failing_services.saves == 0);
PP_EXPECT(harness, failing_services.call_order == "add-failed;");
}
void stroke_control_executor_dispatches_and_rejects_bad_payloads(pp::tests::Harness& harness)
{
FakeBrushStrokeControlServices services;
@@ -681,6 +824,22 @@ void executor_rejects_invalid_plan_payloads(pp::tests::Harness& harness)
move.target_index = 1;
PP_EXPECT(harness, !pp::app::execute_brush_texture_list_plan(move, list_services).ok());
PP_EXPECT(harness, list_services.call_order.empty());
FakeBrushPresetListServices preset_services;
pp::app::BrushPresetListPlan remove_preset;
remove_preset.operation = pp::app::BrushPresetListOperation::remove_preset;
remove_preset.item_count = 1;
remove_preset.current_index = 0;
remove_preset.target_index = 1;
remove_preset.selects_target = true;
PP_EXPECT(harness, !pp::app::execute_brush_preset_list_plan(remove_preset, preset_services).ok());
pp::app::BrushPresetListPlan select_preset;
select_preset.operation = pp::app::BrushPresetListOperation::select_preset;
select_preset.item_count = 1;
select_preset.target_index = 1;
PP_EXPECT(harness, !pp::app::execute_brush_preset_list_plan(select_preset, preset_services).ok());
PP_EXPECT(harness, preset_services.call_order.empty());
}
} // namespace
@@ -701,6 +860,7 @@ int main()
harness.run("executor dispatches texture and preset", executor_dispatches_texture_and_preset);
harness.run("executor dispatches stroke refresh only", executor_dispatches_stroke_refresh_only);
harness.run("texture list executor dispatches and preserves failure", texture_list_executor_dispatches_and_preserves_failure);
harness.run("preset list executor dispatches and preserves failure", preset_list_executor_dispatches_and_preserves_failure);
harness.run("stroke control executor dispatches and rejects bad payloads", stroke_control_executor_dispatches_and_rejects_bad_payloads);
harness.run("executor rejects invalid plan payloads", executor_rejects_invalid_plan_payloads);
return harness.finish();