Add brush stroke control boundary
This commit is contained in:
@@ -1156,6 +1156,42 @@ if(TARGET pano_cli)
|
||||
LABELS "app;paint;integration;desktop-fast;fuzz"
|
||||
WILL_FAIL TRUE)
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_float_smoke
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind float --setting tip-size --value 42.5)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_float_smoke PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-float\".*\"floatSetting\":\"tip-size\".*\"floatValue\":42.5.*\"mutatesBrush\":true.*\"notifiesStrokeChange\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_toggle_smoke
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind bool --setting dual-enabled --enabled)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_toggle_smoke PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-bool\".*\"boolSetting\":\"dual-enabled\".*\"boolValue\":true.*\"refreshesPreview\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_blend_smoke
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind blend --setting pattern --blend-mode 3)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_blend_smoke PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"set-blend-mode\".*\"blendSetting\":\"pattern\".*\"blendMode\":3")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_reset_smoke
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind default-reset)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_reset_smoke PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-brush-stroke-control\".*\"operation\":\"reset-default-brush\".*\"updatesControls\":true.*\"notifiesStrokeChange\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_rejects_bad_setting
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind float --setting imaginary --value 1)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_rejects_bad_setting PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast;fuzz"
|
||||
WILL_FAIL TRUE)
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_stroke_control_rejects_bad_blend
|
||||
COMMAND pano_cli plan-brush-stroke-control --kind blend --setting tip --blend-mode 99)
|
||||
set_tests_properties(pano_cli_plan_brush_stroke_control_rejects_bad_blend PROPERTIES
|
||||
LABELS "app;paint;integration;desktop-fast;fuzz"
|
||||
WILL_FAIL TRUE)
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_tool_draw_smoke
|
||||
COMMAND pano_cli plan-canvas-tool --kind draw)
|
||||
set_tests_properties(pano_cli_plan_canvas_tool_draw_smoke PROPERTIES
|
||||
|
||||
@@ -135,6 +135,80 @@ public:
|
||||
std::string call_order;
|
||||
};
|
||||
|
||||
class FakeBrushStrokeControlServices final : public pp::app::BrushStrokeControlServices {
|
||||
public:
|
||||
void set_float_setting(pp::app::BrushStrokeFloatSetting setting, float value) override
|
||||
{
|
||||
float_sets += 1;
|
||||
last_float_setting = setting;
|
||||
last_float_value = value;
|
||||
call_order += "float;";
|
||||
}
|
||||
|
||||
void set_bool_setting(pp::app::BrushStrokeBoolSetting setting, bool value) override
|
||||
{
|
||||
bool_sets += 1;
|
||||
last_bool_setting = setting;
|
||||
last_bool_value = value;
|
||||
call_order += "bool;";
|
||||
}
|
||||
|
||||
void set_blend_mode(pp::app::BrushStrokeBlendSetting setting, int blend_mode) override
|
||||
{
|
||||
blend_sets += 1;
|
||||
last_blend_setting = setting;
|
||||
last_blend_mode = blend_mode;
|
||||
call_order += "blend;";
|
||||
}
|
||||
|
||||
void reset_tip_aspect(float value) override
|
||||
{
|
||||
tip_aspect_resets += 1;
|
||||
last_float_value = value;
|
||||
call_order += "tip-aspect;";
|
||||
}
|
||||
|
||||
void reset_default_brush() override
|
||||
{
|
||||
default_resets += 1;
|
||||
call_order += "default;";
|
||||
}
|
||||
|
||||
void update_stroke_controls() override
|
||||
{
|
||||
control_updates += 1;
|
||||
call_order += "controls;";
|
||||
}
|
||||
|
||||
void refresh_stroke_preview() override
|
||||
{
|
||||
preview_refreshes += 1;
|
||||
call_order += "preview;";
|
||||
}
|
||||
|
||||
void notify_stroke_changed() override
|
||||
{
|
||||
stroke_notifications += 1;
|
||||
call_order += "notify;";
|
||||
}
|
||||
|
||||
int float_sets = 0;
|
||||
int bool_sets = 0;
|
||||
int blend_sets = 0;
|
||||
int tip_aspect_resets = 0;
|
||||
int default_resets = 0;
|
||||
int control_updates = 0;
|
||||
int preview_refreshes = 0;
|
||||
int stroke_notifications = 0;
|
||||
pp::app::BrushStrokeFloatSetting last_float_setting = pp::app::BrushStrokeFloatSetting::tip_size;
|
||||
pp::app::BrushStrokeBoolSetting last_bool_setting = pp::app::BrushStrokeBoolSetting::tip_angle_init;
|
||||
pp::app::BrushStrokeBlendSetting last_blend_setting = pp::app::BrushStrokeBlendSetting::tip;
|
||||
float last_float_value = 0.0F;
|
||||
bool last_bool_value = false;
|
||||
int last_blend_mode = 0;
|
||||
std::string call_order;
|
||||
};
|
||||
|
||||
void color_plan_validates_all_channels(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_brush_ui_color(0.25F, 0.5F, 0.75F, 1.0F);
|
||||
@@ -202,6 +276,58 @@ void stroke_settings_plan_updates_brush_preview(pp::tests::Harness& harness)
|
||||
PP_EXPECT(harness, !plan.loads_brush_resources);
|
||||
}
|
||||
|
||||
void stroke_control_plans_validate_values_and_reject_breaking_points(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto slider = pp::app::plan_brush_stroke_float_setting(
|
||||
pp::app::BrushStrokeFloatSetting::tip_size,
|
||||
42.5F);
|
||||
PP_EXPECT(harness, slider);
|
||||
if (slider) {
|
||||
PP_EXPECT(harness, slider.value().operation == pp::app::BrushStrokeControlOperation::set_float);
|
||||
PP_EXPECT(harness, slider.value().float_setting == pp::app::BrushStrokeFloatSetting::tip_size);
|
||||
PP_EXPECT(harness, slider.value().float_value == 42.5F);
|
||||
PP_EXPECT(harness, slider.value().mutates_brush);
|
||||
PP_EXPECT(harness, slider.value().refreshes_preview);
|
||||
PP_EXPECT(harness, slider.value().notifies_stroke_change);
|
||||
}
|
||||
|
||||
const auto checkbox = pp::app::plan_brush_stroke_bool_setting(
|
||||
pp::app::BrushStrokeBoolSetting::pattern_enabled,
|
||||
true);
|
||||
PP_EXPECT(harness, checkbox.operation == pp::app::BrushStrokeControlOperation::set_bool);
|
||||
PP_EXPECT(harness, checkbox.bool_setting == pp::app::BrushStrokeBoolSetting::pattern_enabled);
|
||||
PP_EXPECT(harness, checkbox.bool_value);
|
||||
|
||||
const auto blend = pp::app::plan_brush_stroke_blend_mode(
|
||||
pp::app::BrushStrokeBlendSetting::dual,
|
||||
7);
|
||||
PP_EXPECT(harness, blend);
|
||||
if (blend) {
|
||||
PP_EXPECT(harness, blend.value().operation == pp::app::BrushStrokeControlOperation::set_blend_mode);
|
||||
PP_EXPECT(harness, blend.value().blend_setting == pp::app::BrushStrokeBlendSetting::dual);
|
||||
PP_EXPECT(harness, blend.value().blend_mode == 7);
|
||||
}
|
||||
|
||||
const auto tip_aspect = pp::app::plan_brush_tip_aspect_reset();
|
||||
PP_EXPECT(harness, tip_aspect.operation == pp::app::BrushStrokeControlOperation::reset_tip_aspect);
|
||||
PP_EXPECT(harness, tip_aspect.float_setting == pp::app::BrushStrokeFloatSetting::tip_aspect);
|
||||
PP_EXPECT(harness, tip_aspect.float_value == 0.5F);
|
||||
|
||||
const auto defaults = pp::app::plan_brush_default_settings_reset();
|
||||
PP_EXPECT(harness, defaults.operation == pp::app::BrushStrokeControlOperation::reset_default_brush);
|
||||
PP_EXPECT(harness, defaults.updates_controls);
|
||||
PP_EXPECT(harness, defaults.refreshes_preview);
|
||||
PP_EXPECT(harness, defaults.notifies_stroke_change);
|
||||
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
!pp::app::plan_brush_stroke_float_setting(
|
||||
pp::app::BrushStrokeFloatSetting::tip_flow,
|
||||
std::nanf("")));
|
||||
PP_EXPECT(harness, !pp::app::plan_brush_stroke_blend_mode(pp::app::BrushStrokeBlendSetting::tip, -1));
|
||||
PP_EXPECT(harness, !pp::app::plan_brush_stroke_blend_mode(pp::app::BrushStrokeBlendSetting::pattern, 64));
|
||||
}
|
||||
|
||||
void texture_list_add_plans_target_paths_and_rejects_bad_input(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_brush_texture_list_add(
|
||||
@@ -388,6 +514,60 @@ void texture_list_executor_dispatches_and_preserves_failure(pp::tests::Harness&
|
||||
PP_EXPECT(harness, failing_services.call_order == "add-failed;");
|
||||
}
|
||||
|
||||
void stroke_control_executor_dispatches_and_rejects_bad_payloads(pp::tests::Harness& harness)
|
||||
{
|
||||
FakeBrushStrokeControlServices services;
|
||||
|
||||
const auto slider = pp::app::plan_brush_stroke_float_setting(
|
||||
pp::app::BrushStrokeFloatSetting::pattern_depth,
|
||||
0.75F);
|
||||
PP_EXPECT(harness, slider);
|
||||
if (slider) {
|
||||
PP_EXPECT(harness, pp::app::execute_brush_stroke_control_plan(slider.value(), services).ok());
|
||||
}
|
||||
|
||||
const auto checkbox = pp::app::plan_brush_stroke_bool_setting(
|
||||
pp::app::BrushStrokeBoolSetting::dual_enabled,
|
||||
true);
|
||||
PP_EXPECT(harness, pp::app::execute_brush_stroke_control_plan(checkbox, services).ok());
|
||||
|
||||
const auto blend = pp::app::plan_brush_stroke_blend_mode(pp::app::BrushStrokeBlendSetting::pattern, 3);
|
||||
PP_EXPECT(harness, blend);
|
||||
if (blend) {
|
||||
PP_EXPECT(harness, pp::app::execute_brush_stroke_control_plan(blend.value(), services).ok());
|
||||
}
|
||||
|
||||
PP_EXPECT(harness, pp::app::execute_brush_stroke_control_plan(pp::app::plan_brush_tip_aspect_reset(), services).ok());
|
||||
PP_EXPECT(harness, pp::app::execute_brush_stroke_control_plan(pp::app::plan_brush_default_settings_reset(), services).ok());
|
||||
|
||||
PP_EXPECT(harness, services.float_sets == 1);
|
||||
PP_EXPECT(harness, services.last_float_setting == pp::app::BrushStrokeFloatSetting::pattern_depth);
|
||||
PP_EXPECT(harness, services.last_bool_setting == pp::app::BrushStrokeBoolSetting::dual_enabled);
|
||||
PP_EXPECT(harness, services.last_blend_setting == pp::app::BrushStrokeBlendSetting::pattern);
|
||||
PP_EXPECT(harness, services.last_blend_mode == 3);
|
||||
PP_EXPECT(harness, services.tip_aspect_resets == 1);
|
||||
PP_EXPECT(harness, services.default_resets == 1);
|
||||
PP_EXPECT(harness, services.preview_refreshes == 5);
|
||||
PP_EXPECT(harness, services.control_updates == 1);
|
||||
PP_EXPECT(harness, services.stroke_notifications == 5);
|
||||
PP_EXPECT(
|
||||
harness,
|
||||
services.call_order == "float;preview;notify;bool;preview;notify;blend;preview;notify;tip-aspect;"
|
||||
"preview;notify;default;controls;preview;notify;");
|
||||
|
||||
FakeBrushStrokeControlServices bad_services;
|
||||
pp::app::BrushStrokeControlPlan bad_float;
|
||||
bad_float.operation = pp::app::BrushStrokeControlOperation::set_float;
|
||||
bad_float.float_value = std::nanf("");
|
||||
PP_EXPECT(harness, !pp::app::execute_brush_stroke_control_plan(bad_float, bad_services).ok());
|
||||
|
||||
pp::app::BrushStrokeControlPlan bad_blend;
|
||||
bad_blend.operation = pp::app::BrushStrokeControlOperation::set_blend_mode;
|
||||
bad_blend.blend_mode = 99;
|
||||
PP_EXPECT(harness, !pp::app::execute_brush_stroke_control_plan(bad_blend, bad_services).ok());
|
||||
PP_EXPECT(harness, bad_services.call_order.empty());
|
||||
}
|
||||
|
||||
void executor_rejects_invalid_plan_payloads(pp::tests::Harness& harness)
|
||||
{
|
||||
FakeBrushUiServices services;
|
||||
@@ -434,12 +614,14 @@ int main()
|
||||
harness.run("texture plan validates path and slot", texture_plan_validates_path_and_slot);
|
||||
harness.run("preset plan preserves color and requires brush", preset_plan_preserves_color_and_requires_brush);
|
||||
harness.run("stroke settings plan updates brush preview", stroke_settings_plan_updates_brush_preview);
|
||||
harness.run("stroke control plans validate values and reject breaking points", stroke_control_plans_validate_values_and_reject_breaking_points);
|
||||
harness.run("texture list add plans target paths and rejects bad input", texture_list_add_plans_target_paths_and_rejects_bad_input);
|
||||
harness.run("texture list remove and move plans handle edges", texture_list_remove_and_move_plans_handle_edges);
|
||||
harness.run("executor dispatches color and refresh", executor_dispatches_color_and_refresh);
|
||||
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("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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user