diff --git a/Cargo.lock b/Cargo.lock index bf621e3785..2a790af738 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1635,6 +1635,7 @@ dependencies = [ name = "gpui_macros" version = "0.1.0" dependencies = [ + "proc-macro2", "quote", "syn", ] diff --git a/gpui/src/app.rs b/gpui/src/app.rs index f499207a09..c0a2bc4876 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -128,17 +128,6 @@ impl App { f(&mut *cx) } - pub fn test_async(f: Fn) -> T - where - Fn: FnOnce(TestAppContext) -> F, - F: Future, - { - 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 { let platform = platform::current::platform(); let foreground_platform = platform::current::foreground_platform(); @@ -248,16 +237,18 @@ impl App { } impl TestAppContext { - pub fn new(foreground: Rc) -> Self { + pub fn new(foreground: Rc, first_entity_id: usize) -> Self { let platform = Arc::new(platform::test::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 { - cx: Rc::new(RefCell::new(MutableAppContext::new( - foreground.clone(), - platform, - foreground_platform.clone(), - (), - ))), + cx: Rc::new(RefCell::new(cx)), foreground_platform, }; cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx)); diff --git a/gpui/src/lib.rs b/gpui/src/lib.rs index 216ed79b32..29304b2f1a 100644 --- a/gpui/src/lib.rs +++ b/gpui/src/lib.rs @@ -31,3 +31,4 @@ pub use presenter::{ SizeConstraint, Vector2FExt, }; pub use scoped_pool; +pub use smol::block_on; diff --git a/gpui_macros/Cargo.toml b/gpui_macros/Cargo.toml index 19a8e11eb6..b718e953da 100644 --- a/gpui_macros/Cargo.toml +++ b/gpui_macros/Cargo.toml @@ -9,3 +9,4 @@ proc-macro = true [dependencies] syn = "1.0" quote = "1.0" +proc-macro2 = "1.0" \ No newline at end of file diff --git a/gpui_macros/src/lib.rs b/gpui_macros/src/lib.rs index 53aee377e6..4c2087d754 100644 --- a/gpui_macros/src/lib.rs +++ b/gpui_macros/src/lib.rs @@ -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_name = format_ident!("_{}", inner_fn.sig.ident); 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::(); + let mut outer_fn: ItemFn = if inner_fn.sig.asyncness.is_some() { parse_quote! { #[test] @@ -48,9 +58,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { let mut retries = 0; loop { let result = std::panic::catch_unwind(|| { - #namespace::App::test_async(move |cx| async { - #inner_fn_name(cx).await; - }); + let foreground = ::std::rc::Rc::new(#namespace::executor::Foreground::test()); + #namespace::block_on(foreground.run(#inner_fn_name(#inner_fn_args))); }); match result { @@ -66,9 +75,8 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { } } } else { - #namespace::App::test_async(move |cx| async { - #inner_fn_name(cx).await; - }); + let foreground = ::std::rc::Rc::new(#namespace::executor::Foreground::test()); + #namespace::block_on(foreground.run(#inner_fn_name(#inner_fn_args))); } } }