Files
d-logger/test/logger.time-formatting.test.js
IanKulin 9546dd3ab3 initial
2025-09-25 20:50:13 +08:00

200 lines
6.6 KiB
JavaScript

import { assertEquals, assertThrows, assert } from "@std/assert";
import Logger from '../lib/logger.ts';
import {
setupMocks,
getCapturedLogs,
clearCapturedLogs,
getFirstLogAsJSON,
} from './helpers/logger-test-helpers.js';
// Setup and teardown for all tests
setupMocks();
Deno.test("Logger Time Formatting - Default Time Format - should default to short time format", () => {
clearCapturedLogs();
const logger = new Logger({ format: 'json' });
logger.info('test message');
const parsed = getFirstLogAsJSON();
// Short format should be YYYY-MM-DD HH:MM (without seconds)
assert(parsed.time.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/));
assert(!parsed.time.includes('T'));
assert(!parsed.time.includes('Z'));
assert(!parsed.time.includes('.'));
});
Deno.test("Logger Time Formatting - Default Time Format - should include time option in logger options", () => {
const shortLogger = new Logger({ time: 'short' });
const longLogger = new Logger({ time: 'long' });
const defaultLogger = new Logger();
assertEquals(shortLogger.options.time, 'short');
assertEquals(longLogger.options.time, 'long');
assertEquals(defaultLogger.options.time, 'short'); // default
});
Deno.test("Logger Time Formatting - Short Time Format - should format time as short when time option is 'short'", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'short', format: 'json' });
logger.info('test message');
const parsed = getFirstLogAsJSON();
// Short format: YYYY-MM-DD HH:MM
assert(parsed.time.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/));
assertEquals(parsed.time.length, 16);
});
Deno.test("Logger Time Formatting - Short Time Format - should work with simple formatter and short time", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'short', format: 'simple' });
logger.info('test message');
const logOutput = getCapturedLogs()[0];
// Should contain short time format in brackets
assert(logOutput.match(/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}\]/));
assert(!logOutput.includes('T'));
assert(!logOutput.includes('Z'));
});
Deno.test("Logger Time Formatting - Short Time Format - should truncate time correctly in short format", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'short', format: 'json' });
logger.info('test message');
const parsed = getFirstLogAsJSON();
// Short format should not have seconds or milliseconds
assert(
!parsed.time.includes(':') || parsed.time.split(':').length === 2
);
assert(!parsed.time.includes('.'));
// Should be exactly 16 characters: YYYY-MM-DD HH:MM
assertEquals(parsed.time.length, 16);
});
Deno.test("Logger Time Formatting - Long Time Format - should format time as long ISO string when time is 'long'", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'long', format: 'json' });
logger.info('test message');
const parsed = getFirstLogAsJSON();
// Long format should be full ISO string
assert(parsed.time.includes('T'));
assert(parsed.time.includes('Z'));
assert(parsed.time.includes('.'));
// Should be valid ISO string
new Date(parsed.time); // This should not throw
// Should match ISO format pattern
assert(
parsed.time.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/)
);
});
Deno.test("Logger Time Formatting - Long Time Format - should work with simple formatter and long time", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'long', format: 'simple' });
logger.info('test message');
const logOutput = getCapturedLogs()[0];
// Should contain long time format in brackets
assert(
logOutput.match(/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\]/)
);
assert(logOutput.includes('T'));
assert(logOutput.includes('Z'));
});
Deno.test("Logger Time Formatting - Long Time Format - should preserve time precision in long format", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'long', format: 'json' });
const startTime = Date.now();
logger.info('test message');
const endTime = Date.now();
const parsed = getFirstLogAsJSON();
const logTime = new Date(parsed.time).getTime();
// Log time should be within the test execution window
assert(logTime >= startTime);
assert(logTime <= endTime);
// Should have millisecond precision
assert(parsed.time.includes('.'));
});
Deno.test("Logger Time Formatting - Time Format Consistency - should use consistent time format across multiple log calls", () => {
clearCapturedLogs();
const logger = new Logger({ time: 'short', format: 'json' });
logger.info('first message');
logger.warn('second message');
const logs = getCapturedLogs();
const parsed1 = JSON.parse(logs[0]);
const parsed2 = JSON.parse(logs[1]);
// Both should use short format
assert(parsed1.time.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/));
assert(parsed2.time.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/));
});
Deno.test("Logger Time Formatting - Time Option Validation - should validate time option in constructor", () => {
// Valid options should not throw
new Logger({ time: 'long' });
new Logger({ time: 'short' });
// Invalid option should throw
assertThrows(() => {
new Logger({ time: 'medium' });
}, Error, "Invalid time: medium. Valid times are: long, short");
assertThrows(() => {
new Logger({ time: 'invalid' });
}, Error, "Invalid time: invalid. Valid times are: long, short");
});
Deno.test("Logger Time Formatting - Backward Compatibility - should maintain existing behavior for existing code", () => {
clearCapturedLogs();
// Code that doesn't specify time option should work as before
const logger = new Logger({ format: 'json', level: 'info' });
logger.info('test message');
const parsed = getFirstLogAsJSON();
// Should still have all expected fields
assertEquals(parsed.level, 'info');
assertEquals(parsed.msg, 'test message');
assertEquals(typeof parsed.time, 'string');
assertEquals(typeof parsed.pid, 'number');
assertEquals(typeof parsed.hostname, 'string');
// Time should be in short format (new default)
assert(parsed.time.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/));
});
Deno.test("Logger Time Formatting - Backward Compatibility - should not break existing simple formatter tests", () => {
clearCapturedLogs();
const logger = new Logger({ format: 'simple' });
logger.warn('warning message');
const logOutput = getCapturedLogs()[0];
// Should still contain expected elements
assert(logOutput.includes('[WARN ]'));
assert(logOutput.includes('warning message'));
assert(logOutput.includes('.js:'));
// Should use short time format (new default)
assert(logOutput.match(/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}\]/));
});