@@ -148,4 +148,149 @@ describe("ConsoleTransport", () => {
148148 expect ( formattedMsg ) . toContain ( "test-category" ) ;
149149 expect ( formattedMsg ) . toContain ( ">" ) ;
150150 } ) ;
151+
152+ test ( "formats multiple message parts with spaces between them" , ( ) => {
153+ const entry : LogEntry = {
154+ timestamp : new Date ( ) ,
155+ level : LogLevel . INFO ,
156+ message : "" ,
157+ messageParts : [ "Hello" , "world" , 123 ]
158+ } ;
159+
160+ transport . write ( entry ) ;
161+
162+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
163+ expect ( formattedMsg ) . toContain ( "Hello world 123" ) ;
164+ } ) ;
165+
166+ test ( "formats boolean values as 'true' or 'false'" , ( ) => {
167+ const entry : LogEntry = {
168+ timestamp : new Date ( ) ,
169+ level : LogLevel . INFO ,
170+ message : "" ,
171+ messageParts : [ "Status:" , true , "Enabled:" , false ]
172+ } ;
173+
174+ transport . write ( entry ) ;
175+
176+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
177+ expect ( formattedMsg ) . toContain ( "Status: true Enabled: false" ) ;
178+ } ) ;
179+
180+ test ( "formats objects using JSON.stringify" , ( ) => {
181+ const testObj = { name : "test" , value : 42 } ;
182+ const entry : LogEntry = {
183+ timestamp : new Date ( ) ,
184+ level : LogLevel . INFO ,
185+ message : "" ,
186+ messageParts : [ "Object:" , testObj ]
187+ } ;
188+
189+ transport . write ( entry ) ;
190+
191+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
192+ expect ( formattedMsg ) . toContain ( `Object: ${ JSON . stringify ( testObj ) } ` ) ;
193+ } ) ;
194+
195+ test ( "formats arrays using JSON.stringify" , ( ) => {
196+ const testArray = [ 1 , 2 , 3 ] ;
197+ const entry : LogEntry = {
198+ timestamp : new Date ( ) ,
199+ level : LogLevel . INFO ,
200+ message : "" ,
201+ messageParts : [ "Array:" , testArray ]
202+ } ;
203+
204+ transport . write ( entry ) ;
205+
206+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
207+ expect ( formattedMsg ) . toContain ( `Array: ${ JSON . stringify ( testArray ) } ` ) ;
208+ } ) ;
209+
210+ test ( "handles null and undefined values" , ( ) => {
211+ const entry : LogEntry = {
212+ timestamp : new Date ( ) ,
213+ level : LogLevel . INFO ,
214+ message : "" ,
215+ messageParts : [ "Null:" , null , "Undefined:" , undefined ]
216+ } ;
217+
218+ transport . write ( entry ) ;
219+
220+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
221+ expect ( formattedMsg ) . toContain ( "Null: null Undefined: undefined" ) ;
222+ } ) ;
223+
224+ test ( "uses custom formatMessagePart function when provided" , ( ) => {
225+ transport = new ConsoleTransport ( {
226+ formatMessagePart : ( value ) => {
227+ if ( typeof value === 'object' && value !== null ) {
228+ return "OBJECT" ;
229+ }
230+ return String ( value ) . toUpperCase ( ) ;
231+ }
232+ } ) ;
233+
234+ const entry : LogEntry = {
235+ timestamp : new Date ( ) ,
236+ level : LogLevel . INFO ,
237+ message : "" ,
238+ messageParts : [ "test" , 123 , { a : 1 } ]
239+ } ;
240+
241+ transport . write ( entry ) ;
242+
243+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
244+ expect ( formattedMsg ) . toContain ( "TEST 123 OBJECT" ) ;
245+ } ) ;
246+
247+ test ( "falls back to message if messageParts is not provided" , ( ) => {
248+ const entry : LogEntry = {
249+ timestamp : new Date ( ) ,
250+ level : LogLevel . INFO ,
251+ message : "Legacy message" ,
252+ messageParts : [ ]
253+ } ;
254+
255+ transport . write ( entry ) ;
256+
257+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
258+ expect ( formattedMsg ) . toContain ( "Legacy message" ) ;
259+ } ) ;
260+
261+ test ( "uses toString method when available on objects" , ( ) => {
262+ class CustomObject {
263+ toString ( ) {
264+ return "CUSTOM_STRING_REPRESENTATION" ;
265+ }
266+ }
267+
268+ const customObj = new CustomObject ( ) ;
269+ const entry : LogEntry = {
270+ timestamp : new Date ( ) ,
271+ level : LogLevel . INFO ,
272+ message : "" ,
273+ messageParts : [ "Custom object:" , customObj ]
274+ } ;
275+
276+ transport . write ( entry ) ;
277+
278+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
279+ expect ( formattedMsg ) . toContain ( "Custom object: CUSTOM_STRING_REPRESENTATION" ) ;
280+ } ) ;
281+
282+ test ( "falls back to JSON.stringify when toString is not customized" , ( ) => {
283+ const regularObj = { id : 123 , name : "test" } ;
284+ const entry : LogEntry = {
285+ timestamp : new Date ( ) ,
286+ level : LogLevel . INFO ,
287+ message : "" ,
288+ messageParts : [ "Regular object:" , regularObj ]
289+ } ;
290+
291+ transport . write ( entry ) ;
292+
293+ const [ formattedMsg ] = consoleLogSpy . mock . calls [ 0 ] ;
294+ expect ( formattedMsg ) . toContain ( `Regular object: ${ JSON . stringify ( regularObj ) } ` ) ;
295+ } ) ;
151296} ) ;
0 commit comments