Files
privacy.sexy/tests/unit/application/Common/CustomError.spec.ts
undergroundwires 5f11c8d98f Migrate unit/integration tests to Vitest with Vite
As part of transition to Vue 3.0 and Vite (#230), this commit
facilitates the shift towards building rest of the application using
Vite. By doing so, it eliminates reliance on outdated Electron building
system that offered limited control, blocking desktop builds (#233).

Changes include:

- Introduce Vite with Vue 2.0 plugin for test execution.
- Remove `mocha`, `chai` and other related dependencies.
- Adjust test to Vitest syntax.
- Revise and update `tests.md` to document the changes.
- Add `@modyfi/vite-plugin-yaml` plugin to be able to use yaml file
  depended logic on test files, replacing previous webpack behavior.
- Fix failing tests that are revealed by Vitest due to unhandled errors
  and lack of assertments.
- Remove the test that depends on Vue CLI populating `process.env`.
- Use `jsdom` for unit test environment, adding it to dependency to
  `package.json` as project now depends on it and it was not specified
  even though `package-lock.json` included it.
2023-08-22 14:02:35 +02:00

175 lines
5.1 KiB
TypeScript

import {
describe, it, afterEach, expect,
} from 'vitest';
import { CustomError, Environment } from '@/application/Common/CustomError';
describe('CustomError', () => {
afterEach(() => {
Environment.getSetPrototypeOf = () => Object.setPrototypeOf;
Environment.getCaptureStackTrace = () => Error.captureStackTrace;
});
describe('sets members as expected', () => {
it('`name`', () => {
// arrange
const expectedName = CustomErrorConcrete.name;
// act
const sut = new CustomErrorConcrete();
// assert
expect(sut.name).to.equal(expectedName);
});
it('`message`', () => {
// arrange
const expectedMessage = 'expected message';
// act
const sut = new CustomErrorConcrete(expectedMessage);
// assert
expect(sut.message).to.equal(expectedMessage);
});
it('`cause`', () => {
// arrange
const expectedCause = new Error('expected cause');
// act
const sut = new CustomErrorConcrete(undefined, {
cause: expectedCause,
});
// assert
expect(sut.cause).to.equal(expectedCause);
});
describe('`stack`', () => {
it('sets using `getCaptureStackTrace` if available', () => {
// arrange
const mockStackTrace = 'mocked stack trace';
Environment.getCaptureStackTrace = () => (error) => {
(error as Error).stack = mockStackTrace;
};
// act
const sut = new CustomErrorConcrete();
// assert
expect(sut.stack).to.equal(mockStackTrace);
});
it('defined', () => {
// arrange
const customError = new CustomErrorConcrete();
// act
const { stack } = customError;
// assert
expect(stack).to.not.equal(undefined);
});
});
});
describe('retains correct prototypes', () => {
it('instance of `Error`', () => {
// arrange
const expected = Error;
// act
const sut = new CustomErrorConcrete();
// assert
expect(sut).to.be.an.instanceof(expected);
});
it('instance of `CustomErrorConcrete`', () => {
// arrange
const expected = CustomErrorConcrete;
// act
const sut = new CustomErrorConcrete();
// assert
expect(sut).to.be.an.instanceof(expected);
});
it('instance of `CustomError`', () => {
// arrange
const expected = CustomError;
// act
const sut = new CustomErrorConcrete();
// assert
expect(sut).to.be.an.instanceof(expected);
});
it('thrown error retains `CustomError` type', () => {
// arrange
const expected = CustomError;
let thrownError: unknown;
// act
try {
throw new CustomErrorConcrete('message');
} catch (e) {
thrownError = e;
}
// assert
expect(thrownError).to.be.an.instanceof(expected);
});
});
describe('environment compatibility', () => {
describe('Object.setPrototypeOf', () => {
it('does not throw if unavailable', () => {
// arrange
Environment.getSetPrototypeOf = () => undefined;
// act
const act = () => new CustomErrorConcrete();
// assert
expect(act).to.not.throw();
});
it('calls if available', () => {
// arrange
let wasCalled = false;
const setPrototypeOf = () => { wasCalled = true; };
Environment.getSetPrototypeOf = () => setPrototypeOf;
// act
// eslint-disable-next-line no-new
new CustomErrorConcrete();
// assert
expect(wasCalled).to.equal(true);
});
});
describe('Error.captureStackTrace', () => {
it('does not throw if unavailable', () => {
// arrange
Environment.getCaptureStackTrace = () => undefined;
// act
const act = () => new CustomErrorConcrete();
// assert
expect(act).to.not.throw();
});
it('calls if available', () => {
// arrange
let wasCalled = false;
const captureStackTrace = () => { wasCalled = true; };
Environment.getCaptureStackTrace = () => captureStackTrace;
// act
// eslint-disable-next-line no-new
new CustomErrorConcrete();
// assert
expect(wasCalled).to.equal(true);
});
});
});
describe('runtime behavior sanity checks', () => {
/*
* These tests are intended to verify the behavior of the JavaScript runtime or environment,
* rather than specific application logic. Typically, we avoid such tests because we
* trust the behavior of the underlying platform. However, they've been included here
* due to previous unexpected issues, specifically failures when trying to log
* `new Error().stack`. These issues arose because of factors like transpilation,
* source-mapping, and variances in JavaScript engine behaviors.
*/
it('`Error.stack` is defined', () => {
const error = new Error();
// act
const { stack } = error;
// assert
expect(stack).to.not.equal(undefined);
});
});
});
class CustomErrorConcrete extends CustomError { }