@@ -12,6 +12,7 @@ use std::path::{Path, PathBuf};
1212use std:: process:: Command ;
1313use std:: sync:: Mutex ;
1414use std:: sync:: OnceLock ;
15+ #[ cfg( windows) ]
1516use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
1617
1718use crate :: compare:: assert_e2e;
@@ -62,16 +63,15 @@ pub fn global_root() -> PathBuf {
6263 }
6364}
6465
65- // We need to give each test a unique id. The test name could serve this
66- // purpose, but the `test` crate doesn't have a way to obtain the current test
67- // name.[*] Instead, we used the `cargo-test-macro` crate to automatically
68- // insert an init function for each test that sets the test name in a thread
69- // local variable.
70- //
71- // [*] It does set the thread name, but only when running concurrently. If not
72- // running concurrently, all tests are run on the main thread.
66+ // We need to give each test a unique id. The test name serve this
67+ // purpose. We are able to get the test name by having the `cargo-test-macro`
68+ // crate automatically insert an init function for each test that sets the
69+ // test name in a thread local variable.
7370thread_local ! {
71+ #[ cfg( windows) ]
7472 static TEST_ID : RefCell <Option <usize >> = const { RefCell :: new( None ) } ;
73+ #[ cfg( not( windows) ) ]
74+ static TEST_NAME : RefCell <Option <PathBuf >> = const { RefCell :: new( None ) } ;
7575}
7676
7777/// See [`init_root`]
@@ -80,12 +80,26 @@ pub struct TestIdGuard {
8080}
8181
8282/// For test harnesses like [`crate::cargo_test`]
83+ #[ cfg( windows) ]
8384pub fn init_root ( tmp_dir : Option < & ' static str > ) -> TestIdGuard {
8485 static NEXT_ID : AtomicUsize = AtomicUsize :: new ( 0 ) ;
8586
8687 let id = NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) ;
8788 TEST_ID . with ( |n| * n. borrow_mut ( ) = Some ( id) ) ;
89+ let guard = TestIdGuard { _private : ( ) } ;
90+
91+ set_global_root ( tmp_dir) ;
92+ let r = root ( ) ;
93+ r. rm_rf ( ) ;
94+ r. mkdir_p ( ) ;
8895
96+ guard
97+ }
98+
99+ /// For test harnesses like [`crate::cargo_test`]
100+ #[ cfg( not( windows) ) ]
101+ pub fn init_root ( tmp_dir : Option < & ' static str > , test_name : PathBuf ) -> TestIdGuard {
102+ TEST_NAME . with ( |n| * n. borrow_mut ( ) = Some ( test_name) ) ;
89103 let guard = TestIdGuard { _private : ( ) } ;
90104
91105 set_global_root ( tmp_dir) ;
@@ -98,13 +112,17 @@ pub fn init_root(tmp_dir: Option<&'static str>) -> TestIdGuard {
98112
99113impl Drop for TestIdGuard {
100114 fn drop ( & mut self ) {
115+ #[ cfg( windows) ]
101116 TEST_ID . with ( |n| * n. borrow_mut ( ) = None ) ;
117+ #[ cfg( not( windows) ) ]
118+ TEST_NAME . with ( |n| * n. borrow_mut ( ) = None ) ;
102119 }
103120}
104121
105122/// Path to the test's filesystem scratchpad
106123///
107124/// ex: `$CARGO_TARGET_TMPDIR/cit/t0`
125+ #[ cfg( windows) ]
108126pub fn root ( ) -> PathBuf {
109127 let id = TEST_ID . with ( |n| {
110128 n. borrow ( ) . expect (
@@ -118,6 +136,23 @@ pub fn root() -> PathBuf {
118136 root
119137}
120138
139+ /// Path to the test's filesystem scratchpad
140+ ///
141+ /// ex: `$CARGO_TARGET_TMPDIR/cit/t0`
142+ #[ cfg( not( windows) ) ]
143+ pub fn root ( ) -> PathBuf {
144+ let test_name = TEST_NAME . with ( |n| {
145+ n. borrow ( ) . clone ( ) . expect (
146+ "Tests must use the `#[cargo_test]` attribute in \
147+ order to be able to use the crate root.",
148+ )
149+ } ) ;
150+
151+ let mut root = global_root ( ) ;
152+ root. push ( & test_name) ;
153+ root
154+ }
155+
121156/// Path to the current test's `$HOME`
122157///
123158/// ex: `$CARGO_TARGET_TMPDIR/cit/t0/home`
@@ -489,3 +524,26 @@ pub fn windows_reserved_names_are_allowed() -> bool {
489524 true
490525 }
491526}
527+
528+ /// This takes the test location (std::file!() should be passed) and the test name
529+ /// and outputs the location the test should be places in, inside of `target/tmp/cit`
530+ ///
531+ /// `path: tests/testsuite/workspaces.rs`
532+ /// `name: `workspace_in_git
533+ /// `output: "testsuite/workspaces/workspace_in_git`
534+ pub fn test_dir ( path : & str , name : & str ) -> std:: path:: PathBuf {
535+ let test_dir: std:: path:: PathBuf = std:: path:: PathBuf :: from ( path)
536+ . components ( )
537+ // Trim .rs from any files
538+ . map ( |c| c. as_os_str ( ) . to_str ( ) . unwrap ( ) . trim_end_matches ( ".rs" ) )
539+ // We only want to take once we have reached `tests` or `src`. This helps when in a
540+ // workspace: `workspace/more/src/...` would result in `src/...`
541+ . skip_while ( |c| c != & "tests" && c != & "src" )
542+ // We want to skip "tests" since it is taken in `skip_while`.
543+ // "src" is fine since you could have test in "src" named the same as one in "tests"
544+ // Skip "mod" since `snapbox` tests have a folder per test not a file and the files
545+ // are named "mod.rs"
546+ . filter ( |c| c != & "tests" && c != & "mod" )
547+ . collect ( ) ;
548+ test_dir. join ( name)
549+ }
0 commit comments