log_test.go raw
1 package lol
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "strings"
8 "testing"
9 )
10
11 func TestLogLevels(t *testing.T) {
12 // Test that log levels are correctly ordered
13 if !(Off < Fatal && Fatal < Error && Error < Warn && Warn < Info && Info < Debug && Debug < Trace) {
14 t.Error("Log levels are not correctly ordered")
15 }
16
17 // Test that LevelNames matches the constants
18 expectedLevelNames := []string{
19 "off", "fatal", "error", "warn", "info", "debug", "trace",
20 }
21 for i, name := range expectedLevelNames {
22 if LevelNames[i] != name {
23 t.Errorf("LevelNames[%d] = %s, want %s", i, LevelNames[i], name)
24 }
25 }
26 }
27
28 func TestGetLogLevel(t *testing.T) {
29 tests := []struct {
30 level string
31 expected int
32 }{
33 {"off", Off},
34 {"fatal", Fatal},
35 {"error", Error},
36 {"warn", Warn},
37 {"info", Info},
38 {"debug", Debug},
39 {"trace", Trace},
40 {"unknown", Info}, // Default to Info for unknown levels
41 }
42
43 for _, test := range tests {
44 t.Run(
45 test.level, func(t *testing.T) {
46 result := GetLogLevel(test.level)
47 if result != test.expected {
48 t.Errorf(
49 "GetLogLevel(%q) = %d, want %d", test.level, result,
50 test.expected,
51 )
52 }
53 },
54 )
55 }
56 }
57
58 func TestSetLogLevel(t *testing.T) {
59 // Save original level
60 originalLevel := Level.Load()
61 defer SetLoggers(int(originalLevel)) // Restore original level after test
62
63 tests := []struct {
64 level string
65 expected int32
66 }{
67 {"off", Off},
68 {"fatal", Fatal},
69 {"error", Error},
70 {"warn", Warn},
71 {"info", Info},
72 {"debug", Debug},
73 {"trace", Trace},
74 {"unknown", Trace}, // Should default to Trace for unknown levels
75 }
76
77 for _, test := range tests {
78 t.Run(
79 test.level, func(t *testing.T) {
80 SetLogLevel(test.level)
81 result := Level.Load()
82 if result != test.expected {
83 t.Errorf(
84 "After SetLogLevel(%q), Level = %d, want %d",
85 test.level, result, test.expected,
86 )
87 }
88 },
89 )
90 }
91 }
92
93 func TestJoinStrings(t *testing.T) {
94 tests := []struct {
95 args []any
96 expected string
97 }{
98 {[]any{}, ""},
99 {[]any{"hello"}, "hello"},
100 {[]any{"hello", "world"}, "hello world"},
101 {[]any{1, 2, 3}, "1 2 3"},
102 {[]any{1, "hello", 3.14}, "1 hello 3.14"},
103 }
104
105 for i, test := range tests {
106 t.Run(
107 fmt.Sprintf("case_%d", i), func(t *testing.T) {
108 result := JoinStrings(test.args...)
109 if result != test.expected {
110 t.Errorf(
111 "JoinStrings(%v) = %q, want %q", test.args, result,
112 test.expected,
113 )
114 }
115 },
116 )
117 }
118 }
119
120 func TestGetLoc(t *testing.T) {
121 loc := GetLoc(1)
122 if !strings.Contains(loc, "log_test.go") {
123 t.Errorf("GetLoc(1) = %q, expected to contain 'log_test.go'", loc)
124 }
125 }
126
127 func TestGetPrinter(t *testing.T) {
128 // Create a buffer to capture output
129 var buf bytes.Buffer
130
131 // Set log level to Info
132 originalLevel := Level.Load()
133 Level.Store(int32(Info))
134 defer Level.Store(originalLevel) // Restore original level
135
136 // Create a printer for Debug level
137 printer := GetPrinter(int32(Debug), &buf, 1)
138
139 // Test Ln method - should not print because Debug > Info
140 buf.Reset()
141 printer.Ln("test message")
142 if buf.String() != "" {
143 t.Errorf(
144 "printer.Ln() printed when level is too high: %q", buf.String(),
145 )
146 }
147
148 // Set log level to Debug
149 Level.Store(int32(Debug))
150
151 // Test Ln method - should print now
152 buf.Reset()
153 printer.Ln("test message")
154 output := buf.String()
155 if output == "" {
156 t.Error("printer.Ln() did not print when it should have")
157 }
158 if !strings.Contains(output, "test message") {
159 t.Errorf(
160 "printer.Ln() output %q does not contain 'test message'", output,
161 )
162 }
163
164 // Test F method
165 buf.Reset()
166 printer.F("formatted %s", "message")
167 output = buf.String()
168 if !strings.Contains(output, "formatted message") {
169 t.Errorf(
170 "printer.F() output %q does not contain 'formatted message'",
171 output,
172 )
173 }
174
175 // Test S method
176 buf.Reset()
177 printer.S("spew message")
178 output = buf.String()
179 if !strings.Contains(output, "spew message") {
180 t.Errorf(
181 "printer.S() output %q does not contain 'spew message'", output,
182 )
183 }
184
185 // Test C method
186 buf.Reset()
187 printer.C(func() string { return "closure message" })
188 output = buf.String()
189 if !strings.Contains(output, "closure message") {
190 t.Errorf(
191 "printer.C() output %q does not contain 'closure message'", output,
192 )
193 }
194
195 // Test Chk method with nil error
196 buf.Reset()
197 result := printer.Chk(nil)
198 if result != false {
199 t.Error("printer.Chk(nil) returned true, expected false")
200 }
201 if buf.String() != "" {
202 t.Errorf("printer.Chk(nil) printed output: %q", buf.String())
203 }
204
205 // Test Chk method with error
206 buf.Reset()
207 testErr := errors.New("test error")
208 result = printer.Chk(testErr)
209 if result != true {
210 t.Error("printer.Chk(error) returned false, expected true")
211 }
212 if !strings.Contains(buf.String(), "test error") {
213 t.Errorf(
214 "printer.Chk(error) output %q does not contain 'test error'",
215 buf.String(),
216 )
217 }
218
219 // Test Err method
220 buf.Reset()
221 err := printer.Err("error %s", "message")
222 if err == nil {
223 t.Error("printer.Err() returned nil error")
224 }
225 if err.Error() != "error message" {
226 t.Errorf(
227 "printer.Err() returned error with message %q, expected 'error message'",
228 err.Error(),
229 )
230 }
231 // Check if the message was logged
232 if !strings.Contains(buf.String(), "error message") {
233 t.Errorf(
234 "printer.Err() output %q does not contain 'error message'",
235 buf.String(),
236 )
237 }
238 }
239
240 func TestGetNullPrinter(t *testing.T) {
241 printer := GetNullPrinter()
242
243 // Test that Ln, F, S, C methods don't panic
244 printer.Ln("test")
245 printer.F("test %s", "format")
246 printer.S("test")
247 printer.C(func() string { return "test" })
248
249 // Test Chk method
250 if !printer.Chk(errors.New("test")) {
251 t.Error("GetNullPrinter().Chk(error) returned false, expected true")
252 }
253 if printer.Chk(nil) {
254 t.Error("GetNullPrinter().Chk(nil) returned true, expected false")
255 }
256
257 // Test Err method
258 err := printer.Err("test %s", "error")
259 if err == nil {
260 t.Error("GetNullPrinter().Err() returned nil error")
261 }
262 if err.Error() != "test error" {
263 t.Errorf(
264 "GetNullPrinter().Err() returned error with message %q, expected 'test error'",
265 err.Error(),
266 )
267 }
268 }
269
270 func TestNew(t *testing.T) {
271 var buf bytes.Buffer
272 log, check, errorf := New(&buf, 1)
273
274 // Verify that all components are created
275 if log == nil {
276 t.Error("New() returned nil Log")
277 }
278 if check == nil {
279 t.Error("New() returned nil Check")
280 }
281 if errorf == nil {
282 t.Error("New() returned nil Errorf")
283 }
284
285 // Test that the log functions work
286 originalLevel := Level.Load()
287 Level.Store(int32(Debug))
288 defer Level.Store(originalLevel)
289
290 buf.Reset()
291 log.D.Ln("test message")
292 if !strings.Contains(buf.String(), "test message") {
293 t.Errorf(
294 "log.D.Ln() output %q doesn't contain 'test message'",
295 buf.String(),
296 )
297 }
298 }
299