1+ using System ;
12using Serilog . Events ;
3+ using Serilog . Sinks . RichTextBoxForms ;
4+ using Serilog . Sinks . RichTextBoxForms . Themes ;
25using Xunit ;
36
47namespace Serilog . Tests . Integration
@@ -92,5 +95,163 @@ public void ControlCharacters_AreEscapedAsUnicode()
9295 Assert . Equal ( expected , RenderAndGetText ( strEvent , "{Message:j}" ) ) ;
9396 }
9497 }
98+
99+ [ Fact ]
100+ public void PrettyPrintJson_FormatsNestedObjectsWithIndentation ( )
101+ {
102+ var nestedProp = new LogEventProperty ( "Nested" , new StructureValue ( new [ ]
103+ {
104+ new LogEventProperty ( "Id" , new ScalarValue ( 123 ) ) ,
105+ new LogEventProperty ( "Name" , new ScalarValue ( "test" ) )
106+ } , "MyObj" ) ) ;
107+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{Nested:j}" ) , new [ ] { nestedProp } ) ;
108+
109+ var options = new RichTextBoxSinkOptions (
110+ theme : _defaultTheme ,
111+ prettyPrintJson : true ,
112+ indentSize : 4 ,
113+ useSpacesForIndent : true ) ;
114+
115+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
116+ var expected = "{\n \" Id\" : 123,\n \" Name\" : \" test\" ,\n \" $type\" : \" MyObj\" \n }" ;
117+ Assert . Equal ( expected , result ) ;
118+ }
119+
120+ [ Fact ]
121+ public void PrettyPrintJson_FormatsArraysWithIndentation ( )
122+ {
123+ var arrayProp = new LogEventProperty ( "Array" , new SequenceValue ( new [ ]
124+ {
125+ new ScalarValue ( 1 ) ,
126+ new ScalarValue ( 2 ) ,
127+ new ScalarValue ( 3 )
128+ } ) ) ;
129+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{Array:j}" ) , new [ ] { arrayProp } ) ;
130+
131+ var options = new RichTextBoxSinkOptions (
132+ theme : _defaultTheme ,
133+ prettyPrintJson : true ,
134+ indentSize : 4 ,
135+ useSpacesForIndent : true ) ;
136+
137+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
138+ var expected = "[\n 1,\n 2,\n 3\n ]" ;
139+ Assert . Equal ( expected , result ) ;
140+ }
141+
142+ [ Fact ]
143+ public void PrettyPrintJson_FormatsDictionariesWithIndentation ( )
144+ {
145+ var dict = new Dictionary < ScalarValue , LogEventPropertyValue >
146+ {
147+ { new ScalarValue ( "a" ) , new ScalarValue ( 1 ) } ,
148+ { new ScalarValue ( "b" ) , new ScalarValue ( "hello" ) }
149+ } ;
150+ var dictProp = new LogEventProperty ( "DictProp" , new DictionaryValue ( dict ) ) ;
151+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{DictProp:j}" ) , new [ ] { dictProp } ) ;
152+
153+ var options = new RichTextBoxSinkOptions (
154+ theme : _defaultTheme ,
155+ prettyPrintJson : true ,
156+ indentSize : 4 ,
157+ useSpacesForIndent : true ) ;
158+
159+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
160+ var expected = "{\n \" a\" : 1,\n \" b\" : \" hello\" \n }" ;
161+ Assert . Equal ( expected , result ) ;
162+ }
163+
164+ [ Fact ]
165+ public void PrettyPrintJson_FormatsNestedStructures ( )
166+ {
167+ var inner = new StructureValue ( new [ ]
168+ {
169+ new LogEventProperty ( "Value" , new ScalarValue ( 42 ) )
170+ } , "Inner" ) ;
171+ var outer = new LogEventProperty ( "Outer" , new StructureValue ( new [ ]
172+ {
173+ new LogEventProperty ( "Inner" , inner ) ,
174+ new LogEventProperty ( "Name" , new ScalarValue ( "test" ) )
175+ } , "Outer" ) ) ;
176+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{Outer:j}" ) , new [ ] { outer } ) ;
177+
178+ var options = new RichTextBoxSinkOptions (
179+ theme : _defaultTheme ,
180+ prettyPrintJson : true ,
181+ indentSize : 4 ,
182+ useSpacesForIndent : true ) ;
183+
184+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
185+ var expected = "{\n \" Inner\" : {\n \" Value\" : 42,\n \" $type\" : \" Inner\" \n },\n \" Name\" : \" test\" ,\n \" $type\" : \" Outer\" \n }" ;
186+ Assert . Equal ( expected , result ) ;
187+ }
188+
189+ [ Fact ]
190+ public void PrettyPrintJson_EmptyCollectionsFormatCorrectly ( )
191+ {
192+ var emptyArray = new LogEventProperty ( "EmptyArray" , new SequenceValue ( Array . Empty < LogEventPropertyValue > ( ) ) ) ;
193+ var emptyObject = new LogEventProperty ( "EmptyObject" , new StructureValue ( Array . Empty < LogEventProperty > ( ) , null ) ) ;
194+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "Array: {EmptyArray:j}, Object: {EmptyObject:j}" ) , new [ ] { emptyArray , emptyObject } ) ;
195+
196+ var options = new RichTextBoxSinkOptions (
197+ theme : _defaultTheme ,
198+ prettyPrintJson : true ,
199+ indentSize : 4 ,
200+ useSpacesForIndent : true ) ;
201+
202+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
203+ Assert . Contains ( "Array: []" , result ) ;
204+ Assert . Contains ( "Object: {}" , result ) ;
205+ }
206+
207+ [ Fact ]
208+ public void PrettyPrintJson_UsesTabsWhenConfigured ( )
209+ {
210+ var prop = new LogEventProperty ( "Test" , new StructureValue ( new [ ]
211+ {
212+ new LogEventProperty ( "Id" , new ScalarValue ( 123 ) )
213+ } , "MyObj" ) ) ;
214+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{Test:j}" ) , new [ ] { prop } ) ;
215+
216+ var options = new RichTextBoxSinkOptions (
217+ theme : _defaultTheme ,
218+ prettyPrintJson : true ,
219+ indentSize : 4 ,
220+ useSpacesForIndent : false ) ;
221+
222+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
223+ var expected = "{\n \t \" Id\" : 123,\n \t \" $type\" : \" MyObj\" \n }" ;
224+ Assert . Equal ( expected , result ) ;
225+ }
226+
227+ [ Fact ]
228+ public void PrettyPrintJson_RespectsIndentSize ( )
229+ {
230+ var prop = new LogEventProperty ( "Test" , new StructureValue ( new [ ]
231+ {
232+ new LogEventProperty ( "Id" , new ScalarValue ( 123 ) )
233+ } , "MyObj" ) ) ;
234+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "{Test:j}" ) , new [ ] { prop } ) ;
235+
236+ var options = new RichTextBoxSinkOptions (
237+ theme : _defaultTheme ,
238+ prettyPrintJson : true ,
239+ indentSize : 2 ,
240+ useSpacesForIndent : true ) ;
241+
242+ var result = RenderAndGetText ( logEvent , "{Message:l}" , options ) ;
243+ var expected = "{\n \" Id\" : 123,\n \" $type\" : \" MyObj\" \n }" ;
244+ Assert . Equal ( expected , result ) ;
245+ }
246+
247+ [ Fact ]
248+ public void CompactJson_StillWorksByDefault ( )
249+ {
250+ var complexProp = new LogEventProperty ( "ComplexProp" , new StructureValue ( new [ ] { new LogEventProperty ( "Id" , new ScalarValue ( 123 ) ) } , "MyObj" ) ) ;
251+ var logEvent = new LogEvent ( DateTimeOffset . Now , LogEventLevel . Information , null , _parser . Parse ( "Value: {ComplexProp}" ) , new [ ] { complexProp } ) ;
252+
253+ // Default behavior (compact)
254+ Assert . Equal ( "Value: {\" Id\" : 123, \" $type\" : \" MyObj\" }" , RenderAndGetText ( logEvent , "{Message:j}" ) ) ;
255+ }
95256 }
96257}
0 commit comments