-
Notifications
You must be signed in to change notification settings - Fork 766
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
323 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { constants, config } from '../../src'; | ||
|
||
describe('Configuration', () => { | ||
// Reset the configuration before each test to avoid side effects | ||
beforeEach(() => { | ||
config.reset(); | ||
}); | ||
|
||
describe('Initial Configuration', () => { | ||
it('should initialize with default values', () => { | ||
expect(config.get('legacyMode')).toBe(constants.DEFAULT_GLOBAL_CONFIG.legacyMode); | ||
expect(config.get('logLevel')).toBe(constants.DEFAULT_GLOBAL_CONFIG.logLevel); | ||
}); | ||
}); | ||
|
||
describe('get()', () => { | ||
it('should retrieve the value of an existing key', () => { | ||
expect(config.get('logLevel')).toBe(constants.DEFAULT_GLOBAL_CONFIG.logLevel); | ||
}); | ||
|
||
it('should return the default value for a non-existent key', () => { | ||
expect(config.get('nonExistentKey', 'default')).toBe('default'); | ||
}); | ||
|
||
it('should return undefined for a non-existent key without a default', () => { | ||
expect(config.get('nonExistentKey')).toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe('set()', () => { | ||
it('should update the value of an existing key', () => { | ||
config.set('logLevel', 'DEBUG'); | ||
expect(config.get('logLevel')).toBe('DEBUG'); | ||
}); | ||
|
||
it('should add a new key-value pair', () => { | ||
config.set('newKey', 'value'); | ||
expect(config.get('newKey')).toBe('value'); | ||
}); | ||
}); | ||
|
||
describe('update()', () => { | ||
it('should merge provided configuration with existing values', () => { | ||
config.update({ legacyMode: true, newKey: 'value' }); | ||
expect(config.get('legacyMode')).toBe(true); | ||
expect(config.get('newKey')).toBe('value'); | ||
expect(config.get('logLevel')).toBe('INFO'); // Existing key remains unchanged | ||
}); | ||
}); | ||
|
||
describe('getAll()', () => { | ||
it('should return a copy of the configuration', () => { | ||
const all = config.getAll(); | ||
all.legacyMode = true; // Modify the copy | ||
expect(config.get('legacyMode')).toBe(false); // Original remains unaffected | ||
}); | ||
}); | ||
|
||
describe('reset()', () => { | ||
it('should restore the configuration to initial defaults', () => { | ||
config.set('logLevel', 'ERROR'); | ||
config.reset(); | ||
expect(config.get('logLevel')).toBe('INFO'); | ||
}); | ||
}); | ||
|
||
describe('delete()', () => { | ||
it('should remove a key from the configuration', () => { | ||
config.set('newKey', 'value'); | ||
config.delete('newKey'); | ||
expect(config.hasKey('newKey')).toBe(false); | ||
}); | ||
|
||
it('should do nothing if the key does not exist', () => { | ||
config.delete('nonExistentKey'); | ||
expect(config.hasKey('nonExistentKey')).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('hasKey()', () => { | ||
it('should return true for existing keys', () => { | ||
expect(config.hasKey('logLevel')).toBe(true); | ||
}); | ||
|
||
it('should return false for non-existent keys', () => { | ||
expect(config.hasKey('nonExistentKey')).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('Edge Cases', () => { | ||
it('should handle undefined values with default in get()', () => { | ||
config.set('logLevel', undefined); | ||
expect(config.get('logLevel', 'DEFAULT')).toBe('DEFAULT'); | ||
}); | ||
|
||
it('should treat keys as case-sensitive', () => { | ||
config.set('LogLevel', 'DEBUG'); | ||
expect(config.hasKey('LogLevel')).toBe(true); | ||
expect(config.hasKey('logLevel')).toBe(true); // Original key still exists | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* eslint-disable no-console */ | ||
import { logger, LogLevel } from '../../src'; | ||
|
||
// Mock the config module | ||
const mockConfigStore: { logLevel: LogLevel; [key: string]: any } = { | ||
logLevel: 'INFO', | ||
}; | ||
|
||
jest.mock('../../src/global/config', () => ({ | ||
config: { | ||
get: jest.fn().mockImplementation((key: string, defaultValue?: any) => { | ||
return mockConfigStore[key] ?? defaultValue; | ||
}), | ||
set: jest.fn().mockImplementation((key: string, value: any) => { | ||
mockConfigStore[key] = value; | ||
}), | ||
}, | ||
})); | ||
|
||
// Mock console methods | ||
const mockConsole = { | ||
debug: jest.fn(), | ||
info: jest.fn(), | ||
warn: jest.fn(), | ||
error: jest.fn(), | ||
log: jest.fn(), | ||
}; | ||
|
||
global.console = mockConsole as any; | ||
|
||
describe('Logger', () => { | ||
// const gLog = jest.spyOn(global.console, 'log'); | ||
const gInfo = jest.spyOn(global.console, 'info'); | ||
const gDebug = jest.spyOn(global.console, 'debug'); | ||
const gWarn = jest.spyOn(global.console, 'warn'); | ||
const gError = jest.spyOn(global.console, 'error'); | ||
|
||
beforeEach(() => { | ||
// Reset mock config and console calls | ||
mockConfigStore.logLevel = 'INFO'; | ||
jest.clearAllMocks(); | ||
jest.useFakeTimers(); | ||
jest.setSystemTime(new Date('2024-01-01T00:00:00Z')); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.useRealTimers(); | ||
}); | ||
|
||
describe('Log Level Configuration', () => { | ||
it('should have config log level', () => { | ||
expect(logger.getLogLevel()).toBe('INFO'); | ||
}); | ||
|
||
it('should set and get log level OFF', () => { | ||
logger.setLogLevel('OFF'); | ||
expect(logger.getLogLevel()).toBe('OFF'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual([]); | ||
}); | ||
|
||
it('should set and get log level FATAL', () => { | ||
logger.setLogLevel('FATAL'); | ||
expect(logger.getLogLevel()).toBe('FATAL'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual(['FATAL']); | ||
}); | ||
|
||
it('should set and get log level ERROR', () => { | ||
logger.setLogLevel('ERROR'); | ||
expect(logger.getLogLevel()).toBe('ERROR'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual(['ERROR', 'FATAL']); | ||
}); | ||
|
||
it('should set and get log level WARN', () => { | ||
logger.setLogLevel('WARN'); | ||
expect(logger.getLogLevel()).toBe('WARN'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual(['WARN', 'ERROR', 'FATAL']); | ||
}); | ||
|
||
it('should set and get log level INFO', () => { | ||
logger.setLogLevel('INFO'); | ||
expect(logger.getLogLevel()).toBe('INFO'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual(['INFO', 'WARN', 'ERROR', 'FATAL']); | ||
}); | ||
|
||
it('should set and get log level DEBUG', () => { | ||
logger.setLogLevel('DEBUG'); | ||
expect(logger.getLogLevel()).toBe('DEBUG'); | ||
expect(logger.getEnabledLogLevels()).toStrictEqual([ | ||
'DEBUG', | ||
'INFO', | ||
'WARN', | ||
'ERROR', | ||
'FATAL', | ||
]); | ||
}); | ||
}); | ||
|
||
describe('Log Filtering', () => { | ||
it('should log messages at or above current level', () => { | ||
logger.setLogLevel('WARN'); | ||
|
||
logger.debug('Debug message'); | ||
logger.warn('Warning message'); | ||
|
||
expect(gDebug).not.toHaveBeenCalled(); | ||
expect(gWarn).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not log when level is OFF', () => { | ||
logger.setLogLevel('OFF'); | ||
|
||
logger.error('Error message'); | ||
logger.fatal('Fatal message'); | ||
|
||
expect(gError).not.toHaveBeenCalled(); | ||
expect(gError).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe('Log Methods', () => { | ||
it('should format messages correctly', () => { | ||
logger.info('Test message', { key: 'value' }); | ||
|
||
const expectedMessage = `[2024-01-01T00:00:00.000Z] INFO: Test message\n${JSON.stringify({ key: 'value' }, null, 2)}`; | ||
expect(gInfo).toHaveBeenCalledWith(expectedMessage); | ||
}); | ||
|
||
it('should use appropriate console methods', () => { | ||
logger.setLogLevel('DEBUG'); | ||
logger.debug('Debug'); | ||
logger.info('Info'); | ||
logger.warn('Warn'); | ||
logger.error('Error'); | ||
logger.fatal('Fatal'); | ||
|
||
expect(gDebug).toHaveBeenCalled(); | ||
expect(gInfo).toHaveBeenCalled(); | ||
expect(gWarn).toHaveBeenCalled(); | ||
expect(gError).toHaveBeenCalledTimes(2); | ||
}); | ||
}); | ||
|
||
describe('Edge Cases', () => { | ||
it('should handle empty data', () => { | ||
logger.info('Message without data'); | ||
const expectedMessage = '[2024-01-01T00:00:00.000Z] INFO: Message without data'; | ||
expect(gInfo).toHaveBeenCalledWith(expectedMessage); | ||
}); | ||
|
||
it('should handle circular data structures', () => { | ||
logger.setLogLevel('DEBUG'); | ||
const circularObj: any = { a: 'test' }; | ||
circularObj.myself = circularObj; | ||
|
||
logger.error('Circular error', circularObj); | ||
|
||
// Should handle circular references in stringification | ||
expect(gError).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.