Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Jest like API #168

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion source/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import tsd from './lib';

export * from './lib/assertions/assert';
export * from './lib/assertions/tsd/assert';
export * from './lib/assertions/jest-like/assert';

export default tsd;
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/assignable-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is assignable to the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function assignableTo<TargetType>(): void;

/**
* Test that the expected type is assignable to the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function assignableTo<ExpressionType>(expression: ExpressionType): void;

export function assignableTo(): void { }
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/identical-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is identical to the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function identicalTo<TargetType>(): void;

/**
* Test that the expected type is identical to the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function identicalTo<ExpressionType>(expression: ExpressionType): void;

export function identicalTo(): void { }
23 changes: 23 additions & 0 deletions source/lib/assertions/jest-like/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {assignableTo} from './assignable-to';
import {identicalTo} from './identical-to';
import {subtypeOf} from './subtype-of';

import {notAssignableTo} from './not-assignable-to';
import {notIdenticalTo} from './not-identical-to';
import {notSubtypeOf} from './not-subtype-of';

import {toThrowError} from './to-throw-error';

export const api = {
assignableTo,
identicalTo,
subtypeOf,
toThrowError,
not: {
assignableTo: notAssignableTo,
identicalTo: notIdenticalTo,
subtypeOf: notSubtypeOf
},
};

export type AssertTypeAPI = typeof api;
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/not-assignable-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is not assignable to the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function notAssignableTo<TargetType>(): void;

/**
* Test that the expected type is not assignable to the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function notAssignableTo<ExpressionType>(expression: ExpressionType): void;

export function notAssignableTo(): void { }
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/not-identical-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is not identical to the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function notIdenticalTo<TargetType>(): void;

/**
* Test that the expected type is not identical to the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function notIdenticalTo<ExpressionType>(expression: ExpressionType): void;

export function notIdenticalTo(): void { }
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/not-subtype-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is not a subtype of the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function notSubtypeOf<TargetType>(): void;

/**
* Test that the expected type is not a subtype of the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function notSubtypeOf<ExpressionType>(expression: ExpressionType): void;

export function notSubtypeOf(): void { }
18 changes: 18 additions & 0 deletions source/lib/assertions/jest-like/api/subtype-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Test that the expected type is a subtype of the type provided in the first generic parameter.
*
* @template TargetType - The target type that will be compared with expected type.
*/
export function subtypeOf<TargetType>(): void;

/**
* Test that the expected type is a subtype of the type of the expression provided in the first argument.
*
* @param expression - An expression whose type will be compared with expected type.
*/
export function subtypeOf<ExpressionType>(expression: ExpressionType): void;

export function subtypeOf(): void { }
29 changes: 29 additions & 0 deletions source/lib/assertions/jest-like/api/to-throw-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint-disable @typescript-eslint/no-empty-function */

/**
* Test that the expected type throw a type error.
*/
export function toThrowError(): void;

/**
* Test that the expected type throw a type error with expected code.
*
* @param code - The expected error code.
*/
export function toThrowError<Code extends number>(code: Code): void;

/**
* Test that the expected type throw a type error with expected code.
*
* @param regexp - A regular expression that must match the message.
*/
export function toThrowError<Pattern extends RegExp>(regexp: Pattern): void;

/**
* Test that the expected type throw a type error with expected message.
*
* @param message - The expected error message or a regular expression to match the error message.
*/
export function toThrowError<Message extends string>(message: Message): void;

export function toThrowError(): void { }
20 changes: 20 additions & 0 deletions source/lib/assertions/jest-like/assert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import {api, AssertTypeAPI} from './api';

/**
* Create a type assertion holder from the type provided in the first generic parameter.
*
* @template ExpectedType - The expected type that will be compared with another type.
*/
export function assertType<ExpectedType>(): AssertTypeAPI;

/**
* Create a type assertion holder from the type provided in the first argument.
*
* @param expression - The expected expression whose type will be compared with another type.
*/
export function assertType<ExpressionType>(expression: ExpressionType): AssertTypeAPI;

export function assertType() {
return api;
}
36 changes: 36 additions & 0 deletions source/lib/assertions/jest-like/handlers/assignable-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {Diagnostic} from '../../../interfaces';
import {makeDiagnostic} from '../../../utils';
import {JestLikeAssertionNodes, JestLikeContext} from '..';
import {getTypes} from '../util';

export const assignableTo = ({typeChecker}: JestLikeContext, nodes: JestLikeAssertionNodes): Diagnostic[] => {
const diagnostics: Diagnostic[] = [];

if (!nodes) {
return diagnostics;
}

for (const node of nodes) {
const [expectedNode, targetNode] = node;

const expected = getTypes(expectedNode, typeChecker);

if (expected.diagnostic) {
diagnostics.push(expected.diagnostic);
continue;
}

const target = getTypes(targetNode, typeChecker);

if (target.diagnostic) {
diagnostics.push(target.diagnostic);
continue;
}

if (!typeChecker.isTypeAssignableTo(expected.type, target.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is not assignable to type \`${typeChecker.typeToString(target.type)}\`.`));
}
}

return diagnostics;
};
46 changes: 46 additions & 0 deletions source/lib/assertions/jest-like/handlers/identical-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {Diagnostic} from '../../../interfaces';
import {makeDiagnostic} from '../../../utils';
import {JestLikeAssertionNodes, JestLikeContext} from '..';
import {getTypes} from '../util';

export const identicalTo = ({typeChecker}: JestLikeContext, nodes: JestLikeAssertionNodes): Diagnostic[] => {
const diagnostics: Diagnostic[] = [];

if (!nodes) {
return diagnostics;
}

for (const node of nodes) {
const [expectedNode, targetNode] = node;

const expected = getTypes(expectedNode, typeChecker);

if (expected.diagnostic) {
diagnostics.push(expected.diagnostic);
continue;
}

const target = getTypes(targetNode, typeChecker);

if (target.diagnostic) {
diagnostics.push(target.diagnostic);
continue;
}

if (!typeChecker.isTypeAssignableTo(expected.type, target.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is declared too wide for type \`${typeChecker.typeToString(target.type)}\`.`));
continue;
}

if (!typeChecker.isTypeAssignableTo(target.type, expected.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is declared too short for type \`${typeChecker.typeToString(target.type)}\`.`));
continue;
}

if (!typeChecker.isTypeIdenticalTo(expected.type, target.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is not identical to type \`${typeChecker.typeToString(target.type)}\`.`));
}
}

return diagnostics;
};
9 changes: 9 additions & 0 deletions source/lib/assertions/jest-like/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {assignableTo} from './assignable-to';
export {identicalTo} from './identical-to';
export {subtypeOf} from './subtype-of';

export {notAssignableTo} from './not-assignable-to';
export {notIdenticalTo} from './not-identical-to';
export {notSubtypeOf} from './not-subtype-of';

export {toThrowError} from './to-throw-error';
36 changes: 36 additions & 0 deletions source/lib/assertions/jest-like/handlers/not-assignable-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {Diagnostic} from '../../../interfaces';
import {makeDiagnostic} from '../../../utils';
import {JestLikeAssertionNodes, JestLikeContext} from '..';
import {getTypes} from '../util';

export const notAssignableTo = ({typeChecker}: JestLikeContext, nodes: JestLikeAssertionNodes): Diagnostic[] => {
const diagnostics: Diagnostic[] = [];

if (!nodes) {
return diagnostics;
}

for (const node of nodes) {
const [expectedNode, targetNode] = node;

const expected = getTypes(expectedNode, typeChecker);

if (expected.diagnostic) {
diagnostics.push(expected.diagnostic);
continue;
}

const target = getTypes(targetNode, typeChecker);

if (target.diagnostic) {
diagnostics.push(target.diagnostic);
continue;
}

if (typeChecker.isTypeAssignableTo(expected.type, target.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is assignable to type \`${typeChecker.typeToString(target.type)}\`.`));
}
}

return diagnostics;
};
36 changes: 36 additions & 0 deletions source/lib/assertions/jest-like/handlers/not-identical-to.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {Diagnostic} from '../../../interfaces';
import {makeDiagnostic} from '../../../utils';
import {JestLikeAssertionNodes, JestLikeContext} from '..';
import {getTypes} from '../util';

export const notIdenticalTo = ({typeChecker}: JestLikeContext, nodes: JestLikeAssertionNodes): Diagnostic[] => {
const diagnostics: Diagnostic[] = [];

if (!nodes) {
return diagnostics;
}

for (const node of nodes) {
const [expectedNode, targetNode] = node;

const expected = getTypes(expectedNode, typeChecker);

if (expected.diagnostic) {
diagnostics.push(expected.diagnostic);
continue;
}

const target = getTypes(targetNode, typeChecker);

if (target.diagnostic) {
diagnostics.push(target.diagnostic);
continue;
}

if (typeChecker.isTypeIdenticalTo(expected.type, target.type)) {
diagnostics.push(makeDiagnostic(expectedNode, `Expected type \`${typeChecker.typeToString(expected.type)}\` is identical to type \`${typeChecker.typeToString(target.type)}\`.`));
}
}

return diagnostics;
};