#include "app_core/document_animation.h" #include "test_harness.h" #include #define PP_REQUIRE(harness, expression) \ do { \ const bool pp_require_ok = static_cast(expression); \ (harness).expect(pp_require_ok, #expression, __FILE__, __LINE__); \ if (!pp_require_ok) { \ return; \ } \ } while (false) namespace { void add_duplicate_and_remove_validate_frame_bounds(pp::tests::Harness& harness) { const auto add = pp::app::plan_animation_add_frame(2, 0); PP_REQUIRE(harness, add); PP_EXPECT(harness, add.value().operation == pp::app::DocumentAnimationOperation::add_frame); PP_EXPECT(harness, add.value().selected_frame == 2); PP_EXPECT(harness, add.value().mutates_document); PP_EXPECT(harness, add.value().reloads_animation_layers); PP_EXPECT(harness, add.value().updates_canvas_animation); PP_EXPECT(harness, add.value().marks_unsaved); const auto duplicate = pp::app::plan_animation_duplicate_frame(3, 1); PP_REQUIRE(harness, duplicate); PP_EXPECT(harness, duplicate.value().operation == pp::app::DocumentAnimationOperation::duplicate_frame); PP_EXPECT(harness, duplicate.value().target_frame == 2); PP_EXPECT(harness, duplicate.value().requires_selected_frame); const auto remove = pp::app::plan_animation_remove_frame(3, 2); PP_REQUIRE(harness, remove); PP_EXPECT(harness, remove.value().operation == pp::app::DocumentAnimationOperation::remove_frame); PP_EXPECT(harness, remove.value().target_frame == 1); PP_EXPECT(harness, !pp::app::plan_animation_add_frame(0, 0)); PP_EXPECT(harness, !pp::app::plan_animation_add_frame(1, -1)); PP_EXPECT(harness, !pp::app::plan_animation_duplicate_frame(2, 2)); PP_EXPECT(harness, !pp::app::plan_animation_remove_frame(1, 0)); } void duration_plans_clamp_floor_and_reject_overflow(pp::tests::Harness& harness) { const auto up = pp::app::plan_animation_adjust_duration(2, 1, 4, 1); PP_REQUIRE(harness, up); PP_EXPECT(harness, up.value().operation == pp::app::DocumentAnimationOperation::adjust_duration); PP_EXPECT(harness, up.value().frame_duration == 5); PP_EXPECT(harness, up.value().mutates_document); const auto down = pp::app::plan_animation_adjust_duration(2, 1, 1, -1); PP_REQUIRE(harness, down); PP_EXPECT(harness, down.value().frame_duration == 1); PP_EXPECT(harness, !down.value().mutates_document); PP_EXPECT(harness, !down.value().marks_unsaved); PP_EXPECT(harness, !pp::app::plan_animation_adjust_duration(2, 1, 0, 1)); PP_EXPECT(harness, !pp::app::plan_animation_adjust_duration(2, 1, 2, 0)); PP_EXPECT( harness, !pp::app::plan_animation_adjust_duration(2, 1, std::numeric_limits::max(), 1)); } void move_and_timeline_plans_handle_edges(pp::tests::Harness& harness) { const auto left_edge = pp::app::plan_animation_move_frame(3, 0, -1); PP_REQUIRE(harness, left_edge); PP_EXPECT(harness, left_edge.value().operation == pp::app::DocumentAnimationOperation::move_frame); PP_EXPECT(harness, left_edge.value().target_frame == 0); PP_EXPECT(harness, !left_edge.value().mutates_document); PP_EXPECT(harness, left_edge.value().reloads_animation_layers); const auto right = pp::app::plan_animation_move_frame(3, 1, 1); PP_REQUIRE(harness, right); PP_EXPECT(harness, right.value().target_frame == 2); PP_EXPECT(harness, right.value().mutates_document); const auto huge_left = pp::app::plan_animation_move_frame(3, 1, std::numeric_limits::min()); PP_REQUIRE(harness, huge_left); PP_EXPECT(harness, huge_left.value().target_frame == 0); const auto huge_right = pp::app::plan_animation_move_frame(3, 1, std::numeric_limits::max()); PP_REQUIRE(harness, huge_right); PP_EXPECT(harness, huge_right.value().target_frame == 2); const auto go = pp::app::plan_animation_goto_frame(5, 3); PP_REQUIRE(harness, go); PP_EXPECT(harness, go.value().operation == pp::app::DocumentAnimationOperation::goto_frame); PP_EXPECT(harness, go.value().target_frame == 3); PP_EXPECT(harness, !go.value().mutates_document); PP_EXPECT(harness, go.value().updates_canvas_animation); const auto next = pp::app::plan_animation_step_frame(5, 4, 1); PP_REQUIRE(harness, next); PP_EXPECT(harness, next.value().operation == pp::app::DocumentAnimationOperation::goto_next); PP_EXPECT(harness, next.value().target_frame == 0); const auto prev = pp::app::plan_animation_step_frame(5, 0, -1); PP_REQUIRE(harness, prev); PP_EXPECT(harness, prev.value().operation == pp::app::DocumentAnimationOperation::goto_previous); PP_EXPECT(harness, prev.value().target_frame == 4); PP_EXPECT(harness, !pp::app::plan_animation_move_frame(3, 1, 0)); PP_EXPECT(harness, !pp::app::plan_animation_goto_frame(5, 5)); PP_EXPECT(harness, !pp::app::plan_animation_step_frame(0, 0, 1)); } void onion_size_updates_canvas_without_document_mutation(pp::tests::Harness& harness) { const auto plan = pp::app::plan_animation_onion_size(2); PP_REQUIRE(harness, plan); PP_EXPECT(harness, plan.value().operation == pp::app::DocumentAnimationOperation::set_onion_size); PP_EXPECT(harness, plan.value().onion_size == 2); PP_EXPECT(harness, plan.value().updates_canvas_animation); PP_EXPECT(harness, !plan.value().mutates_document); PP_EXPECT(harness, !plan.value().marks_unsaved); PP_EXPECT(harness, !pp::app::plan_animation_onion_size(-1)); } } // namespace int main() { pp::tests::Harness harness; harness.run("add duplicate and remove validate frame bounds", add_duplicate_and_remove_validate_frame_bounds); harness.run("duration plans clamp floor and reject overflow", duration_plans_clamp_floor_and_reject_overflow); harness.run("move and timeline plans handle edges", move_and_timeline_plans_handle_edges); harness.run("onion size updates canvas without document mutation", onion_size_updates_canvas_without_document_mutation); return harness.finish(); }