servo/components/devtools/id.rs
Ashwin Naren be6105a202
wrap tests with #[cfg(test)]
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
2025-05-23 21:37:12 -07:00

178 lines
6.3 KiB
Rust

/* 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::collections::HashMap;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
#[derive(Debug, Default)]
pub(crate) struct IdMap {
pub(crate) browser_ids: HashMap<WebViewId, u32>,
pub(crate) browsing_context_ids: HashMap<BrowsingContextId, u32>,
pub(crate) outer_window_ids: HashMap<PipelineId, u32>,
}
impl IdMap {
pub(crate) fn browser_id(&mut self, webview_id: WebViewId) -> DevtoolsBrowserId {
let len = self
.browser_ids
.len()
.checked_add(1)
.expect("WebViewId count overflow")
.try_into()
.expect("DevtoolsBrowserId overflow");
DevtoolsBrowserId(*self.browser_ids.entry(webview_id).or_insert(len))
}
pub(crate) fn browsing_context_id(
&mut self,
browsing_context_id: BrowsingContextId,
) -> DevtoolsBrowsingContextId {
let len = self
.browsing_context_ids
.len()
.checked_add(1)
.expect("BrowsingContextId count overflow")
.try_into()
.expect("DevtoolsBrowsingContextId overflow");
DevtoolsBrowsingContextId(
*self
.browsing_context_ids
.entry(browsing_context_id)
.or_insert(len),
)
}
pub(crate) fn outer_window_id(&mut self, pipeline_id: PipelineId) -> DevtoolsOuterWindowId {
let len = self
.outer_window_ids
.len()
.checked_add(1)
.expect("PipelineId count overflow")
.try_into()
.expect("DevtoolsOuterWindowId overflow");
DevtoolsOuterWindowId(*self.outer_window_ids.entry(pipeline_id).or_insert(len))
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct DevtoolsBrowserId(u32);
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct DevtoolsBrowsingContextId(u32);
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct DevtoolsOuterWindowId(u32);
impl DevtoolsBrowserId {
pub(crate) fn value(&self) -> u32 {
self.0
}
}
impl DevtoolsBrowsingContextId {
pub(crate) fn value(&self) -> u32 {
self.0
}
}
impl DevtoolsOuterWindowId {
pub(crate) fn value(&self) -> u32 {
self.0
}
}
#[cfg(test)]
mod tests {
#[test]
pub(crate) fn test_id_map() {
use std::thread;
use base::id::{PipelineNamespace, PipelineNamespaceId};
use crossbeam_channel::unbounded;
macro_rules! test_sequential_id_assignment {
($id_type:ident, $new_id_function:expr, $map_id_function:expr) => {
let (sender, receiver) = unbounded();
let sender1 = sender.clone();
let sender2 = sender.clone();
let sender3 = sender.clone();
let threads = [
thread::spawn(move || {
PipelineNamespace::install(PipelineNamespaceId(1));
sender1.send($new_id_function()).expect("Send failed");
sender1.send($new_id_function()).expect("Send failed");
sender1.send($new_id_function()).expect("Send failed");
}),
thread::spawn(move || {
PipelineNamespace::install(PipelineNamespaceId(2));
sender2.send($new_id_function()).expect("Send failed");
sender2.send($new_id_function()).expect("Send failed");
sender2.send($new_id_function()).expect("Send failed");
}),
thread::spawn(move || {
PipelineNamespace::install(PipelineNamespaceId(3));
sender3.send($new_id_function()).expect("Send failed");
sender3.send($new_id_function()).expect("Send failed");
sender3.send($new_id_function()).expect("Send failed");
}),
];
for thread in threads {
thread.join().expect("Thread join failed");
}
let mut id_map = IdMap::default();
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(1)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(2)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(3)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(4)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(5)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(6)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(7)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(8)
);
assert_eq!(
$map_id_function(&mut id_map, receiver.recv().expect("Recv failed")),
$id_type(9)
);
};
}
test_sequential_id_assignment!(
DevtoolsBrowserId,
|| WebViewId::new(),
|id_map: &mut IdMap, id| id_map.browser_id(id)
);
test_sequential_id_assignment!(
DevtoolsBrowsingContextId,
|| BrowsingContextId::new(),
|id_map: &mut IdMap, id| id_map.browsing_context_id(id)
);
test_sequential_id_assignment!(
DevtoolsOuterWindowId,
|| PipelineId::new(),
|id_map: &mut IdMap, id| id_map.outer_window_id(id)
);
}
}