#include "document/document.h" #include "test_harness.h" #include using pp::document::CanvasDocument; using pp::document::DocumentConfig; using pp::document::max_canvas_dimension; using pp::document::max_frame_count; using pp::document::max_layer_count; using pp::foundation::StatusCode; namespace { void creates_document_with_default_layers(pp::tests::Harness& h) { const auto document = CanvasDocument::create( DocumentConfig { .width = 128, .height = 64, .layer_count = 2 }); PP_EXPECT(h, document.ok()); PP_EXPECT(h, document.value().width() == 128U); PP_EXPECT(h, document.value().height() == 64U); PP_EXPECT(h, document.value().layers().size() == 2U); PP_EXPECT(h, document.value().layers()[0].name == std::string_view("Layer 1")); PP_EXPECT(h, document.value().layers()[1].name == std::string_view("Layer 2")); PP_EXPECT(h, document.value().active_layer_index() == 0U); PP_EXPECT(h, document.value().frames().size() == 1U); PP_EXPECT(h, document.value().frames()[0].duration_ms == 100U); PP_EXPECT(h, document.value().active_frame_index() == 0U); } void rejects_invalid_document_configs(pp::tests::Harness& h) { const auto zero_width = CanvasDocument::create( DocumentConfig { .width = 0, .height = 64, .layer_count = 1 }); const auto huge_width = CanvasDocument::create( DocumentConfig { .width = max_canvas_dimension + 1U, .height = 64, .layer_count = 1 }); const auto no_layers = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = 0 }); const auto too_many_layers = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = max_layer_count + 1U }); PP_EXPECT(h, !zero_width.ok()); PP_EXPECT(h, zero_width.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !huge_width.ok()); PP_EXPECT(h, huge_width.status().code == StatusCode::out_of_range); PP_EXPECT(h, !no_layers.ok()); PP_EXPECT(h, no_layers.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !too_many_layers.ok()); PP_EXPECT(h, too_many_layers.status().code == StatusCode::out_of_range); } void manages_layer_add_remove_and_active_index(pp::tests::Harness& h) { auto document_result = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = 1 }); PP_EXPECT(h, document_result.ok()); auto document = document_result.value(); const auto added = document.add_layer("Paint"); PP_EXPECT(h, added.ok()); PP_EXPECT(h, added.value() == 1U); PP_EXPECT(h, document.active_layer_index() == 1U); PP_EXPECT(h, document.layers()[1].name == std::string_view("Paint")); PP_EXPECT(h, document.remove_layer(0).ok()); PP_EXPECT(h, document.layers().size() == 1U); PP_EXPECT(h, document.active_layer_index() == 0U); const auto remove_last = document.remove_layer(0); PP_EXPECT(h, !remove_last.ok()); PP_EXPECT(h, remove_last.code == StatusCode::invalid_argument); } void moves_layers_and_preserves_active_layer_identity(pp::tests::Harness& h) { auto document_result = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = 3 }); PP_EXPECT(h, document_result.ok()); auto document = document_result.value(); PP_EXPECT(h, document.set_active_layer(2).ok()); PP_EXPECT(h, document.move_layer(2, 0).ok()); PP_EXPECT(h, document.active_layer_index() == 0U); PP_EXPECT(h, document.layers()[0].name == std::string_view("Layer 3")); PP_EXPECT(h, document.layers()[1].name == std::string_view("Layer 1")); PP_EXPECT(h, document.layers()[2].name == std::string_view("Layer 2")); const auto bad_move = document.move_layer(4, 0); PP_EXPECT(h, !bad_move.ok()); PP_EXPECT(h, bad_move.code == StatusCode::out_of_range); } void manages_animation_frames_and_duration(pp::tests::Harness& h) { auto document_result = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = 1 }); PP_EXPECT(h, document_result.ok()); auto document = document_result.value(); const auto added = document.add_frame(250); PP_EXPECT(h, added.ok()); PP_EXPECT(h, added.value() == 1U); PP_EXPECT(h, document.active_frame_index() == 1U); PP_EXPECT(h, document.frames()[1].duration_ms == 250U); const auto duplicated = document.duplicate_frame(1); PP_EXPECT(h, duplicated.ok()); PP_EXPECT(h, duplicated.value() == 2U); PP_EXPECT(h, document.frames()[2].duration_ms == 250U); PP_EXPECT(h, document.set_frame_duration(2, 333).ok()); PP_EXPECT(h, document.frames()[2].duration_ms == 333U); PP_EXPECT(h, document.remove_frame(1).ok()); PP_EXPECT(h, document.frames().size() == 2U); PP_EXPECT(h, document.active_frame_index() == 1U); } void rejects_invalid_animation_frame_operations(pp::tests::Harness& h) { auto document_result = CanvasDocument::create( DocumentConfig { .width = 64, .height = 64, .layer_count = 1 }); PP_EXPECT(h, document_result.ok()); auto document = document_result.value(); const auto zero_duration = document.add_frame(0); const auto duplicate_missing = document.duplicate_frame(9); const auto remove_missing = document.remove_frame(9); const auto remove_only = document.remove_frame(0); const auto set_bad_duration = document.set_frame_duration(0, 0); const auto set_missing_active = document.set_active_frame(2); PP_EXPECT(h, !zero_duration.ok()); PP_EXPECT(h, zero_duration.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !duplicate_missing.ok()); PP_EXPECT(h, duplicate_missing.status().code == StatusCode::out_of_range); PP_EXPECT(h, !remove_missing.ok()); PP_EXPECT(h, remove_missing.code == StatusCode::out_of_range); PP_EXPECT(h, !remove_only.ok()); PP_EXPECT(h, remove_only.code == StatusCode::invalid_argument); PP_EXPECT(h, !set_bad_duration.ok()); PP_EXPECT(h, set_bad_duration.code == StatusCode::invalid_argument); PP_EXPECT(h, !set_missing_active.ok()); PP_EXPECT(h, set_missing_active.code == StatusCode::out_of_range); PP_EXPECT(h, max_frame_count > document.frames().size()); } } int main() { pp::tests::Harness harness; harness.run("creates_document_with_default_layers", creates_document_with_default_layers); harness.run("rejects_invalid_document_configs", rejects_invalid_document_configs); harness.run("manages_layer_add_remove_and_active_index", manages_layer_add_remove_and_active_index); harness.run("moves_layers_and_preserves_active_layer_identity", moves_layers_and_preserves_active_layer_identity); harness.run("manages_animation_frames_and_duration", manages_animation_frames_and_duration); harness.run("rejects_invalid_animation_frame_operations", rejects_invalid_animation_frame_operations); return harness.finish(); }