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.
165 lines
6.1 KiB
TypeScript
165 lines
6.1 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { validateRuntimeSanity } from '@/infrastructure/RuntimeSanity/SanityChecks';
|
|
import type { SanityCheckOptions } from '@/infrastructure/RuntimeSanity/Common/SanityCheckOptions';
|
|
import { SanityCheckOptionsStub } from '@tests/unit/shared/Stubs/SanityCheckOptionsStub';
|
|
import type { SanityValidator } from '@/infrastructure/RuntimeSanity/Common/SanityValidator';
|
|
import { SanityValidatorStub } from '@tests/unit/shared/Stubs/SanityValidatorStub';
|
|
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
|
|
import { collectExceptionMessage } from '@tests/unit/shared/ExceptionCollector';
|
|
|
|
describe('SanityChecks', () => {
|
|
describe('validateRuntimeSanity', () => {
|
|
describe('parameter validation', () => {
|
|
describe('throws when validators are empty', () => {
|
|
itEachAbsentCollectionValue<SanityValidator>((absentCollection) => {
|
|
// arrange
|
|
const expectedError = 'missing validators';
|
|
const validators = absentCollection;
|
|
const context = new TestContext()
|
|
.withValidators(validators);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
// assert
|
|
expect(act).to.throw(expectedError);
|
|
}, { excludeUndefined: true, excludeNull: true });
|
|
});
|
|
});
|
|
|
|
describe('aggregates validators', () => {
|
|
it('does not throw if all validators pass', () => {
|
|
// arrange
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(false),
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(false),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
// assert
|
|
expect(act).to.not.throw();
|
|
});
|
|
it('does not throw if a validator return errors but pass', () => {
|
|
// arrange
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withErrorsResult(['should be ignored'])
|
|
.withShouldValidateResult(false),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
// assert
|
|
expect(act).to.not.throw();
|
|
});
|
|
it('does not throw if validators return no errors', () => {
|
|
// arrange
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([]),
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([]),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
// assert
|
|
expect(act).to.not.throw();
|
|
});
|
|
it('throws if single validator has errors', () => {
|
|
// arrange
|
|
const firstError = 'first-error';
|
|
const secondError = 'second-error';
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([firstError, secondError]),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
const actualError = collectExceptionMessage(act);
|
|
// assert
|
|
expect(actualError).to.have.length.above(0);
|
|
expect(actualError).to.include(firstError);
|
|
expect(actualError).to.include(secondError);
|
|
});
|
|
it('throws with validators name', () => {
|
|
// arrange
|
|
const validatorWithErrors = 'validator-with-errors';
|
|
const validatorWithNoErrors = 'validator-with-no-errors';
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withName(validatorWithErrors)
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult(['error']),
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([]),
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([]),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
const actualError = collectExceptionMessage(act);
|
|
// assert
|
|
expect(actualError).to.have.length.above(0);
|
|
expect(actualError).to.include(validatorWithErrors);
|
|
expect(actualError).to.not.include(validatorWithNoErrors);
|
|
});
|
|
it('accumulates error messages from validators', () => {
|
|
// arrange
|
|
const errorFromFirstValidator = 'first-error';
|
|
const errorFromSecondValidator = 'second-error';
|
|
const context = new TestContext()
|
|
.withValidators([
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([errorFromFirstValidator]),
|
|
new SanityValidatorStub()
|
|
.withShouldValidateResult(true)
|
|
.withErrorsResult([errorFromSecondValidator]),
|
|
]);
|
|
// act
|
|
const act = () => context.validateRuntimeSanity();
|
|
const actualError = collectExceptionMessage(act);
|
|
// assert
|
|
expect(actualError).to.have.length.above(0);
|
|
expect(actualError).to.include(errorFromFirstValidator);
|
|
expect(actualError).to.include(errorFromSecondValidator);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
class TestContext {
|
|
private options: SanityCheckOptions = new SanityCheckOptionsStub();
|
|
|
|
private validators: SanityValidator[] = [new SanityValidatorStub()];
|
|
|
|
public withOptionsSetup(
|
|
setup: (stub: SanityCheckOptionsStub) => SanityCheckOptionsStub,
|
|
) {
|
|
return this.withOptions(setup(new SanityCheckOptionsStub()));
|
|
}
|
|
|
|
public withOptions(options: SanityCheckOptions): this {
|
|
this.options = options;
|
|
return this;
|
|
}
|
|
|
|
public withValidators(validators: SanityValidator[]): this {
|
|
this.validators = validators;
|
|
return this;
|
|
}
|
|
|
|
public validateRuntimeSanity(): ReturnType<typeof validateRuntimeSanity> {
|
|
return validateRuntimeSanity(this.options, this.validators);
|
|
}
|
|
}
|