11//! Utilities to help writing tests. 
22//! 
33//! This private module is only compiled for test runs. 
4- use  std:: collections:: { BTreeMap ,  HashSet } ; 
4+ use  std:: collections:: { BTreeMap ,  BTreeSet ,   HashSet } ; 
55use  std:: env:: current_dir; 
66use  std:: fmt:: Write ; 
77use  std:: ops:: { Deref ,  DerefMut } ; 
@@ -70,67 +70,70 @@ static CONTEXT_NAMES: LazyLock<std::sync::RwLock<BTreeMap<u32, String>>> =
7070/// [`TestContext`]s without managing your own [`LogSink`]. 
7171pub  struct  TestContextManager  { 
7272    log_sink :  LogSink , 
73+     used_names :  BTreeSet < String > , 
7374} 
7475
7576impl  TestContextManager  { 
7677    pub  fn  new ( )  -> Self  { 
77-         let  log_sink = LogSink :: new ( ) ; 
78-         Self  {  log_sink } 
78+         Self  { 
79+             log_sink :  LogSink :: new ( ) , 
80+             used_names :  BTreeSet :: new ( ) , 
81+         } 
7982    } 
8083
8184    pub  async  fn  alice ( & mut  self )  -> TestContext  { 
8285        TestContext :: builder ( ) 
8386            . configure_alice ( ) 
8487            . with_log_sink ( self . log_sink . clone ( ) ) 
85-             . build ( ) 
88+             . build ( Some ( & mut   self . used_names ) ) 
8689            . await 
8790    } 
8891
8992    pub  async  fn  bob ( & mut  self )  -> TestContext  { 
9093        TestContext :: builder ( ) 
9194            . configure_bob ( ) 
9295            . with_log_sink ( self . log_sink . clone ( ) ) 
93-             . build ( ) 
96+             . build ( Some ( & mut   self . used_names ) ) 
9497            . await 
9598    } 
9699
97100    pub  async  fn  charlie ( & mut  self )  -> TestContext  { 
98101        TestContext :: builder ( ) 
99102            . configure_charlie ( ) 
100103            . with_log_sink ( self . log_sink . clone ( ) ) 
101-             . build ( ) 
104+             . build ( Some ( & mut   self . used_names ) ) 
102105            . await 
103106    } 
104107
105108    pub  async  fn  dom ( & mut  self )  -> TestContext  { 
106109        TestContext :: builder ( ) 
107110            . configure_dom ( ) 
108111            . with_log_sink ( self . log_sink . clone ( ) ) 
109-             . build ( ) 
112+             . build ( Some ( & mut   self . used_names ) ) 
110113            . await 
111114    } 
112115
113116    pub  async  fn  elena ( & mut  self )  -> TestContext  { 
114117        TestContext :: builder ( ) 
115118            . configure_elena ( ) 
116119            . with_log_sink ( self . log_sink . clone ( ) ) 
117-             . build ( ) 
120+             . build ( Some ( & mut   self . used_names ) ) 
118121            . await 
119122    } 
120123
121124    pub  async  fn  fiona ( & mut  self )  -> TestContext  { 
122125        TestContext :: builder ( ) 
123126            . configure_fiona ( ) 
124127            . with_log_sink ( self . log_sink . clone ( ) ) 
125-             . build ( ) 
128+             . build ( Some ( & mut   self . used_names ) ) 
126129            . await 
127130    } 
128131
129132    /// Creates a new unconfigured test account. 
130133pub  async  fn  unconfigured ( & mut  self )  -> TestContext  { 
131134        TestContext :: builder ( ) 
132135            . with_log_sink ( self . log_sink . clone ( ) ) 
133-             . build ( ) 
136+             . build ( Some ( & mut   self . used_names ) ) 
134137            . await 
135138    } 
136139
@@ -326,7 +329,7 @@ impl TestContextBuilder {
326329    } 
327330
328331    /// Builds the [`TestContext`]. 
329- pub  async  fn  build ( self )  -> TestContext  { 
332+ pub  async  fn  build ( self ,   used_names :   Option < & mut   BTreeSet < String > > )  -> TestContext  { 
330333        if  let  Some ( key_pair)  = self . key_pair  { 
331334            let  userid = { 
332335                let  public_key = & key_pair. public ; 
@@ -340,7 +343,19 @@ impl TestContextBuilder {
340343                . addr ; 
341344            let  name = EmailAddress :: new ( & addr) . unwrap ( ) . local ; 
342345
343-             let  test_context = TestContext :: new_internal ( Some ( name) ,  self . log_sink ) . await ; 
346+             let  mut  unused_name = name. clone ( ) ; 
347+             if  let  Some ( used_names)  = used_names { 
348+                 assert ! ( used_names. len( )  < 100 ) ; 
349+                 // If there are multiple Alices, call them 'alice', 'alice2', 'alice3', ... 
350+                 let  mut  i = 1 ; 
351+                 while  used_names. contains ( & unused_name)  { 
352+                     i += 1 ; 
353+                     unused_name = format ! ( "{name}{i}" ) ; 
354+                 } 
355+                 used_names. insert ( unused_name. clone ( ) ) ; 
356+             } 
357+ 
358+             let  test_context = TestContext :: new_internal ( Some ( unused_name) ,  self . log_sink ) . await ; 
344359            test_context. configure_addr ( & addr) . await ; 
345360            key:: store_self_keypair ( & test_context,  & key_pair) 
346361                . await 
@@ -394,21 +409,21 @@ impl TestContext {
394409/// 
395410/// This is a shortcut which configures [email protected]  with a fixed key. 396411pub  async  fn  new_alice ( )  -> Self  { 
397-         Self :: builder ( ) . configure_alice ( ) . build ( ) . await 
412+         Self :: builder ( ) . configure_alice ( ) . build ( None ) . await 
398413    } 
399414
400415    /// Creates a new configured [`TestContext`]. 
401416/// 
402417/// This is a shortcut which configures [email protected]  with a fixed key. 403418pub  async  fn  new_bob ( )  -> Self  { 
404-         Self :: builder ( ) . configure_bob ( ) . build ( ) . await 
419+         Self :: builder ( ) . configure_bob ( ) . build ( None ) . await 
405420    } 
406421
407422    /// Creates a new configured [`TestContext`]. 
408423/// 
409424/// This is a shortcut which configures [email protected]  with a fixed key. 410425pub  async  fn  new_fiona ( )  -> Self  { 
411-         Self :: builder ( ) . configure_fiona ( ) . build ( ) . await 
426+         Self :: builder ( ) . configure_fiona ( ) . build ( None ) . await 
412427    } 
413428
414429    /// Print current chat state. 
@@ -1585,14 +1600,14 @@ mod tests {
15851600
15861601    #[ tokio:: test( flavor = "multi_thread" ,  worker_threads = 2 ) ]  
15871602    async  fn  test_with_alice ( )  { 
1588-         let  alice = TestContext :: builder ( ) . configure_alice ( ) . build ( ) . await ; 
1603+         let  alice = TestContext :: builder ( ) . configure_alice ( ) . build ( None ) . await ; 
15891604        alice. ctx . emit_event ( EventType :: Info ( "hello" . into ( ) ) ) ; 
15901605        // panic!("Alice fails"); 
15911606    } 
15921607
15931608    #[ tokio:: test( flavor = "multi_thread" ,  worker_threads = 2 ) ]  
15941609    async  fn  test_with_bob ( )  { 
1595-         let  bob = TestContext :: builder ( ) . configure_bob ( ) . build ( ) . await ; 
1610+         let  bob = TestContext :: builder ( ) . configure_bob ( ) . build ( None ) . await ; 
15961611        bob. ctx . emit_event ( EventType :: Info ( "there" . into ( ) ) ) ; 
15971612        // panic!("Bob fails"); 
15981613    } 
0 commit comments