11import { describe , it , expect } from 'vitest' ;
22import {
33 LogLevel ,
4+ LogFormat ,
5+ LoggerConfigSchema ,
6+ LogEntrySchema ,
47 ExtendedLogLevel ,
58 LogDestinationType ,
69 ConsoleDestinationConfigSchema ,
@@ -11,11 +14,103 @@ import {
1114 LogEnrichmentConfigSchema ,
1215 StructuredLogEntrySchema ,
1316 LoggingConfigSchema ,
17+ type LoggerConfig ,
18+ type LogEntry ,
1419 type LogDestination ,
1520 type StructuredLogEntry ,
1621 type LoggingConfig ,
1722} from './logging.zod' ;
1823
24+ describe ( 'LogLevel' , ( ) => {
25+ it ( 'should accept valid log levels' , ( ) => {
26+ const levels = [ 'debug' , 'info' , 'warn' , 'error' , 'fatal' ] ;
27+
28+ levels . forEach ( ( level ) => {
29+ expect ( ( ) => LogLevel . parse ( level ) ) . not . toThrow ( ) ;
30+ } ) ;
31+ } ) ;
32+
33+ it ( 'should reject invalid log levels' , ( ) => {
34+ expect ( ( ) => LogLevel . parse ( 'invalid' ) ) . toThrow ( ) ;
35+ expect ( ( ) => LogLevel . parse ( 'trace' ) ) . toThrow ( ) ; // trace is only in ExtendedLogLevel
36+ } ) ;
37+ } ) ;
38+
39+ describe ( 'LogFormat' , ( ) => {
40+ it ( 'should accept valid log formats' , ( ) => {
41+ const formats = [ 'json' , 'text' , 'pretty' ] ;
42+
43+ formats . forEach ( ( format ) => {
44+ expect ( ( ) => LogFormat . parse ( format ) ) . not . toThrow ( ) ;
45+ } ) ;
46+ } ) ;
47+
48+ it ( 'should reject invalid log formats' , ( ) => {
49+ expect ( ( ) => LogFormat . parse ( 'invalid' ) ) . toThrow ( ) ;
50+ } ) ;
51+ } ) ;
52+
53+ describe ( 'LoggerConfigSchema' , ( ) => {
54+ it ( 'should accept minimal configuration' , ( ) => {
55+ const config = LoggerConfigSchema . parse ( { } ) ;
56+
57+ expect ( config . level ) . toBe ( 'info' ) ;
58+ expect ( config . format ) . toBe ( 'json' ) ;
59+ expect ( config . sourceLocation ) . toBe ( false ) ;
60+ } ) ;
61+
62+ it ( 'should accept full configuration' , ( ) => {
63+ const config : LoggerConfig = {
64+ name : 'my-logger' ,
65+ level : 'debug' ,
66+ format : 'pretty' ,
67+ redact : [ 'apiKey' , 'password' ] ,
68+ sourceLocation : true ,
69+ file : '/var/log/app.log' ,
70+ rotation : {
71+ maxSize : '50m' ,
72+ maxFiles : 10 ,
73+ } ,
74+ } ;
75+
76+ expect ( ( ) => LoggerConfigSchema . parse ( config ) ) . not . toThrow ( ) ;
77+ } ) ;
78+
79+ it ( 'should apply defaults' , ( ) => {
80+ const config = LoggerConfigSchema . parse ( { } ) ;
81+
82+ expect ( config . redact ) . toEqual ( [ 'password' , 'token' , 'secret' , 'key' ] ) ;
83+ } ) ;
84+ } ) ;
85+
86+ describe ( 'LogEntrySchema' , ( ) => {
87+ it ( 'should accept minimal log entry' , ( ) => {
88+ const entry : LogEntry = {
89+ timestamp : '2024-01-15T10:30:00.000Z' ,
90+ level : 'info' ,
91+ message : 'Application started' ,
92+ } ;
93+
94+ expect ( ( ) => LogEntrySchema . parse ( entry ) ) . not . toThrow ( ) ;
95+ } ) ;
96+
97+ it ( 'should accept full log entry' , ( ) => {
98+ const entry : LogEntry = {
99+ timestamp : '2024-01-15T10:30:00.000Z' ,
100+ level : 'error' ,
101+ message : 'Database connection failed' ,
102+ context : { database : 'postgres' , attempt : 3 } ,
103+ error : { message : 'Connection timeout' } ,
104+ traceId : 'abc123' ,
105+ spanId : 'def456' ,
106+ service : 'api-server' ,
107+ component : 'database-pool' ,
108+ } ;
109+
110+ expect ( ( ) => LogEntrySchema . parse ( entry ) ) . not . toThrow ( ) ;
111+ } ) ;
112+ } ) ;
113+
19114describe ( 'ExtendedLogLevel' , ( ) => {
20115 it ( 'should accept valid log levels' , ( ) => {
21116 const levels = [ 'trace' , 'debug' , 'info' , 'warn' , 'error' , 'fatal' ] ;
@@ -268,6 +363,54 @@ describe('LoggingConfigSchema', () => {
268363 expect ( ( ) => LoggingConfigSchema . parse ( config ) ) . not . toThrow ( ) ;
269364 } ) ;
270365
366+ it ( 'should accept configuration with default logger' , ( ) => {
367+ const config : LoggingConfig = {
368+ name : 'app_logging' ,
369+ label : 'Application Logging' ,
370+ default : {
371+ level : 'info' ,
372+ format : 'json' ,
373+ } ,
374+ destinations : [
375+ {
376+ name : 'console' ,
377+ type : 'console' ,
378+ } ,
379+ ] ,
380+ } ;
381+
382+ const parsed = LoggingConfigSchema . parse ( config ) ;
383+ expect ( parsed . default ) . toBeDefined ( ) ;
384+ expect ( parsed . default ?. level ) . toBe ( 'info' ) ;
385+ } ) ;
386+
387+ it ( 'should accept configuration with named loggers' , ( ) => {
388+ const config : LoggingConfig = {
389+ name : 'multi_logger' ,
390+ label : 'Multi Logger' ,
391+ default : {
392+ level : 'info' ,
393+ } ,
394+ loggers : {
395+ database : {
396+ level : 'debug' ,
397+ format : 'json' ,
398+ } ,
399+ http : {
400+ level : 'warn' ,
401+ format : 'text' ,
402+ } ,
403+ } ,
404+ destinations : [ ] ,
405+ } ;
406+
407+ const parsed = LoggingConfigSchema . parse ( config ) ;
408+ expect ( parsed . loggers ) . toBeDefined ( ) ;
409+ expect ( parsed . loggers ?. database ) . toBeDefined ( ) ;
410+ expect ( parsed . loggers ?. database . level ) . toBe ( 'debug' ) ;
411+ expect ( parsed . loggers ?. http . level ) . toBe ( 'warn' ) ;
412+ } ) ;
413+
271414 it ( 'should apply defaults' , ( ) => {
272415 const config = LoggingConfigSchema . parse ( {
273416 name : 'test_logging' ,
@@ -287,6 +430,15 @@ describe('LoggingConfigSchema', () => {
287430 label : 'Production Logging' ,
288431 enabled : true ,
289432 level : 'warn' ,
433+ default : {
434+ level : 'info' ,
435+ format : 'json' ,
436+ } ,
437+ loggers : {
438+ app : {
439+ level : 'debug' ,
440+ } ,
441+ } ,
290442 destinations : [
291443 {
292444 name : 'console_dest' ,
0 commit comments