spec-up-t 1.5.0 → 1.6.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/compiled/body.js +1 -0
- package/assets/compiled/head.css +3 -3
- package/assets/css/index.css +5 -4
- package/assets/css/refs.css +30 -0
- package/assets/css/terms-and-definitions.css +89 -1
- package/assets/js/insert-irefs.js +214 -0
- package/config/asset-map.json +2 -1
- package/package.json +1 -1
- package/src/create-docx.js +13 -6
- package/src/create-pdf.js +22 -18
- package/src/init.js +7 -3
- package/src/parsers/template-tag-parser.js +23 -1
- package/src/pipeline/references/collect-external-references.js +41 -14
- package/src/pipeline/references/external-references-service.js +60 -24
- package/src/pipeline/references/process-xtrefs-data.js +43 -19
- package/src/utils/logger.js +116 -9
- package/src/utils/regex-patterns.js +3 -1
- package/test/logger.test.js +290 -0
- package/assets/css/insert-trefs.css +0 -1
- package/src/utils/LOGGER.md +0 -81
package/src/utils/logger.js
CHANGED
|
@@ -15,30 +15,127 @@ class Logger {
|
|
|
15
15
|
static success(message, ...args) {
|
|
16
16
|
console.log(chalk.green('✅'), chalk.green(message), ...args);
|
|
17
17
|
messageCollector.addMessage('success', message, args);
|
|
18
|
+
|
|
19
|
+
console.log(); // Extra newline for readability
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Error messages - red with X mark
|
|
24
|
+
*
|
|
25
|
+
* Enhanced error logging with optional context and actionable guidance.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} message - The main error message
|
|
28
|
+
* @param {...any} args - Additional arguments. Can include:
|
|
29
|
+
* - Regular values (strings, numbers, objects) for message formatting
|
|
30
|
+
* - An options object (if last arg is object with 'hint', 'context', or 'details' keys):
|
|
31
|
+
* - hint: Actionable suggestion for fixing the error
|
|
32
|
+
* - context: Additional context about where/why the error occurred
|
|
33
|
+
* - details: Technical details or error objects
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* Logger.error('File not found', {
|
|
37
|
+
* context: 'specs.json',
|
|
38
|
+
* hint: 'Create a specs.json file in your project root',
|
|
39
|
+
* details: error.message
|
|
40
|
+
* });
|
|
22
41
|
*/
|
|
23
42
|
static error(message, ...args) {
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
// Extract options object if present (last arg with special keys)
|
|
44
|
+
const lastArg = args[args.length - 1];
|
|
45
|
+
const isOptionsObject = lastArg && typeof lastArg === 'object' &&
|
|
46
|
+
(lastArg.hint || lastArg.context || lastArg.details);
|
|
47
|
+
|
|
48
|
+
const options = isOptionsObject ? args.pop() : {};
|
|
49
|
+
const regularArgs = args;
|
|
50
|
+
|
|
51
|
+
// Display main error message
|
|
52
|
+
console.log(chalk.red('❌'), chalk.red(message), ...regularArgs);
|
|
53
|
+
|
|
54
|
+
// Display context if provided - helps identify the scope of the error
|
|
55
|
+
if (options.context) {
|
|
56
|
+
console.log(chalk.red(' Context:'), chalk.gray(options.context));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Display technical details if provided - useful for debugging
|
|
60
|
+
if (options.details) {
|
|
61
|
+
const detailsStr = typeof options.details === 'object'
|
|
62
|
+
? JSON.stringify(options.details, null, 2)
|
|
63
|
+
: String(options.details);
|
|
64
|
+
console.log(chalk.red(' Details:'), chalk.gray(detailsStr));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Display actionable hint if provided - most valuable for authors
|
|
68
|
+
if (options.hint) {
|
|
69
|
+
console.log(chalk.yellow(' 💡 How to fix:'), chalk.yellow(options.hint));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Collect message with all context for healthcheck/JSON output
|
|
73
|
+
messageCollector.addMessage('error', message, [...regularArgs, options]);
|
|
74
|
+
|
|
75
|
+
console.log(); // Extra newline for readability
|
|
26
76
|
}
|
|
27
77
|
|
|
28
78
|
/**
|
|
29
79
|
* Warning messages - yellow with warning symbol
|
|
80
|
+
*
|
|
81
|
+
* Enhanced warning logging with optional context and actionable guidance.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} message - The main warning message
|
|
84
|
+
* @param {...any} args - Additional arguments. Can include:
|
|
85
|
+
* - Regular values (strings, numbers, objects) for message formatting
|
|
86
|
+
* - An options object (if last arg is object with 'hint', 'context', or 'details' keys):
|
|
87
|
+
* - hint: Actionable suggestion for addressing the warning
|
|
88
|
+
* - context: Additional context about where/why the warning occurred
|
|
89
|
+
* - details: Technical details or related information
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* Logger.warn('Using fallback configuration', {
|
|
93
|
+
* context: 'specs.json missing optional field',
|
|
94
|
+
* hint: 'Add "output_path" to specs.json for better control',
|
|
95
|
+
* details: 'Using default: ./docs'
|
|
96
|
+
* });
|
|
30
97
|
*/
|
|
31
98
|
static warn(message, ...args) {
|
|
32
|
-
|
|
33
|
-
|
|
99
|
+
// Extract options object if present (last arg with special keys)
|
|
100
|
+
const lastArg = args[args.length - 1];
|
|
101
|
+
const isOptionsObject = lastArg && typeof lastArg === 'object' &&
|
|
102
|
+
(lastArg.hint || lastArg.context || lastArg.details);
|
|
103
|
+
|
|
104
|
+
const options = isOptionsObject ? args.pop() : {};
|
|
105
|
+
const regularArgs = args;
|
|
106
|
+
|
|
107
|
+
// Display main warning message
|
|
108
|
+
console.log(chalk.keyword('orange')('❗'), chalk.yellow(message), ...regularArgs);
|
|
109
|
+
|
|
110
|
+
// Display context if provided - helps identify the scope of the warning
|
|
111
|
+
if (options.context) {
|
|
112
|
+
console.log(chalk.yellow(' Context:'), chalk.gray(options.context));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Display technical details if provided - useful for understanding the situation
|
|
116
|
+
if (options.details) {
|
|
117
|
+
const detailsStr = typeof options.details === 'object'
|
|
118
|
+
? JSON.stringify(options.details, null, 2)
|
|
119
|
+
: String(options.details);
|
|
120
|
+
console.log(chalk.yellow(' Details:'), chalk.gray(detailsStr));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Display actionable hint if provided - helps authors improve their spec
|
|
124
|
+
if (options.hint) {
|
|
125
|
+
console.log(chalk.cyan(' 💡 Suggestion:'), chalk.cyan(options.hint));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Collect message with all context for healthcheck/JSON output
|
|
129
|
+
messageCollector.addMessage('warn', message, [...regularArgs, options]);
|
|
130
|
+
|
|
131
|
+
console.log(); // Extra newline for readability
|
|
34
132
|
}
|
|
35
133
|
|
|
36
|
-
/**
|
|
37
|
-
* Info messages - blue with info symbol
|
|
38
|
-
*/
|
|
39
134
|
static info(message, ...args) {
|
|
40
|
-
console.log(chalk.blue('
|
|
135
|
+
console.log(chalk.blue('📋'), chalk.blue(message), ...args);
|
|
41
136
|
messageCollector.addMessage('info', message, args);
|
|
137
|
+
|
|
138
|
+
console.log(); // Extra newline for readability
|
|
42
139
|
}
|
|
43
140
|
|
|
44
141
|
/**
|
|
@@ -47,6 +144,8 @@ class Logger {
|
|
|
47
144
|
static process(message, ...args) {
|
|
48
145
|
console.log(chalk.cyan('🔄'), chalk.cyan(message), ...args);
|
|
49
146
|
messageCollector.addMessage('process', message, args);
|
|
147
|
+
|
|
148
|
+
console.log(); // Extra newline for readability
|
|
50
149
|
}
|
|
51
150
|
|
|
52
151
|
/**
|
|
@@ -55,14 +154,18 @@ class Logger {
|
|
|
55
154
|
static debug(message, ...args) {
|
|
56
155
|
console.log(chalk.gray('🔍'), chalk.gray(message), ...args);
|
|
57
156
|
messageCollector.addMessage('debug', message, args);
|
|
157
|
+
|
|
158
|
+
console.log(); // Extra newline for readability
|
|
58
159
|
}
|
|
59
160
|
|
|
60
161
|
/**
|
|
61
162
|
* Highlight important data - magenta
|
|
62
163
|
*/
|
|
63
164
|
static highlight(message, ...args) {
|
|
64
|
-
console.log(chalk.blue('
|
|
165
|
+
console.log(chalk.blue('📋'), chalk.blue(message), ...args);
|
|
65
166
|
messageCollector.addMessage('highlight', message, args);
|
|
167
|
+
|
|
168
|
+
console.log(); // Extra newline for readability
|
|
66
169
|
}
|
|
67
170
|
|
|
68
171
|
/**
|
|
@@ -71,6 +174,8 @@ class Logger {
|
|
|
71
174
|
static separator() {
|
|
72
175
|
console.log(chalk.gray('═'.repeat(60)));
|
|
73
176
|
messageCollector.addMessage('separator', '═'.repeat(60), []);
|
|
177
|
+
|
|
178
|
+
console.log(); // Extra newline for readability
|
|
74
179
|
}
|
|
75
180
|
|
|
76
181
|
/**
|
|
@@ -82,6 +187,8 @@ class Logger {
|
|
|
82
187
|
const progressMessage = `[${bar}] ${percentage}% ${message}`;
|
|
83
188
|
console.log(chalk.cyan(`📊 ${progressMessage}`));
|
|
84
189
|
messageCollector.addMessage('progress', progressMessage, [current, total]);
|
|
190
|
+
|
|
191
|
+
console.log(); // Extra newline for readability
|
|
85
192
|
}
|
|
86
193
|
}
|
|
87
194
|
|
|
@@ -109,12 +109,14 @@ const templateTags = {
|
|
|
109
109
|
* Pattern breakdown:
|
|
110
110
|
* - ^def$ → Exact match for "def" (definition)
|
|
111
111
|
* - ^ref$ → Exact match for "ref" (reference)
|
|
112
|
+
* - ^iref$ → Exact match for "iref" (inline reference - copies existing term)
|
|
112
113
|
* - ^xref → Starts with "xref" (external reference)
|
|
113
114
|
* - ^tref → Starts with "tref" (typed reference)
|
|
114
115
|
*
|
|
115
116
|
* Examples:
|
|
116
117
|
* - "def" → matches
|
|
117
118
|
* - "ref" → matches
|
|
119
|
+
* - "iref" → matches
|
|
118
120
|
* - "xref" → matches
|
|
119
121
|
* - "tref" → matches
|
|
120
122
|
* - "xref:spec,term" → matches (starts with xref)
|
|
@@ -122,7 +124,7 @@ const templateTags = {
|
|
|
122
124
|
* Flags:
|
|
123
125
|
* - i: case-insensitive matching
|
|
124
126
|
*/
|
|
125
|
-
terminology: /^def$|^ref$|^xref|^tref$/i
|
|
127
|
+
terminology: /^def$|^ref$|^iref$|^xref|^tref$/i
|
|
126
128
|
};
|
|
127
129
|
|
|
128
130
|
/**
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Unit tests for enhanced Logger.error and Logger.warn functionality
|
|
3
|
+
*
|
|
4
|
+
* Tests the new context, hint, and details options for error and warning messages.
|
|
5
|
+
* Ensures backward compatibility with existing simple message calls.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const Logger = require('../src/utils/logger');
|
|
9
|
+
const messageCollector = require('../src/utils/message-collector');
|
|
10
|
+
|
|
11
|
+
// Mock console.log to capture output
|
|
12
|
+
let consoleLogs = [];
|
|
13
|
+
const originalConsoleLog = console.log;
|
|
14
|
+
|
|
15
|
+
beforeAll(() => {
|
|
16
|
+
console.log = (...args) => {
|
|
17
|
+
consoleLogs.push(args);
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterAll(() => {
|
|
22
|
+
console.log = originalConsoleLog;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
consoleLogs = [];
|
|
27
|
+
messageCollector.clearMessages();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
messageCollector.stopCollecting();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('Enhanced Logger.error', () => {
|
|
35
|
+
test('should work with simple message (backward compatibility)', () => {
|
|
36
|
+
Logger.error('Simple error message');
|
|
37
|
+
|
|
38
|
+
expect(consoleLogs.length).toBeGreaterThan(0);
|
|
39
|
+
expect(consoleLogs[0].join(' ')).toContain('Simple error message');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should work with message and regular arguments', () => {
|
|
43
|
+
Logger.error('Error with args', 'arg1', 123);
|
|
44
|
+
|
|
45
|
+
expect(consoleLogs.length).toBeGreaterThan(0);
|
|
46
|
+
const output = consoleLogs[0].join(' ');
|
|
47
|
+
expect(output).toContain('Error with args');
|
|
48
|
+
expect(output).toContain('arg1');
|
|
49
|
+
expect(output).toContain('123');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('should display context when provided', () => {
|
|
53
|
+
consoleLogs = [];
|
|
54
|
+
Logger.error('Test error', { context: 'specs.json' });
|
|
55
|
+
|
|
56
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
57
|
+
expect(allOutput).toContain('Context:');
|
|
58
|
+
expect(allOutput).toContain('specs.json');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should display hint when provided', () => {
|
|
62
|
+
consoleLogs = [];
|
|
63
|
+
Logger.error('Test error', { hint: 'Run npm install' });
|
|
64
|
+
|
|
65
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
66
|
+
expect(allOutput).toContain('How to fix:');
|
|
67
|
+
expect(allOutput).toContain('Run npm install');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('should display details when provided', () => {
|
|
71
|
+
consoleLogs = [];
|
|
72
|
+
Logger.error('Test error', { details: 'Error code: 404' });
|
|
73
|
+
|
|
74
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
75
|
+
expect(allOutput).toContain('Details:');
|
|
76
|
+
expect(allOutput).toContain('Error code: 404');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('should handle all options together', () => {
|
|
80
|
+
consoleLogs = [];
|
|
81
|
+
Logger.error('Test error', {
|
|
82
|
+
context: 'Test context',
|
|
83
|
+
hint: 'Test hint',
|
|
84
|
+
details: 'Test details'
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
88
|
+
expect(allOutput).toContain('Test error');
|
|
89
|
+
expect(allOutput).toContain('Context:');
|
|
90
|
+
expect(allOutput).toContain('Test context');
|
|
91
|
+
expect(allOutput).toContain('How to fix:');
|
|
92
|
+
expect(allOutput).toContain('Test hint');
|
|
93
|
+
expect(allOutput).toContain('Details:');
|
|
94
|
+
expect(allOutput).toContain('Test details');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should handle regular args mixed with options', () => {
|
|
98
|
+
consoleLogs = [];
|
|
99
|
+
Logger.error('Error', 'arg1', 'arg2', { hint: 'Fix it' });
|
|
100
|
+
|
|
101
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
102
|
+
expect(allOutput).toContain('Error');
|
|
103
|
+
expect(allOutput).toContain('arg1');
|
|
104
|
+
expect(allOutput).toContain('arg2');
|
|
105
|
+
expect(allOutput).toContain('Fix it');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('should handle object details', () => {
|
|
109
|
+
consoleLogs = [];
|
|
110
|
+
Logger.error('Test error', {
|
|
111
|
+
details: { code: 404, message: 'Not found' }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
115
|
+
expect(allOutput).toContain('404');
|
|
116
|
+
expect(allOutput).toContain('Not found');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('should not treat regular object as options', () => {
|
|
120
|
+
consoleLogs = [];
|
|
121
|
+
Logger.error('Test error', { someData: 'value' });
|
|
122
|
+
|
|
123
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
124
|
+
expect(allOutput).toContain('Test error');
|
|
125
|
+
// Should treat it as regular argument, not as options
|
|
126
|
+
// The object will be stringified as [object Object]
|
|
127
|
+
expect(allOutput).toContain('[object Object]');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('should collect enhanced messages', () => {
|
|
131
|
+
messageCollector.startCollecting('test');
|
|
132
|
+
|
|
133
|
+
Logger.error('Test error', {
|
|
134
|
+
context: 'test context',
|
|
135
|
+
hint: 'test hint',
|
|
136
|
+
details: 'test details'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const messages = messageCollector.getMessages();
|
|
140
|
+
expect(messages).toHaveLength(1);
|
|
141
|
+
expect(messages[0].type).toBe('error');
|
|
142
|
+
expect(messages[0].message).toBe('Test error');
|
|
143
|
+
|
|
144
|
+
// Should have collected the options
|
|
145
|
+
const additionalData = messages[0].additionalData;
|
|
146
|
+
expect(additionalData).toBeDefined();
|
|
147
|
+
expect(additionalData.length).toBeGreaterThan(0);
|
|
148
|
+
|
|
149
|
+
messageCollector.stopCollecting();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe('Enhanced Logger.warn', () => {
|
|
154
|
+
test('should work with simple message (backward compatibility)', () => {
|
|
155
|
+
Logger.warn('Simple warning message');
|
|
156
|
+
|
|
157
|
+
expect(consoleLogs.length).toBeGreaterThan(0);
|
|
158
|
+
expect(consoleLogs[0].join(' ')).toContain('Simple warning message');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('should work with message and regular arguments', () => {
|
|
162
|
+
Logger.warn('Warning with args', 'arg1', 123);
|
|
163
|
+
|
|
164
|
+
expect(consoleLogs.length).toBeGreaterThan(0);
|
|
165
|
+
const output = consoleLogs[0].join(' ');
|
|
166
|
+
expect(output).toContain('Warning with args');
|
|
167
|
+
expect(output).toContain('arg1');
|
|
168
|
+
expect(output).toContain('123');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('should display context when provided', () => {
|
|
172
|
+
consoleLogs = [];
|
|
173
|
+
Logger.warn('Test warning', { context: 'Configuration file' });
|
|
174
|
+
|
|
175
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
176
|
+
expect(allOutput).toContain('Context:');
|
|
177
|
+
expect(allOutput).toContain('Configuration file');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('should display hint when provided', () => {
|
|
181
|
+
consoleLogs = [];
|
|
182
|
+
Logger.warn('Test warning', { hint: 'Consider updating to latest version' });
|
|
183
|
+
|
|
184
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
185
|
+
expect(allOutput).toContain('Suggestion:');
|
|
186
|
+
expect(allOutput).toContain('Consider updating to latest version');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('should display details when provided', () => {
|
|
190
|
+
consoleLogs = [];
|
|
191
|
+
Logger.warn('Test warning', { details: 'Using fallback: default' });
|
|
192
|
+
|
|
193
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
194
|
+
expect(allOutput).toContain('Details:');
|
|
195
|
+
expect(allOutput).toContain('Using fallback: default');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('should handle all options together', () => {
|
|
199
|
+
consoleLogs = [];
|
|
200
|
+
Logger.warn('Test warning', {
|
|
201
|
+
context: 'Test context',
|
|
202
|
+
hint: 'Test suggestion',
|
|
203
|
+
details: 'Test details'
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
207
|
+
expect(allOutput).toContain('Test warning');
|
|
208
|
+
expect(allOutput).toContain('Context:');
|
|
209
|
+
expect(allOutput).toContain('Test context');
|
|
210
|
+
expect(allOutput).toContain('Suggestion:');
|
|
211
|
+
expect(allOutput).toContain('Test suggestion');
|
|
212
|
+
expect(allOutput).toContain('Details:');
|
|
213
|
+
expect(allOutput).toContain('Test details');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test('should handle regular args mixed with options', () => {
|
|
217
|
+
consoleLogs = [];
|
|
218
|
+
Logger.warn('Warning', 'arg1', 'arg2', { hint: 'Update config' });
|
|
219
|
+
|
|
220
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
221
|
+
expect(allOutput).toContain('Warning');
|
|
222
|
+
expect(allOutput).toContain('arg1');
|
|
223
|
+
expect(allOutput).toContain('arg2');
|
|
224
|
+
expect(allOutput).toContain('Update config');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('should collect enhanced messages', () => {
|
|
228
|
+
messageCollector.startCollecting('test');
|
|
229
|
+
|
|
230
|
+
Logger.warn('Test warning', {
|
|
231
|
+
context: 'test context',
|
|
232
|
+
hint: 'test hint',
|
|
233
|
+
details: 'test details'
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const messages = messageCollector.getMessages();
|
|
237
|
+
expect(messages).toHaveLength(1);
|
|
238
|
+
expect(messages[0].type).toBe('warn');
|
|
239
|
+
expect(messages[0].message).toBe('Test warning');
|
|
240
|
+
|
|
241
|
+
messageCollector.stopCollecting();
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('Edge Cases', () => {
|
|
246
|
+
test('should handle empty options object', () => {
|
|
247
|
+
consoleLogs = [];
|
|
248
|
+
Logger.error('Test', {});
|
|
249
|
+
|
|
250
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
251
|
+
expect(allOutput).toContain('Test');
|
|
252
|
+
// Should just show the message without extra lines
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('should handle null and undefined in options', () => {
|
|
256
|
+
consoleLogs = [];
|
|
257
|
+
Logger.error('Test', {
|
|
258
|
+
context: null,
|
|
259
|
+
hint: undefined,
|
|
260
|
+
details: 'valid'
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
264
|
+
expect(allOutput).toContain('Test');
|
|
265
|
+
expect(allOutput).toContain('Details:');
|
|
266
|
+
expect(allOutput).toContain('valid');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('should handle special characters in options', () => {
|
|
270
|
+
consoleLogs = [];
|
|
271
|
+
Logger.error('Test', {
|
|
272
|
+
hint: 'Fix with: npm run build && npm test'
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
276
|
+
expect(allOutput).toContain('npm run build && npm test');
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test('should handle multiline strings in options', () => {
|
|
280
|
+
consoleLogs = [];
|
|
281
|
+
Logger.error('Test', {
|
|
282
|
+
details: 'Line 1\nLine 2\nLine 3'
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const allOutput = consoleLogs.map(log => log.join(' ')).join('\n');
|
|
286
|
+
expect(allOutput).toContain('Line 1');
|
|
287
|
+
expect(allOutput).toContain('Line 2');
|
|
288
|
+
expect(allOutput).toContain('Line 3');
|
|
289
|
+
});
|
|
290
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/* Currently empty */
|
package/src/utils/LOGGER.md
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# Logger Utility
|
|
2
|
-
|
|
3
|
-
A centralized logging utility for the spec-up-t project that provides consistent, color-coded console output using chalk.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Color-coded messages** for different log levels
|
|
8
|
-
- **Consistent icons** and formatting
|
|
9
|
-
- **Progress indicators** with visual progress bars
|
|
10
|
-
- **Section separators** for organized output
|
|
11
|
-
- **Terminal-friendly** symbols that work across platforms
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```javascript
|
|
16
|
-
const Logger = require('./src/utils/logger');
|
|
17
|
-
|
|
18
|
-
// Success messages (green with checkmark)
|
|
19
|
-
Logger.success('Operation completed successfully');
|
|
20
|
-
|
|
21
|
-
// Error messages (red with X mark)
|
|
22
|
-
Logger.error('Failed to process request');
|
|
23
|
-
|
|
24
|
-
// Warning messages (yellow with warning symbol)
|
|
25
|
-
Logger.warn('Configuration file not found, using defaults');
|
|
26
|
-
|
|
27
|
-
// Info messages (blue with info symbol)
|
|
28
|
-
Logger.info('Processing 42 external references');
|
|
29
|
-
|
|
30
|
-
// Processing status (cyan with arrow)
|
|
31
|
-
Logger.process('Processing repository: owner/repo (15 terms)');
|
|
32
|
-
|
|
33
|
-
// Highlighted information (magenta with star)
|
|
34
|
-
Logger.highlight('Grouped 42 terms into 6 repositories');
|
|
35
|
-
|
|
36
|
-
// Progress indicators
|
|
37
|
-
Logger.progress(3, 5, 'Processing terms'); // Shows: [████████████░░░░░░░░] 60% Processing terms
|
|
38
|
-
|
|
39
|
-
// Section separators
|
|
40
|
-
Logger.separator(); // Shows: ════════════════════════════════════════════════════════════
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Log Levels
|
|
44
|
-
|
|
45
|
-
| Method | Color | Icon | Purpose |
|
|
46
|
-
|--------|-------|------|---------|
|
|
47
|
-
| `success()` | Green | ✓ | Successful operations |
|
|
48
|
-
| `error()` | Red | ✗ | Errors and failures |
|
|
49
|
-
| `warn()` | Yellow | ⚠ | Warnings and non-critical issues |
|
|
50
|
-
| `info()` | Blue | ℹ | General information |
|
|
51
|
-
| `process()` | Cyan | → | Processing status updates |
|
|
52
|
-
| `highlight()` | Magenta | ★ | Important data/summaries |
|
|
53
|
-
| `debug()` | Gray | ◦ | Debug information |
|
|
54
|
-
|
|
55
|
-
## Migration from console.log
|
|
56
|
-
|
|
57
|
-
**Before:**
|
|
58
|
-
```javascript
|
|
59
|
-
console.log(`✅ Successfully processed ${count} items`);
|
|
60
|
-
console.log(`❌ Failed to fetch data from ${url}`);
|
|
61
|
-
console.log(`⚠️ Missing configuration file`);
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**After:**
|
|
65
|
-
```javascript
|
|
66
|
-
Logger.success(`Successfully processed ${count} items`);
|
|
67
|
-
Logger.error(`Failed to fetch data from ${url}`);
|
|
68
|
-
Logger.warn('Missing configuration file');
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Dependencies
|
|
72
|
-
|
|
73
|
-
- `chalk@4` - For terminal colors (CommonJS compatible version)
|
|
74
|
-
|
|
75
|
-
## Installation
|
|
76
|
-
|
|
77
|
-
The logger is automatically available when chalk v4 is installed:
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
npm install chalk@4
|
|
81
|
-
```
|