Skip to content

Commit 0a8af75

Browse files
author
John Doe
committed
refactor: fix unit tests
1 parent a54e5dc commit 0a8af75

File tree

5 files changed

+74
-94
lines changed

5 files changed

+74
-94
lines changed

packages/nx-plugin/src/executors/cli/executor.int.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('runAutorunExecutor', () => {
3535
expect(success).toBe(true);
3636
const cleanCommand = removeColorCodes(command || '');
3737
expect(cleanCommand).toMatch('npx @code-pushup/cli');
38-
expect(cleanCommand).toMatch('CP_VERBOSE=true');
38+
expect(cleanCommand).toMatch('CP_VERBOSE="true"');
3939
expect(executeProcessSpy).toHaveBeenCalledTimes(1);
4040
expect(executeProcessSpy).toHaveBeenCalledWith(
4141
expect.objectContaining({

packages/nx-plugin/src/executors/cli/executor.ts

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,21 @@ export default async function runAutorunExecutor(
4444
if (dryRun) {
4545
logger.warn(`DryRun execution of: \n ${formattedBinString}`);
4646
} else {
47-
logger.command(
48-
binString,
49-
async () => {
50-
try {
51-
await executeProcess({
52-
command,
53-
args: [...positionals, ...args],
54-
...(envVariables && { env: envVariables }),
55-
...(cwd ? { cwd } : {}),
56-
});
57-
} catch (error) {
58-
logger.error(stringifyError(error));
59-
return {
60-
success: false,
61-
command: formattedBinString,
62-
error: error instanceof Error ? error : new Error(`${error}`),
63-
};
64-
}
65-
},
66-
{
67-
env: envVariables,
68-
cwd,
69-
},
70-
);
47+
try {
48+
await executeProcess({
49+
command,
50+
args: [...positionals, ...args],
51+
...(envVariables && { env: envVariables }),
52+
...(cwd ? { cwd } : {}),
53+
});
54+
} catch (error) {
55+
logger.error(stringifyError(error));
56+
return {
57+
success: false,
58+
command: formattedBinString,
59+
error: error instanceof Error ? error : new Error(`${error}`),
60+
};
61+
}
7162
}
7263

7364
return {

packages/nx-plugin/src/executors/cli/executor.unit.test.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,12 @@ describe('runAutorunExecutor', () => {
5858

5959
expect(success).toBe(true);
6060
expect(removeColorCodes(command || '')).toMatch('npx @code-pushup/cli');
61-
// The executor doesn't await logger.command, so executeProcess is called asynchronously
62-
// We verify logger.command was called, which will execute executeProcess
63-
expect(loggerCommandSpy).toHaveBeenCalledTimes(1);
64-
expect(loggerCommandSpy).toHaveBeenCalledWith(
65-
expect.stringContaining('npx @code-pushup/cli'),
66-
expect.any(Function),
61+
// The executor now calls executeProcess directly
62+
expect(executeProcessSpy).toHaveBeenCalledTimes(1);
63+
expect(executeProcessSpy).toHaveBeenCalledWith(
6764
expect.objectContaining({
65+
command: 'npx',
66+
args: expect.arrayContaining(['@code-pushup/cli']),
6867
cwd: MEMFS_VOLUME,
6968
env: expect.any(Object),
7069
}),
@@ -83,7 +82,12 @@ describe('runAutorunExecutor', () => {
8382
expect(output.success).toBe(true);
8483
const commandWithoutAnsi = removeColorCodes(output.command || '');
8584
expect(commandWithoutAnsi).toMatch('cwd-form-context');
86-
expect(loggerCommandSpy).toHaveBeenCalledTimes(1);
85+
expect(executeProcessSpy).toHaveBeenCalledTimes(1);
86+
expect(executeProcessSpy).toHaveBeenCalledWith(
87+
expect.objectContaining({
88+
cwd: 'cwd-form-context',
89+
}),
90+
);
8791
});
8892

8993
it('should get env variables from options', async () => {
@@ -97,8 +101,16 @@ describe('runAutorunExecutor', () => {
97101
executorContext('utils'),
98102
);
99103
const commandWithoutAnsi = removeColorCodes(command || '');
100-
expect(commandWithoutAnsi).toMatch('CP_API_KEY=123456789');
101-
expect(commandWithoutAnsi).toMatch('CP_PROJECT=cli');
104+
expect(commandWithoutAnsi).toMatch('CP_API_KEY="123456789"');
105+
expect(commandWithoutAnsi).toMatch('CP_PROJECT="cli"');
106+
expect(executeProcessSpy).toHaveBeenCalledWith(
107+
expect.objectContaining({
108+
env: expect.objectContaining({
109+
CP_API_KEY: '123456789',
110+
CP_PROJECT: 'cli',
111+
}),
112+
}),
113+
);
102114
});
103115

104116
it('should process executorOptions', async () => {
@@ -147,12 +159,12 @@ describe('runAutorunExecutor', () => {
147159
{ ...executorContext('github-action'), cwd: '<CWD>' },
148160
);
149161

150-
expect(removeColorCodes(command || '')).toMatch('CP_VERBOSE=true');
151-
expect(loggerCommandSpy).toHaveBeenCalledTimes(1);
152-
expect(loggerCommandSpy).toHaveBeenCalledWith(
153-
expect.stringContaining('npx @code-pushup/cli'),
154-
expect.any(Function),
155-
expect.objectContaining({ env: { CP_VERBOSE: 'true' } }),
162+
expect(removeColorCodes(command || '')).toMatch('CP_VERBOSE="true"');
163+
expect(executeProcessSpy).toHaveBeenCalledTimes(1);
164+
expect(executeProcessSpy).toHaveBeenCalledWith(
165+
expect.objectContaining({
166+
env: expect.objectContaining({ CP_VERBOSE: 'true' }),
167+
}),
156168
);
157169
});
158170

packages/utils/src/lib/logger.ts

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -196,41 +196,6 @@ export class Logger {
196196
});
197197
}
198198

199-
/**
200-
* Formats a command string for display with status indicator.
201-
*
202-
* @param bin Command string with arguments.
203-
* @param options Command options (cwd, env).
204-
* @param status Command status ('pending' | 'success' | 'failure').
205-
* @returns Formatted command string with colored status indicator.
206-
*/
207-
#formatCommandStatus(
208-
bin: string,
209-
options?: {
210-
env?: Record<string, string | number | boolean>;
211-
cwd?: string;
212-
},
213-
status: 'pending' | 'success' | 'failure' = 'pending',
214-
): string {
215-
const cwd = options?.cwd && path.relative(process.cwd(), options.cwd);
216-
const cwdPrefix = cwd ? `${ansis.blue(cwd)} ` : '';
217-
const envString =
218-
options?.env && Object.keys(options.env).length > 0
219-
? Object.entries(options.env)
220-
.map(([key, value]) => {
221-
return ansis.gray(`${key}=${value}`);
222-
})
223-
.join(' ')
224-
: '';
225-
const statusColor =
226-
status === 'pending'
227-
? ansis.blue('$')
228-
: status === 'success'
229-
? ansis.green('$')
230-
: ansis.red('$');
231-
return `${cwdPrefix}${statusColor} ${envString}${bin}`;
232-
}
233-
234199
/**
235200
* Similar to {@link task}, but spinner texts are formatted as shell commands.
236201
*
@@ -545,21 +510,24 @@ export function formatCommand(
545510
status: 'pending' | 'success' | 'failure' = 'pending',
546511
): string {
547512
const cwd = options?.cwd && path.relative(process.cwd(), options.cwd);
548-
const cwdPrefix = cwd ? `${ansis.blue(cwd)} ` : '';
513+
const cwdPrefix = cwd ? ansis.blue(cwd) : '';
549514
const envString =
550515
options?.env && Object.keys(options.env).length > 0
551-
? [
552-
...Object.entries(options.env).map(([key, value]) => {
553-
return ansis.gray(`${key}=${value}`);
554-
}),
555-
' ',
556-
].join(' ')
557-
: '';
516+
? Object.entries(options.env).map(([key, value]) => {
517+
return ansis.gray(`${key}="${value}"`);
518+
})
519+
: [];
558520
const statusColor =
559521
status === 'pending'
560522
? ansis.blue('$')
561523
: status === 'success'
562524
? ansis.green('$')
563525
: ansis.red('$');
564-
return `${cwdPrefix}${statusColor} ${envString}${bin}`;
526+
527+
return [
528+
...(cwdPrefix ? [cwdPrefix] : []),
529+
statusColor,
530+
...envString,
531+
bin,
532+
].join(' ');
565533
}

packages/utils/src/lib/logger.unit.test.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ describe('formatCommand', () => {
2222
'failure',
2323
),
2424
).toBe(
25-
`${ansis.blue('<CWD>')} ${ansis.red('$')} ${ansis.gray('CP_VERBOSE=true')} npx eslint . --format=json`,
25+
`${ansis.blue('<CWD>')} ${ansis.red('$')} ${ansis.gray('CP_VERBOSE="true"')} npx eslint . --format=json`,
2626
);
2727
});
2828

2929
it.each([
3030
[undefined, ansis.blue], // default to pending
31-
['pending', ansis.blue],
32-
['success', ansis.green],
33-
['failure', ansis.red],
31+
['pending' as const, ansis.blue],
32+
['success' as const, ansis.green],
33+
['failure' as const, ansis.red],
3434
])(`should format command status %s explicitly`, (status, color) => {
35-
expect(
36-
formatCommand('npx eslint . --format=json', {}, 'pending'),
37-
).toContain(`${color('$')}`);
35+
expect(formatCommand('npx eslint . --format=json', {}, status)).toContain(
36+
`${color('$')}`,
37+
);
3838
});
3939

4040
it('should include cwd prefix when cwd is provided and different from process.cwd()', () => {
@@ -53,12 +53,21 @@ describe('formatCommand', () => {
5353
);
5454
});
5555

56-
it('should format command with single environment variable', () => {
56+
it('should format command with multiple environment variables', () => {
5757
const result = formatCommand('npx eslint .', {
58-
env: { NODE_ENV: 'test' },
58+
env: { NODE_ENV: 'test', NODE_OPTIONS: '--import tsx' },
59+
});
60+
expect(result).toStartWith(
61+
`${ansis.blue('$')} ${ansis.gray('NODE_ENV="test"')} ${ansis.gray('NODE_OPTIONS="--import tsx"')}`,
62+
);
63+
});
64+
65+
it('should format command with environment variable containing spaces', () => {
66+
const result = formatCommand('node packages/cli/src/index.ts', {
67+
env: { NODE_OPTIONS: '--import tsx' },
5968
});
6069
expect(result).toBe(
61-
`${ansis.blue('$')} ${ansis.gray('NODE_ENV=test')} npx eslint .`,
70+
`${ansis.blue('$')} ${ansis.gray('NODE_OPTIONS="--import tsx"')} node packages/cli/src/index.ts`,
6271
);
6372
});
6473
});

0 commit comments

Comments
 (0)