Skip to content

Commit 8c2c97d

Browse files
authored
feat: make logger injectable in ResponsiveTable class (#628)
- Add optional logger parameter to TableOptions type - Update ResponsiveTable constructor to accept injected logger function - Replace hardcoded logger.warn call with injected logger instance - Default to logger.warn when no custom logger is provided - Update test to use mock logger function instead of spying on global logger This change improves testability by allowing tests to inject custom loggers and increases flexibility by enabling different logging behaviors per table instance. The change is backward compatible as the logger parameter is optional and defaults to the existing behavior. Resolves dependency injection concerns and enhances unit test isolation by removing reliance on global logger state in tests.
1 parent 509eb8c commit 8c2c97d

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

src/_table.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type TableOptions = {
2929
compactColAligns?: TableCellAlign[];
3030
compactThreshold?: number;
3131
forceCompact?: boolean;
32+
logger?: (message: string) => void;
3233
};
3334

3435
/**
@@ -46,6 +47,7 @@ export class ResponsiveTable {
4647
private compactThreshold: number;
4748
private compactMode = false;
4849
private forceCompact: boolean;
50+
private logger: (message: string) => void;
4951

5052
/**
5153
* Creates a new responsive table instance
@@ -60,6 +62,7 @@ export class ResponsiveTable {
6062
this.compactColAligns = options.compactColAligns;
6163
this.compactThreshold = options.compactThreshold ?? 100;
6264
this.forceCompact = options.forceCompact ?? false;
65+
this.logger = options.logger ?? logger.warn;
6366
}
6467

6568
/**
@@ -105,7 +108,7 @@ export class ResponsiveTable {
105108
const index = this.head.indexOf(compactHeader);
106109
if (index < 0) {
107110
// Log warning for debugging configuration issues
108-
logger.warn(`Warning: Compact header "${compactHeader}" not found in table headers [${this.head.join(', ')}]. Using first column as fallback.`);
111+
this.logger(`Warning: Compact header "${compactHeader}" not found in table headers [${this.head.join(', ')}]. Using first column as fallback.`);
109112
return 0; // fallback to first column if not found
110113
}
111114
return index;
@@ -711,15 +714,15 @@ if (import.meta.vitest != null) {
711714
});
712715

713716
it('should fallback to first column for non-existent headers and log warning', () => {
717+
// Mock logger.warn to capture warning
718+
const mockLogger = vi.fn();
714719
const table = new ResponsiveTable({
715720
head: ['Date', 'Model', 'Input', 'Output', 'Cost'],
716721
compactHead: ['Date', 'NonExistent', 'Cost'],
717722
compactThreshold: 100,
723+
logger: mockLogger,
718724
});
719725

720-
// Mock logger.warn to capture warning
721-
const mockWarn = vi.spyOn(logger, 'warn');
722-
723726
// Mock process.env.COLUMNS to simulate narrow terminal
724727
const originalColumns = process.env.COLUMNS;
725728
process.env.COLUMNS = '80';
@@ -733,12 +736,11 @@ if (import.meta.vitest != null) {
733736
expect(indices).toEqual([0, 0, 4]); // Date (0), fallback to first (0), Cost (4)
734737

735738
// Verify warning was logged
736-
expect(mockWarn).toHaveBeenCalledWith(
739+
expect(mockLogger).toHaveBeenCalledWith(
737740
'Warning: Compact header "NonExistent" not found in table headers [Date, Model, Input, Output, Cost]. Using first column as fallback.',
738741
);
739742

740-
// Restore original values
741-
mockWarn.mockRestore();
743+
// Restore original value
742744
process.env.COLUMNS = originalColumns;
743745
});
744746

0 commit comments

Comments
 (0)