#include "platform_api/platform_services.h" #include "test_harness.h" #include #include #include #include namespace { class FakePlatformServices final : public pp::platform::PlatformServices { public: explicit FakePlatformServices(std::string clipboard_value) : clipboard_value_(std::move(clipboard_value)) { } [[nodiscard]] std::string clipboard_text() override { ++clipboard_reads; return clipboard_value_; } [[nodiscard]] bool set_clipboard_text(std::string_view text) override { ++clipboard_writes; clipboard_value_.assign(text); return true; } void set_cursor_visible(bool visible) override { ++cursor_updates; cursor_visible = visible; } void set_virtual_keyboard_visible(bool visible) override { ++keyboard_updates; keyboard_visible = visible; } void attach_ui_thread() override { ++ui_thread_attaches; } void detach_ui_thread() override { ++ui_thread_detaches; } void acquire_render_context() override { ++render_context_acquires; } void release_render_context() override { ++render_context_releases; } void present_render_context() override { ++render_context_presents; } void update_platform_frame(float delta_time_seconds) override { ++platform_frame_updates; last_platform_delta = delta_time_seconds; } void report_rendered_frames(int frames) override { ++frame_reports; last_frame_report = frames; } void display_file(std::string_view path) override { ++display_file_requests; displayed_path.assign(path); } void share_file(std::string_view path) override { ++share_file_requests; shared_path.assign(path); } void request_app_close() override { ++app_close_requests; } void pick_image(pp::platform::PickedPathCallback callback) override { ++pick_image_requests; callback(picker_path); } void pick_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { ++pick_file_requests; picked_file_types = std::move(file_types); callback(picker_path); } void pick_save_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { ++pick_save_file_requests; save_file_types = std::move(file_types); callback(save_path); } void pick_directory(pp::platform::PickedPathCallback callback) override { ++pick_directory_requests; callback(directory_path); } void save_prepared_file( std::string_view path, std::string_view suggested_name, pp::platform::PreparedFileCallback callback) override { ++save_prepared_file_requests; prepared_file_path.assign(path); prepared_file_name.assign(suggested_name); callback(prepared_file_path, prepared_file_saved); } int clipboard_reads = 0; int clipboard_writes = 0; int cursor_updates = 0; int keyboard_updates = 0; int ui_thread_attaches = 0; int ui_thread_detaches = 0; int render_context_acquires = 0; int render_context_releases = 0; int render_context_presents = 0; int platform_frame_updates = 0; int frame_reports = 0; int display_file_requests = 0; int share_file_requests = 0; int app_close_requests = 0; int pick_image_requests = 0; int pick_file_requests = 0; int pick_save_file_requests = 0; int pick_directory_requests = 0; int save_prepared_file_requests = 0; bool cursor_visible = false; bool keyboard_visible = false; bool prepared_file_saved = true; float last_platform_delta = 0.0f; int last_frame_report = 0; std::string displayed_path; std::string shared_path; std::string prepared_file_path; std::string prepared_file_name; std::string picker_path = "D:/Paint/import.png"; std::string save_path = "D:/Paint/export.ppi"; std::string directory_path = "D:/Paint"; std::vector picked_file_types; std::vector save_file_types; private: std::string clipboard_value_; }; void platform_services_dispatch_clipboard_reads_and_writes(pp::tests::Harness& harness) { FakePlatformServices fake("#112233"); pp::platform::PlatformServices& services = fake; PP_EXPECT(harness, services.clipboard_text() == "#112233"); PP_EXPECT(harness, services.set_clipboard_text("#ff00aa")); PP_EXPECT(harness, services.clipboard_text() == "#ff00aa"); PP_EXPECT(harness, fake.clipboard_reads == 2); PP_EXPECT(harness, fake.clipboard_writes == 1); } void platform_services_preserve_empty_clipboard_writes(pp::tests::Harness& harness) { FakePlatformServices fake("initial"); pp::platform::PlatformServices& services = fake; PP_EXPECT(harness, services.set_clipboard_text("")); PP_EXPECT(harness, services.clipboard_text().empty()); PP_EXPECT(harness, fake.clipboard_writes == 1); } void platform_services_dispatch_visibility_updates(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; services.set_cursor_visible(true); services.set_virtual_keyboard_visible(true); services.set_cursor_visible(false); services.set_virtual_keyboard_visible(false); PP_EXPECT(harness, fake.cursor_updates == 2); PP_EXPECT(harness, fake.keyboard_updates == 2); PP_EXPECT(harness, !fake.cursor_visible); PP_EXPECT(harness, !fake.keyboard_visible); } void platform_services_dispatch_ui_thread_lifecycle(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; services.attach_ui_thread(); services.detach_ui_thread(); PP_EXPECT(harness, fake.ui_thread_attaches == 1); PP_EXPECT(harness, fake.ui_thread_detaches == 1); } void platform_services_dispatch_render_context_lifecycle(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; services.acquire_render_context(); services.present_render_context(); services.release_render_context(); PP_EXPECT(harness, fake.render_context_acquires == 1); PP_EXPECT(harness, fake.render_context_presents == 1); PP_EXPECT(harness, fake.render_context_releases == 1); } void platform_services_dispatch_frame_hooks(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; services.update_platform_frame(0.125f); services.report_rendered_frames(42); PP_EXPECT(harness, fake.platform_frame_updates == 1); PP_EXPECT(harness, fake.last_platform_delta == 0.125f); PP_EXPECT(harness, fake.frame_reports == 1); PP_EXPECT(harness, fake.last_frame_report == 42); } void platform_services_dispatch_file_actions(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; services.display_file("D:/Paint/export.png"); services.share_file("D:/Paint/demo.ppi"); services.request_app_close(); PP_EXPECT(harness, fake.display_file_requests == 1); PP_EXPECT(harness, fake.share_file_requests == 1); PP_EXPECT(harness, fake.app_close_requests == 1); PP_EXPECT(harness, fake.displayed_path == "D:/Paint/export.png"); PP_EXPECT(harness, fake.shared_path == "D:/Paint/demo.ppi"); } void platform_services_dispatch_picker_callbacks(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; std::string image_path; std::string file_path; std::string save_path; std::string directory_path; services.pick_image([&](std::string path) { image_path = std::move(path); }); services.pick_file({ "ppi", "ppbr" }, [&](std::string path) { file_path = std::move(path); }); services.pick_save_file({ "ppi" }, [&](std::string path) { save_path = std::move(path); }); services.pick_directory([&](std::string path) { directory_path = std::move(path); }); PP_EXPECT(harness, fake.pick_image_requests == 1); PP_EXPECT(harness, fake.pick_file_requests == 1); PP_EXPECT(harness, fake.pick_save_file_requests == 1); PP_EXPECT(harness, fake.pick_directory_requests == 1); PP_EXPECT(harness, image_path == "D:/Paint/import.png"); PP_EXPECT(harness, file_path == "D:/Paint/import.png"); PP_EXPECT(harness, save_path == "D:/Paint/export.ppi"); PP_EXPECT(harness, directory_path == "D:/Paint"); PP_EXPECT(harness, fake.picked_file_types.size() == 2); PP_EXPECT(harness, fake.save_file_types.size() == 1); } void platform_services_dispatch_prepared_file_save(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); pp::platform::PlatformServices& services = fake; std::string saved_path; bool saved = false; services.save_prepared_file( "D:/Paint/export.mp4", "export.mp4", [&](std::string path, bool success) { saved_path = std::move(path); saved = success; }); PP_EXPECT(harness, fake.save_prepared_file_requests == 1); PP_EXPECT(harness, fake.prepared_file_path == "D:/Paint/export.mp4"); PP_EXPECT(harness, fake.prepared_file_name == "export.mp4"); PP_EXPECT(harness, saved_path == "D:/Paint/export.mp4"); PP_EXPECT(harness, saved); } } int main() { pp::tests::Harness harness; harness.run("platform services dispatch clipboard reads and writes", platform_services_dispatch_clipboard_reads_and_writes); harness.run("platform services preserve empty clipboard writes", platform_services_preserve_empty_clipboard_writes); harness.run("platform services dispatch visibility updates", platform_services_dispatch_visibility_updates); harness.run("platform services dispatch UI thread lifecycle", platform_services_dispatch_ui_thread_lifecycle); harness.run("platform services dispatch render context lifecycle", platform_services_dispatch_render_context_lifecycle); harness.run("platform services dispatch frame hooks", platform_services_dispatch_frame_hooks); harness.run("platform services dispatch file actions", platform_services_dispatch_file_actions); harness.run("platform services dispatch picker callbacks", platform_services_dispatch_picker_callbacks); harness.run("platform services dispatch prepared file save", platform_services_dispatch_prepared_file_save); return harness.finish(); }