From 2454e00a688d14bbd3da2b94d5a4685367a4672b Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 12 Apr 2025 20:36:14 +0200 Subject: [PATCH] libservo: Add a very simple `libservo` API test (#36440) libservo: Add a very simple `libservo` API test This is the first step toward adding full testing for the `WebView` API. The test added here simply starts up a Servo instance and verifies that it does not crash when shutting down. Testing: This change is a test, so there are tests for these changes. Signed-off-by: Martin Robinson Signed-off-by: Martin Robinson --- components/servo/tests/common/mod.rs | 86 ++++++++++++++++++++++++++++ components/servo/tests/servo.rs | 13 +++++ 2 files changed, 99 insertions(+) create mode 100644 components/servo/tests/common/mod.rs create mode 100644 components/servo/tests/servo.rs diff --git a/components/servo/tests/common/mod.rs b/components/servo/tests/common/mod.rs new file mode 100644 index 00000000000..2807a3134ec --- /dev/null +++ b/components/servo/tests/common/mod.rs @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use std::rc::Rc; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::time::Duration; + +use compositing::windowing::{EmbedderMethods, WindowMethods}; +use compositing_traits::rendering_context::{RenderingContext, SoftwareRenderingContext}; +use dpi::PhysicalSize; +use embedder_traits::EventLoopWaker; +use euclid::Scale; +use servo::Servo; +use servo_geometry::DeviceIndependentPixel; +use webrender_api::units::DevicePixel; + +pub struct ServoTest { + servo: Servo, +} + +impl ServoTest { + pub fn new() -> Self { + let rendering_context = Rc::new( + SoftwareRenderingContext::new(PhysicalSize { + width: 500, + height: 500, + }) + .expect("Could not create SoftwareRenderingContext"), + ); + assert!(rendering_context.make_current().is_ok()); + + #[derive(Clone)] + struct EmbedderMethodsImpl(Arc); + impl EmbedderMethods for EmbedderMethodsImpl { + fn create_event_loop_waker(&mut self) -> Box { + Box::new(EventLoopWakerImpl(self.0.clone())) + } + } + + struct WindowMethodsImpl; + impl WindowMethods for WindowMethodsImpl { + fn hidpi_factor(&self) -> Scale { + Scale::new(1.0) + } + } + + #[derive(Clone)] + struct EventLoopWakerImpl(Arc); + impl EventLoopWaker for EventLoopWakerImpl { + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } + + fn wake(&self) { + self.0.store(true, Ordering::Relaxed); + } + } + + let user_event_triggered = Arc::new(AtomicBool::new(false)); + let servo = Servo::new( + Default::default(), + Default::default(), + rendering_context.clone(), + Box::new(EmbedderMethodsImpl(user_event_triggered)), + Rc::new(WindowMethodsImpl), + Default::default(), + ); + Self { servo } + } + + pub fn servo(&self) -> &Servo { + &self.servo + } +} + +impl Drop for ServoTest { + fn drop(&mut self) { + self.servo.start_shutting_down(); + while self.servo.spin_event_loop() { + std::thread::sleep(Duration::from_millis(1)); + } + self.servo.deinit(); + } +} diff --git a/components/servo/tests/servo.rs b/components/servo/tests/servo.rs new file mode 100644 index 00000000000..5c77a57194f --- /dev/null +++ b/components/servo/tests/servo.rs @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +mod common; + +use common::*; + +#[test] +fn test_simple_servo_start_and_stop() { + let shared_test = ServoTest::new(); + assert!(!shared_test.servo().animating()); +}