1
+ package org .slf4j .test ;
2
+
3
+ import org .junit .Test ;
4
+ import org .slf4j .Logger ;
5
+ import org .slf4j .event .Level ;
6
+
7
+ import java .io .IOException ;
8
+ import java .io .OutputStream ;
9
+ import java .util .ArrayList ;
10
+ import java .util .List ;
11
+
12
+ import static org .junit .Assert .assertEquals ;
13
+ import static org .junit .Assert .assertTrue ;
14
+
15
+
16
+ public abstract class LoggerTestSuite {
17
+
18
+ public static class ListAppendingOutputStream extends OutputStream {
19
+ private final StringBuilder word = new StringBuilder ();
20
+ private int index = 0 ;
21
+ private final List <String > list ;
22
+
23
+ private ListAppendingOutputStream (List <String > list ) {this .list = list ;}
24
+
25
+
26
+ @ Override
27
+ public void write (int b ) throws IOException {
28
+ word .append ((char ) b );
29
+ }
30
+
31
+ @ Override
32
+ public void flush () {
33
+ list .add (word .toString ());
34
+ word .delete (0 , word .length ());
35
+ index ++;
36
+ }
37
+ }
38
+
39
+ private ListAppendingOutputStream prepareSink (List <String > source ) {
40
+ return new ListAppendingOutputStream (source );
41
+
42
+ }
43
+
44
+ @ Test
45
+ public void testTrace () {
46
+ ArrayList <String > loggingEvents = new ArrayList <>();
47
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .TRACE );
48
+
49
+ assertTrue ("Trace level should be enabled for this test" , configuredLogger .isTraceEnabled ());
50
+ configuredLogger .trace ("Simple trace message" );
51
+
52
+ assertEquals ("Trace message should've been captured" , 1 , loggingEvents .size ());
53
+ assertTrue ("Message should be logged in trace level" , isTraceMessage (loggingEvents .get (0 )));
54
+ assertEquals ("Supplied trace message wasn't found in the log" ,
55
+ "Simple trace message" ,
56
+ extractMessage (loggingEvents .get (0 )));
57
+
58
+ loggingEvents .clear ();
59
+
60
+ configuredLogger .debug ("Simple debug message" );
61
+ configuredLogger .info ("Simple info message" );
62
+ configuredLogger .warn ("Simple warn message" );
63
+ configuredLogger .error ("Simple error message" );
64
+ assertEquals ("The other levels should have been captured" , 4 , loggingEvents .size ());
65
+
66
+ }
67
+
68
+ @ Test
69
+ public void testDebug () {
70
+ ArrayList <String > loggingEvents = new ArrayList <>();
71
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .DEBUG );
72
+
73
+ configuredLogger .trace ("Simple trace message" );
74
+ assertEquals ("Lower levels should have been ignored" , 0 , loggingEvents .size ());
75
+
76
+ assertTrue ("Debug level should be enabled for this test" , configuredLogger .isDebugEnabled ());
77
+ configuredLogger .debug ("Simple debug message" );
78
+
79
+ assertEquals ("Debug message should've been captured" , 1 , loggingEvents .size ());
80
+ assertTrue ("Message should be logged in debug level" , isDebugMessage (loggingEvents .get (0 )));
81
+ assertEquals ("Supplied debug message wasn't found in the log" ,
82
+ "Simple debug message" ,
83
+ extractMessage (loggingEvents .get (0 )));
84
+
85
+ loggingEvents .clear ();
86
+
87
+ configuredLogger .info ("Simple info message" );
88
+ configuredLogger .warn ("Simple warn message" );
89
+ configuredLogger .error ("Simple error message" );
90
+ assertEquals ("The other levels should have been captured" , 3 , loggingEvents .size ());
91
+ }
92
+
93
+
94
+ @ Test
95
+ public void testInfo () {
96
+ ArrayList <String > loggingEvents = new ArrayList <>();
97
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .INFO );
98
+
99
+ configuredLogger .trace ("Simple trace message" );
100
+ configuredLogger .debug ("Simple debug message" );
101
+ assertEquals ("Lower levels should have been ignored" , 0 , loggingEvents .size ());
102
+
103
+ assertTrue ("Info level should be enabled for this test" , configuredLogger .isInfoEnabled ());
104
+ configuredLogger .info ("Simple info message" );
105
+
106
+ assertEquals ("Info message should've been captured" , 1 , loggingEvents .size ());
107
+ assertTrue ("Message should be logged in debug level" , isInfoMessage (loggingEvents .get (0 )));
108
+ assertEquals ("Supplied info message wasn't found in the log" ,
109
+ "Simple info message" ,
110
+ extractMessage (loggingEvents .get (0 )));
111
+
112
+ loggingEvents .clear ();
113
+
114
+ configuredLogger .warn ("Simple warn message" );
115
+ configuredLogger .error ("Simple error message" );
116
+ assertEquals ("The other levels should have been captured" , 2 , loggingEvents .size ());
117
+ }
118
+
119
+ @ Test
120
+ public void testWarn () {
121
+ ArrayList <String > loggingEvents = new ArrayList <>();
122
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .WARN );
123
+
124
+ configuredLogger .trace ("Simple trace message" );
125
+ configuredLogger .debug ("Simple debug message" );
126
+ configuredLogger .info ("Simple info message" );
127
+ assertEquals ("Lower levels should have been ignored" , 0 , loggingEvents .size ());
128
+
129
+ assertTrue ("Warn level should be enabled for this test" , configuredLogger .isWarnEnabled ());
130
+ configuredLogger .warn ("Simple warn message" );
131
+
132
+ assertEquals ("Warn message should've been captured" , 1 , loggingEvents .size ());
133
+ assertTrue ("Message should be logged in warn level" , isWarnMessage (loggingEvents .get (0 )));
134
+ assertEquals ("Supplied warn message wasn't found in the log" ,
135
+ "Simple warn message" ,
136
+ extractMessage (loggingEvents .get (0 )));
137
+
138
+ loggingEvents .clear ();
139
+
140
+ configuredLogger .error ("Simple error message" );
141
+ assertEquals ("The other levels should have been captured" , 1 , loggingEvents .size ());
142
+ }
143
+
144
+ @ Test
145
+ public void testError () {
146
+ ArrayList <String > loggingEvents = new ArrayList <>();
147
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .ERROR );
148
+
149
+ configuredLogger .trace ("Simple trace message" );
150
+ configuredLogger .debug ("Simple debug message" );
151
+ configuredLogger .info ("Simple info message" );
152
+ configuredLogger .warn ("Simple warn message" );
153
+ assertEquals ("Lower levels should have been ignored" , 0 , loggingEvents .size ());
154
+
155
+ assertTrue ("Error level should be enabled for this test" , configuredLogger .isErrorEnabled ());
156
+ configuredLogger .error ("Simple error message" );
157
+
158
+ assertEquals ("Error message should've been captured" , 1 , loggingEvents .size ());
159
+ assertTrue ("Message should be logged in error level" , isErrorMessage (loggingEvents .get (0 )));
160
+ assertEquals ("Supplied error message wasn't found in the log" ,
161
+ "Simple error message" ,
162
+ extractMessage (loggingEvents .get (0 )));
163
+ }
164
+
165
+ @ Test
166
+ public void testFormatting () {
167
+ ArrayList <String > loggingEvents = new ArrayList <>();
168
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .INFO );
169
+
170
+ configuredLogger .info ("Some {} string" , "formatted" );
171
+ assertEquals ("The formatted message should've been captured" , 1 , loggingEvents .size ());
172
+ assertEquals ("Message should've been formatted" , "Some formatted string" , extractMessage (loggingEvents .get (0 )));
173
+ }
174
+
175
+ @ Test
176
+ public void testException () {
177
+ ArrayList <String > loggingEvents = new ArrayList <>();
178
+ Logger configuredLogger = createLogger (prepareSink (loggingEvents ), Level .INFO );
179
+
180
+ Exception exception = new RuntimeException ("My error" );
181
+
182
+ configuredLogger .info ("Logging with an exception" , exception );
183
+ assertEquals ("The formatted message should've been captured" , 1 , loggingEvents .size ());
184
+ assertEquals ("Message should've been formatted" ,
185
+ "My error" ,
186
+ extractExceptionMessage (loggingEvents .get (0 )));
187
+
188
+ assertEquals ("Message should've been formatted" ,
189
+ "java.lang.RuntimeException" ,
190
+ extractExceptionType (loggingEvents .get (0 )));
191
+ }
192
+
193
+
194
+ /**
195
+ * Allows tests to check whether the log message contains a trace message.
196
+ * Override if needed.
197
+ * @param message String containing the full log message
198
+ * @return whether it is a trace message or not
199
+ */
200
+ protected boolean isTraceMessage (String message ) {
201
+ return message .toLowerCase ().contains ("trace" );
202
+ }
203
+
204
+ /**
205
+ * Allows tests to check whether the log message contains a debug message.
206
+ * Override if needed.
207
+ * @param message String containing the full log message
208
+ * @return whether it is a debug message or not
209
+ */
210
+ protected boolean isDebugMessage (String message ) {
211
+ return message .toLowerCase ().contains ("debug" );
212
+ }
213
+
214
+ /**
215
+ * Allows tests to check whether the log message contains an info message.
216
+ * Override if needed.
217
+ * @param message String containing the full log message
218
+ * @return whether it is an info message or not
219
+ */
220
+ protected boolean isInfoMessage (String message ) {
221
+ return message .toLowerCase ().contains ("info" );
222
+ }
223
+
224
+ /**
225
+ * Allows tests to check whether the log message contains a warn message.
226
+ * Override if needed.
227
+ * @param message String containing the full log message
228
+ * @return whether it is a warn message or not
229
+ */
230
+ protected boolean isWarnMessage (String message ) {
231
+ return message .toLowerCase ().contains ("warn" );
232
+ }
233
+
234
+ /**
235
+ * Allows tests to check whether the log message contains an error message.
236
+ * Override if needed.
237
+ * @param message String containing the full log message
238
+ * @return whether it is an error message or not
239
+ */
240
+ protected boolean isErrorMessage (String message ) {
241
+ return message .toLowerCase ().contains ("error" );
242
+ }
243
+
244
+ /**
245
+ * Extracts only the part of the log string that should represent the `message` string.
246
+ * @param message the full log message
247
+ * @return only the supplied message
248
+ */
249
+ public abstract String extractMessage (String message );
250
+
251
+ /**
252
+ * Extracts only the part of the log string that should represent the supplied exception message, if any.
253
+ * @param message the full log message
254
+ * @return only the supplied exception message
255
+ */
256
+ public abstract String extractExceptionMessage (String message );
257
+
258
+ /**
259
+ * Extracts only the part of the log string that should represent the supplied exception type.
260
+ * @param message the full log message
261
+ * @return only the supplied exception type name
262
+ */
263
+ public abstract String extractExceptionType (String message );
264
+
265
+ /**
266
+ * Configures the logger for running the tests.
267
+ * @param outputStream The output stream for logs to be written to
268
+ * @param level The expected level the tests will run for this logger
269
+ * @return a configured logger able to run the tests
270
+ */
271
+ public abstract Logger createLogger (ListAppendingOutputStream outputStream , Level level );
272
+
273
+ }
0 commit comments