This commit upgrades TypeScript from 5.4 to 5.5 and enables the
`noImplicitAny` option for stricter type checking. It refactors code to
comply with `noImplicitAny` and adapts to new TypeScript features and
limitations.
Key changes:
- Migrate from TypeScript 5.4 to 5.5
- Enable `noImplicitAny` for stricter type checking
- Refactor code to comply with new TypeScript features and limitations
Other supporting changes:
- Refactor progress bar handling for type safety
- Drop 'I' prefix from interfaces to align with new code convention
- Update TypeScript target from `ES2017` and `ES2018`.
This allows named capturing groups. Otherwise, new TypeScript compiler
does not compile the project and shows the following error:
```
...
TimestampedFilenameGenerator.spec.ts:105:23 - error TS1503: Named capturing groups are only available when targeting 'ES2018' or later
const pattern = /^(?<timestamp>\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-(?<scriptName>[^.]+?)(?:\.(?<extension>[^.]+))?$/;// timestamp-scriptName.extension
...
```
- Refactor usage of `electron-progressbar` for type safety and
less complexity.
91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
import {
|
|
describe, it, beforeAll, afterAll,
|
|
} from 'vitest';
|
|
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
|
import { main } from './check-desktop-runtime-errors/main';
|
|
import { COMMAND_LINE_FLAGS, CommandLineFlag } from './check-desktop-runtime-errors/cli-args';
|
|
|
|
describe('desktop runtime error checks', () => {
|
|
const { waitForExitCode } = useInterceptedProcessExitOrCompletion(beforeAll, afterAll);
|
|
it('should successfully execute the main function and exit with a zero status code', async () => {
|
|
// arrange
|
|
setCommandLineFlagsFromEnvironmentVariables();
|
|
// act
|
|
const exitCode = await waitForExitCode(
|
|
() => main(),
|
|
);
|
|
// assert
|
|
expect(exitCode).to.equal(0, formatAssertionMessage([
|
|
`Test failed with exit code ${exitCode}; expected 0.`,
|
|
'Examine preceding logs to identify errors.',
|
|
]));
|
|
}, {
|
|
timeout: 60 /* minutes */ * 60000,
|
|
});
|
|
});
|
|
|
|
function useInterceptedProcessExitOrCompletion(
|
|
beforeTest: (callback: () => void) => void,
|
|
afterTest: (callback: () => void) => void,
|
|
) {
|
|
const originalFunction = global.process.exit;
|
|
let isExitCodeReceived = false;
|
|
let exitCodeResolver: (value: number | undefined) => void;
|
|
const waitForExitCode = (runner: () => Promise<void>) => new Promise<number | undefined>(
|
|
(resolve, reject) => {
|
|
exitCodeResolver = resolve;
|
|
runner()
|
|
.catch((error) => {
|
|
if (isExitCodeReceived) {
|
|
return;
|
|
}
|
|
console.error('Process did not call `process.exit` but threw an error:', error);
|
|
reject(error);
|
|
})
|
|
.then(() => {
|
|
if (isExitCodeReceived) {
|
|
return;
|
|
}
|
|
console.log('Process completed without calling `process.exit`. Treating as `0` exit code.');
|
|
exitCodeResolver(0);
|
|
});
|
|
},
|
|
);
|
|
beforeTest(() => {
|
|
global.process.exit = (code?: number): never => {
|
|
exitCodeResolver(code);
|
|
isExitCodeReceived = true;
|
|
return undefined as never;
|
|
};
|
|
});
|
|
afterTest(() => {
|
|
global.process.exit = originalFunction;
|
|
});
|
|
return {
|
|
waitForExitCode,
|
|
};
|
|
}
|
|
|
|
/*
|
|
Map environment variables to CLI arguments for compatibility with Vitest.
|
|
*/
|
|
function setCommandLineFlagsFromEnvironmentVariables() {
|
|
const flagEnvironmentVariableKeyMappings: {
|
|
readonly [key in CommandLineFlag]: string;
|
|
} = {
|
|
[CommandLineFlag.ForceRebuild]: 'BUILD',
|
|
[CommandLineFlag.TakeScreenshot]: 'SCREENSHOT',
|
|
};
|
|
Object.entries(flagEnvironmentVariableKeyMappings)
|
|
.forEach(([flag, environmentVariableKey]) => {
|
|
const flagValue = Number.parseInt(flag, 10) as CommandLineFlag;
|
|
const flagDefinition = COMMAND_LINE_FLAGS[flagValue];
|
|
if (process.env[environmentVariableKey] !== undefined) {
|
|
process.argv = [
|
|
...process.argv,
|
|
flagDefinition,
|
|
];
|
|
}
|
|
});
|
|
}
|