mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Improve support for gpui tests that need multiple contexts
If a test function takes multiple contexts, pass it however many distinct contexts are needed. Construct each one with a different starting entity id so that they do not share any entity ids.
This commit is contained in:
parent
7335e70eb7
commit
f46c0a790e
5 changed files with 26 additions and 24 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1635,6 +1635,7 @@ dependencies = [
|
||||||
name = "gpui_macros"
|
name = "gpui_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
|
@ -128,17 +128,6 @@ impl App {
|
||||||
f(&mut *cx)
|
f(&mut *cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_async<T, F, Fn>(f: Fn) -> T
|
|
||||||
where
|
|
||||||
Fn: FnOnce(TestAppContext) -> F,
|
|
||||||
F: Future<Output = T>,
|
|
||||||
{
|
|
||||||
let foreground = Rc::new(executor::Foreground::test());
|
|
||||||
let cx = TestAppContext::new(foreground.clone());
|
|
||||||
let future = f(cx);
|
|
||||||
smol::block_on(foreground.run(future))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(asset_source: impl AssetSource) -> Result<Self> {
|
pub fn new(asset_source: impl AssetSource) -> Result<Self> {
|
||||||
let platform = platform::current::platform();
|
let platform = platform::current::platform();
|
||||||
let foreground_platform = platform::current::foreground_platform();
|
let foreground_platform = platform::current::foreground_platform();
|
||||||
|
@ -248,16 +237,18 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestAppContext {
|
impl TestAppContext {
|
||||||
pub fn new(foreground: Rc<executor::Foreground>) -> Self {
|
pub fn new(foreground: Rc<executor::Foreground>, first_entity_id: usize) -> Self {
|
||||||
let platform = Arc::new(platform::test::platform());
|
let platform = Arc::new(platform::test::platform());
|
||||||
let foreground_platform = Rc::new(platform::test::foreground_platform());
|
let foreground_platform = Rc::new(platform::test::foreground_platform());
|
||||||
|
let mut cx = MutableAppContext::new(
|
||||||
|
foreground.clone(),
|
||||||
|
platform,
|
||||||
|
foreground_platform.clone(),
|
||||||
|
(),
|
||||||
|
);
|
||||||
|
cx.next_entity_id = first_entity_id;
|
||||||
let cx = TestAppContext {
|
let cx = TestAppContext {
|
||||||
cx: Rc::new(RefCell::new(MutableAppContext::new(
|
cx: Rc::new(RefCell::new(cx)),
|
||||||
foreground.clone(),
|
|
||||||
platform,
|
|
||||||
foreground_platform.clone(),
|
|
||||||
(),
|
|
||||||
))),
|
|
||||||
foreground_platform,
|
foreground_platform,
|
||||||
};
|
};
|
||||||
cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
|
cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
|
||||||
|
|
|
@ -31,3 +31,4 @@ pub use presenter::{
|
||||||
SizeConstraint, Vector2FExt,
|
SizeConstraint, Vector2FExt,
|
||||||
};
|
};
|
||||||
pub use scoped_pool;
|
pub use scoped_pool;
|
||||||
|
pub use smol::block_on;
|
||||||
|
|
|
@ -9,3 +9,4 @@ proc-macro = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
syn = "1.0"
|
syn = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
|
proc-macro2 = "1.0"
|
|
@ -38,6 +38,16 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
||||||
let inner_fn_attributes = mem::take(&mut inner_fn.attrs);
|
let inner_fn_attributes = mem::take(&mut inner_fn.attrs);
|
||||||
let inner_fn_name = format_ident!("_{}", inner_fn.sig.ident);
|
let inner_fn_name = format_ident!("_{}", inner_fn.sig.ident);
|
||||||
let outer_fn_name = mem::replace(&mut inner_fn.sig.ident, inner_fn_name.clone());
|
let outer_fn_name = mem::replace(&mut inner_fn.sig.ident, inner_fn_name.clone());
|
||||||
|
|
||||||
|
// Pass to the test function the number of app contexts that it needs,
|
||||||
|
// based on its parameter list.
|
||||||
|
let inner_fn_args = (0..inner_fn.sig.inputs.len())
|
||||||
|
.map(|i| {
|
||||||
|
let first_entity_id = i * 100_000;
|
||||||
|
quote!(#namespace::TestAppContext::new(foreground.clone(), #first_entity_id),)
|
||||||
|
})
|
||||||
|
.collect::<proc_macro2::TokenStream>();
|
||||||
|
|
||||||
let mut outer_fn: ItemFn = if inner_fn.sig.asyncness.is_some() {
|
let mut outer_fn: ItemFn = if inner_fn.sig.asyncness.is_some() {
|
||||||
parse_quote! {
|
parse_quote! {
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -48,9 +58,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
||||||
let mut retries = 0;
|
let mut retries = 0;
|
||||||
loop {
|
loop {
|
||||||
let result = std::panic::catch_unwind(|| {
|
let result = std::panic::catch_unwind(|| {
|
||||||
#namespace::App::test_async(move |cx| async {
|
let foreground = ::std::rc::Rc::new(#namespace::executor::Foreground::test());
|
||||||
#inner_fn_name(cx).await;
|
#namespace::block_on(foreground.run(#inner_fn_name(#inner_fn_args)));
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
@ -66,9 +75,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#namespace::App::test_async(move |cx| async {
|
let foreground = ::std::rc::Rc::new(#namespace::executor::Foreground::test());
|
||||||
#inner_fn_name(cx).await;
|
#namespace::block_on(foreground.run(#inner_fn_name(#inner_fn_args)));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue