33//! This private module is only compiled for test runs.
44#![ allow( clippy:: indexing_slicing) ]
55use std:: collections:: BTreeMap ;
6+ use std:: fmt:: Write ;
67use std:: ops:: { Deref , DerefMut } ;
78use std:: panic;
9+ use std:: path:: Path ;
810use std:: sync:: Arc ;
911use std:: time:: { Duration , Instant } ;
1012
1113use ansi_term:: Color ;
1214use async_channel:: { self as channel, Receiver , Sender } ;
1315use chat:: ChatItem ;
1416use once_cell:: sync:: Lazy ;
17+ use pretty_assertions:: assert_eq;
1518use rand:: Rng ;
1619use tempfile:: { tempdir, TempDir } ;
1720use tokio:: runtime:: Handle ;
1821use tokio:: sync:: RwLock ;
19- use tokio:: task;
22+ use tokio:: { fs , task} ;
2023
2124use crate :: chat:: {
2225 self , add_to_chat_contacts_table, create_group_chat, Chat , ChatId , MessageListOptions ,
@@ -285,7 +288,7 @@ impl TestContext {
285288 println ! ( "\n ========== Chats of {}: ==========" , self . name( ) ) ;
286289 if let Ok ( chats) = Chatlist :: try_load ( self , 0 , None , None ) . await {
287290 for ( chat, _) in chats. iter ( ) {
288- self . print_chat ( * chat) . await ;
291+ print ! ( "{}" , self . display_chat ( * chat) . await ) ;
289292 }
290293 }
291294 println ! ( ) ;
@@ -624,14 +627,38 @@ impl TestContext {
624627 res
625628 }
626629
630+ #[ allow( unused) ]
631+ pub async fn golden_test_chat ( & self , chat_id : ChatId , filename : & str ) {
632+ let filename = Path :: new ( "test-data/golden/" ) . join ( filename) ;
633+
634+ let actual = self . display_chat ( chat_id) . await ;
635+
636+ // We're using `unwrap_or_default()` here so that if the file doesn't exist,
637+ // it can be created using `write` below.
638+ let expected = fs:: read ( & filename) . await . unwrap_or_default ( ) ;
639+ let expected = String :: from_utf8 ( expected) . unwrap ( ) ;
640+ if ( std:: env:: var ( "UPDATE_GOLDEN_TESTS" ) == Ok ( "1" . to_string ( ) ) ) && actual != expected {
641+ fs:: write ( & filename, & actual)
642+ . await
643+ . unwrap_or_else ( |e| panic ! ( "Error writing {filename:?}: {e}" ) ) ;
644+ } else {
645+ assert_eq ! (
646+ actual, expected,
647+ "To update the expected value, run `UPDATE_GOLDEN_TESTS=1 cargo test`"
648+ ) ;
649+ }
650+ }
651+
627652 /// Prints out the entire chat to stdout.
628653 ///
629654 /// You can use this to debug your test by printing the entire chat conversation.
630655 // This code is mainly the same as `log_msglist` in `cmdline.rs`, so one day, we could
631656 // merge them to a public function in the `deltachat` crate.
632657 #[ allow( dead_code) ]
633658 #[ allow( clippy:: indexing_slicing) ]
634- pub async fn print_chat ( & self , chat_id : ChatId ) {
659+ async fn display_chat ( & self , chat_id : ChatId ) -> String {
660+ let mut res = String :: new ( ) ;
661+
635662 let msglist = chat:: get_chat_msgs_ex (
636663 self ,
637664 chat_id,
@@ -662,7 +689,8 @@ impl TestContext {
662689 } else {
663690 format ! ( "{} member(s)" , members. len( ) )
664691 } ;
665- println ! (
692+ writeln ! (
693+ res,
666694 "{}#{}: {} [{}]{}{}{} {}" ,
667695 sel_chat. typ,
668696 sel_chat. get_id( ) ,
@@ -686,32 +714,38 @@ impl TestContext {
686714 } else {
687715 ""
688716 } ,
689- ) ;
717+ )
718+ . unwrap ( ) ;
690719
691720 let mut lines_out = 0 ;
692721 for msg_id in msglist {
693722 if msg_id == MsgId :: new ( DC_MSG_ID_DAYMARKER ) {
694- println ! (
723+ writeln ! ( res ,
695724 "--------------------------------------------------------------------------------"
696- ) ;
725+ )
726+ . unwrap ( ) ;
697727
698728 lines_out += 1
699729 } else if !msg_id. is_special ( ) {
700730 if lines_out == 0 {
701- println ! (
731+ writeln ! ( res ,
702732 "--------------------------------------------------------------------------------" ,
703- ) ;
733+ ) . unwrap ( ) ;
704734 lines_out += 1
705735 }
706736 let msg = Message :: load_from_db ( self , msg_id) . await . unwrap ( ) ;
707- log_msg ( self , "" , & msg) . await ;
737+ write_msg ( self , "" , & msg, & mut res ) . await ;
708738 }
709739 }
710740 if lines_out > 0 {
711- println ! (
741+ writeln ! (
742+ res,
712743 "--------------------------------------------------------------------------------"
713- ) ;
744+ )
745+ . unwrap ( ) ;
714746 }
747+
748+ res
715749 }
716750
717751 pub async fn create_group_with_members (
@@ -1041,7 +1075,7 @@ fn print_event(event: &Event) {
10411075/// Logs an individual message to stdout.
10421076///
10431077/// This includes a bunch of the message meta-data as well.
1044- async fn log_msg ( context : & Context , prefix : & str , msg : & Message ) {
1078+ async fn write_msg ( context : & Context , prefix : & str , msg : & Message , buf : & mut String ) {
10451079 let contact = match Contact :: get_by_id ( context, msg. get_from_id ( ) ) . await {
10461080 Ok ( contact) => contact,
10471081 Err ( e) => {
@@ -1061,7 +1095,8 @@ async fn log_msg(context: &Context, prefix: &str, msg: &Message) {
10611095 _ => "" ,
10621096 } ;
10631097 let msgtext = msg. get_text ( ) ;
1064- println ! (
1098+ writeln ! (
1099+ buf,
10651100 "{}{}{}{}: {} (Contact#{}): {} {}{}{}{}{}" ,
10661101 prefix,
10671102 msg. get_id( ) ,
@@ -1095,7 +1130,8 @@ async fn log_msg(context: &Context, prefix: &str, msg: &Message) {
10951130 ""
10961131 } ,
10971132 statestr,
1098- ) ;
1133+ )
1134+ . unwrap ( ) ;
10991135}
11001136
11011137#[ cfg( test) ]
0 commit comments