1+ import { describe , it , expect , beforeEach , afterEach , vi } from "vitest" ;
2+ import fs from "fs" ;
3+ import path from "path" ;
4+ import { createLogger } from "./logger" ;
5+
6+ const TEST_LOG_DIR = "test-logs" ;
7+
8+ beforeEach ( ( ) => {
9+ vi . clearAllMocks ( ) ;
10+ if ( fs . existsSync ( TEST_LOG_DIR ) ) {
11+ fs . rmSync ( TEST_LOG_DIR , { recursive : true , force : true } ) ;
12+ }
13+ } ) ;
14+
15+ afterEach ( ( ) => {
16+ if ( fs . existsSync ( TEST_LOG_DIR ) ) {
17+ fs . rmSync ( TEST_LOG_DIR , { recursive : true , force : true } ) ;
18+ }
19+ } ) ;
20+
21+ describe ( "createLogger" , ( ) => {
22+ it ( "creates logger with default config" , ( ) => {
23+ const logger = createLogger ( ) ;
24+ expect ( logger ) . toHaveProperty ( "info" ) ;
25+ expect ( logger ) . toHaveProperty ( "warn" ) ;
26+ expect ( logger ) . toHaveProperty ( "error" ) ;
27+ expect ( logger ) . toHaveProperty ( "debug" ) ;
28+ expect ( logger ) . toHaveProperty ( "flush" ) ;
29+ } ) ;
30+
31+ it ( "logs to console for stdout levels" , ( ) => {
32+ const consoleSpy = vi . spyOn ( console , "log" ) . mockImplementation ( ( ) => { } ) ;
33+ const errorSpy = vi . spyOn ( console , "error" ) . mockImplementation ( ( ) => { } ) ;
34+
35+ const logger = createLogger ( { levels : { stdout : [ "warn" , "error" ] } } ) ;
36+
37+ logger . warn ( "test" , "warning message" ) ;
38+ logger . error ( "test" , "error message" ) ;
39+ logger . info ( "test" , "info message" ) ;
40+
41+ expect ( consoleSpy ) . toHaveBeenCalledWith ( expect . stringContaining ( "[WARN] warning message" ) ) ;
42+ expect ( errorSpy ) . toHaveBeenCalledWith ( expect . stringContaining ( "[ERROR] error message" ) ) ;
43+ expect ( consoleSpy ) . not . toHaveBeenCalledWith ( expect . stringContaining ( "[INFO] info message" ) ) ;
44+ } ) ;
45+
46+ it ( "writes to files in memory mode" , ( ) => {
47+ const logger = createLogger ( {
48+ mode : "memory" ,
49+ logDir : TEST_LOG_DIR ,
50+ levels : { file : [ "info" , "warn" ] }
51+ } ) ;
52+
53+ logger . info ( "test" , "info message" ) ;
54+ logger . warn ( "test" , "warning message" ) ;
55+ logger . flush ( ) ;
56+
57+ const files = fs . readdirSync ( TEST_LOG_DIR ) ;
58+ expect ( files . length ) . toBeGreaterThan ( 0 ) ;
59+
60+ const logContent = fs . readFileSync ( path . join ( TEST_LOG_DIR , files [ 0 ] ) , "utf8" ) ;
61+ expect ( logContent ) . toContain ( "[INFO] info message" ) ;
62+ expect ( logContent ) . toContain ( "[WARN] warning message" ) ;
63+ } ) ;
64+
65+ it ( "writes to single file when singleFile is true" , ( ) => {
66+ const logger = createLogger ( {
67+ mode : "memory" ,
68+ logDir : TEST_LOG_DIR ,
69+ singleFile : true
70+ } ) ;
71+
72+ logger . info ( "file1" , "message1" ) ;
73+ logger . info ( "file2" , "message2" ) ;
74+ logger . flush ( ) ;
75+
76+ const files = fs . readdirSync ( TEST_LOG_DIR ) ;
77+ expect ( files . length ) . toBe ( 1 ) ;
78+ expect ( files [ 0 ] ) . toMatch ( / c o m b i n e d - / ) ;
79+ } ) ;
80+
81+ it ( "creates log directory if it doesn't exist" , ( ) => {
82+ const logger = createLogger ( { logDir : TEST_LOG_DIR } ) ;
83+ expect ( fs . existsSync ( TEST_LOG_DIR ) ) . toBe ( true ) ;
84+ } ) ;
85+
86+ it ( "handles stream mode" , async ( ) => {
87+ const logger = createLogger ( {
88+ mode : "stream" ,
89+ logDir : TEST_LOG_DIR
90+ } ) ;
91+
92+ logger . info ( "test" , "stream message" ) ;
93+ logger . flush ( ) ;
94+
95+ // Wait for stream to close
96+ await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
97+
98+ const files = fs . readdirSync ( TEST_LOG_DIR ) ;
99+ expect ( files . length ) . toBeGreaterThan ( 0 ) ;
100+ } ) ;
101+
102+ it ( "filters logs by level" , ( ) => {
103+ const logger = createLogger ( {
104+ mode : "memory" ,
105+ logDir : TEST_LOG_DIR ,
106+ levels : { file : [ "error" ] }
107+ } ) ;
108+
109+ logger . info ( "test" , "info" ) ;
110+ logger . error ( "test" , "error" ) ;
111+ logger . flush ( ) ;
112+
113+ const files = fs . readdirSync ( TEST_LOG_DIR ) ;
114+ const content = fs . readFileSync ( path . join ( TEST_LOG_DIR , files [ 0 ] ) , "utf8" ) ;
115+ expect ( content ) . toContain ( "error" ) ;
116+ expect ( content ) . not . toContain ( "info" ) ;
117+ } ) ;
118+ } ) ;
0 commit comments