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.
175 lines
5.1 KiB
TypeScript
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 { }
|