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

feat!: replace mlh-tsd with tsd-lite #41

Merged
merged 19 commits into from Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 0 additions & 7 deletions e2e/__fixtures__/docblock/concat.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion e2e/__fixtures__/docblock/concat.js

This file was deleted.

9 changes: 0 additions & 9 deletions e2e/__fixtures__/docblock/concat.test.ts

This file was deleted.

@@ -1,4 +1,4 @@
import { expectType } from 'mlh-tsd';
import { expectType } from 'tsd-lite';
import concat from '.';

expectType<string>(concat('pre', 'fix'));
Expand Down
@@ -1,4 +1,4 @@
import { expectType } from 'mlh-tsd';
import { expectType } from 'tsd-lite';
import concat from '.';

expectType<string>(concat('pre', 'fix'));
Expand Down
7 changes: 0 additions & 7 deletions e2e/__fixtures__/pkg-types/types.d.ts

This file was deleted.

5 changes: 0 additions & 5 deletions e2e/__fixtures__/pkg-types/types.test.ts

This file was deleted.

8 changes: 8 additions & 0 deletions e2e/__fixtures__/ts-failing/index.test.ts
@@ -0,0 +1,8 @@
import { expectError, expectType } from 'tsd-lite';
import { makeDate } from '.';

expectType<Date>(makeDate(12345678));
expectType<string>(makeDate(5, 5, 5));

expectError(makeDate(1, 3, 6));
expectError(makeDate(1, 3));
13 changes: 13 additions & 0 deletions e2e/__fixtures__/ts-failing/index.ts
@@ -0,0 +1,13 @@
/* eslint-disable no-unused-vars */

function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}

export { makeDate };
12 changes: 12 additions & 0 deletions e2e/__fixtures__/ts-passing/index.test.ts
@@ -0,0 +1,12 @@
import { expectError, expectType } from 'tsd-lite';

interface SomeType {
readonly prop: string;
}

function doSomething(obj: SomeType) {
expectError((obj.prop = 'hello'));
return obj.prop;
}

expectType<string>(doSomething({ prop: 'val' }));
@@ -1,5 +1,4 @@
{
"types": "./types.d.ts",
"jest": {
"runner": "../../../src/",
"testMatch": ["**/*.test.ts"]
Expand Down
12 changes: 0 additions & 12 deletions e2e/__snapshots__/docblock.test.ts.snap

This file was deleted.

24 changes: 22 additions & 2 deletions e2e/__snapshots__/failing.test.ts.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`works with failing test 1`] = `
"FAIL ./index.test.ts
exports[`works with failing JS test 1`] = `
"FAIL e2e/__fixtures__/js-failing/index.test.ts
✕ tsd typecheck
● tsd typecheck
Argument of type 'number' is not assignable to parameter of type 'string'.
Expand All @@ -15,3 +15,23 @@ Time:
Ran all test suites.
"
`;

exports[`works with failing TS test 1`] = `
"FAIL e2e/__fixtures__/ts-failing/index.test.ts
✕ tsd typecheck
● tsd typecheck
Argument of type 'Date' is not assignable to parameter of type 'string'.
> 5 | expectType<string>(makeDate(5, 5, 5));
| ^
at index.test.ts:5:20
Expected an error, but found none.
> 7 | expectError(makeDate(1, 3, 6));
| ^
at index.test.ts:7:1
Test Suites: 1 failed, 1 total
Tests: 2 failed, 2 passed, 4 total
Snapshots: 0 total
Time:
Ran all test suites.
"
`;
15 changes: 13 additions & 2 deletions e2e/__snapshots__/passing.test.ts.snap
@@ -1,7 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`works with passing test 1`] = `
"PASS ./index.test.ts
exports[`works with passing JS test 1`] = `
"PASS e2e/__fixtures__/js-passing/index.test.ts
✓ tsd typecheck
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time:
Ran all test suites.
"
`;

exports[`works with passing TS test 1`] = `
"PASS e2e/__fixtures__/ts-passing/index.test.ts
✓ tsd typecheck
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Expand Down
12 changes: 0 additions & 12 deletions e2e/__snapshots__/pkg-types.test.ts.snap

This file was deleted.

6 changes: 0 additions & 6 deletions e2e/docblock.test.ts

This file was deleted.

8 changes: 6 additions & 2 deletions e2e/failing.test.ts
@@ -1,6 +1,10 @@
import { expect, test } from '@jest/globals';
import runJest from './runJest';

test('works with failing test', async () => {
expect(await runJest('failing')).toMatchSnapshot();
test('works with failing JS test', async () => {
expect(await runJest('js-failing')).toMatchSnapshot();
});

test('works with failing TS test', async () => {
expect(await runJest('ts-failing')).toMatchSnapshot();
});
8 changes: 6 additions & 2 deletions e2e/passing.test.ts
@@ -1,6 +1,10 @@
import { expect, test } from '@jest/globals';
import runJest from './runJest';

test('works with passing test', async () => {
expect(await runJest('passing')).toMatchSnapshot();
test('works with passing JS test', async () => {
expect(await runJest('js-passing')).toMatchSnapshot();
});

test('works with passing TS test', async () => {
expect(await runJest('ts-passing')).toMatchSnapshot();
});
6 changes: 0 additions & 6 deletions e2e/pkg-types.test.ts

This file was deleted.

11 changes: 11 additions & 0 deletions e2e/tsconfig.json
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"noImplicitOverride": true,
"skipLibCheck": true
},
"include": ["**/*"]
}
8 changes: 5 additions & 3 deletions package.json
Expand Up @@ -20,14 +20,13 @@
"@babel/code-frame": "^7.15.8",
"chalk": "^4.1.2",
"create-jest-runner": "^0.9.0",
"graceful-fs": "^4.2.8",
"jest-docblock": "^27.0.6",
"mlh-tsd": "^0.14.1"
"tsd-lite": "^0.1.0"
},
"devDependencies": {
"@babel/core": "^7.15.8",
"@babel/preset-env": "^7.15.8",
"@babel/preset-typescript": "^7.15.0",
"@tsd/typescript": "^4.4.4",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"babel-jest": "^27.2.5",
Expand All @@ -39,6 +38,9 @@
"prettier": "^2.4.1",
"typescript": "^4.4.4"
},
"peerDependencies": {
"@tsd/typescript": "^3.8.3 || ^4.0.7"
mrazauskas marked this conversation as resolved.
Show resolved Hide resolved
},
"prettier": {
"arrowParens": "avoid",
"singleQuote": true
Expand Down
10 changes: 5 additions & 5 deletions src/formatErrorMessage.js
Expand Up @@ -18,24 +18,24 @@ const NOT_EMPTY_LINE_REGEXP = /^(?!$)/gm;
const indentAllLines = (lines, indent) =>
lines.replace(NOT_EMPTY_LINE_REGEXP, indent);

module.exports = (diagnostics, fileContents) => {
module.exports = diagnostics => {
const title = chalk.bold.red(TITLE_INDENT + BULLET + 'tsd typecheck') + '\n';

const messages = [];

diagnostics.forEach(error => {
const { column, fileName, line, message } = error;
const { column, fileName, fileText, line, message } = error;

const codeFrame = codeFrameColumns(
fileContents,
{ start: { column: column + 1, line } },
fileText,
{ start: { column, line } },
{ highlightCode: true, linesAbove: 0, linesBelow: 0 }
);

const location =
chalk.dim('at ') +
chalk.cyan(basename(fileName)) +
chalk.dim(':' + line + ':' + (column + 1));
chalk.dim(':' + line + ':' + column);

messages.push(
indentAllLines(message, MESSAGE_INDENT) +
Expand Down
49 changes: 7 additions & 42 deletions src/run.js
@@ -1,62 +1,27 @@
const { dirname, join, posix, relative, sep } = require('path');
const { readFileSync } = require('graceful-fs');
const { parse } = require('jest-docblock');
const tsd = require('mlh-tsd');
const tsdLite = require('tsd-lite');
const formatErrorMessage = require('./formatErrorMessage');
const { pass } = require('./pass');
const { fail } = require('./fail');

const TEST_TITLE = 'tsd typecheck';

/**
* @param {string} testFile
* @param {string} fileContents
*/
function resolveTypingsFile(testFile, fileContents) {
let { type } = parse(fileContents);

if (Array.isArray(type)) {
type = type[0];
}

if (type !== undefined) {
return join(dirname(testFile), type);
}

return undefined;
}

/**
* @param {string} input
*/
const normalizeSlashes = input => input.split(sep).join(posix.sep);

module.exports = async ({ config: { rootDir }, testPath }) => {
const testFileContents = readFileSync(testPath, 'utf8');

const testFile = relative(rootDir, testPath);
const typingsFile = resolveTypingsFile(testFile, testFileContents);

module.exports = async ({ testPath }) => {
const start = Date.now();

const { diagnostics, numTests } = await tsd.default({
cwd: rootDir,
testFiles: [normalizeSlashes(testFile)],
typingsFile,
});
const { assertionCount, diagnostics } = tsdLite.default(testPath);

const end = Date.now();

const numFailed = diagnostics.length;
const numPassed = numTests - numFailed;
const numPassed = assertionCount - numFailed;

if (diagnostics.length > 0) {
const errorMessage = formatErrorMessage(diagnostics, testFileContents);
const errorMessage = formatErrorMessage(diagnostics);

return fail({
start,
end,
test: { path: testFile, title: TEST_TITLE },
test: { path: testPath, title: TEST_TITLE },
numFailed,
numPassed,
errorMessage,
Expand All @@ -67,6 +32,6 @@ module.exports = async ({ config: { rootDir }, testPath }) => {
start,
end,
numPassed,
test: { path: testFile, title: TEST_TITLE },
test: { path: testPath, title: TEST_TITLE },
});
};