-
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Tommy <[email protected]>
- Loading branch information
1 parent
621aad9
commit 8387d9e
Showing
15 changed files
with
289 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
import makeDiagnostic from './make-diagnostic'; | ||
import makeDiagnosticWithDiff from './make-diagnostic-with-diff'; | ||
import getJSONPropertyPosition from './get-json-property-position'; | ||
import * as tsutils from './typescript'; | ||
|
||
export { | ||
getJSONPropertyPosition, | ||
makeDiagnostic, | ||
makeDiagnosticWithDiff, | ||
tsutils | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import {Node, Type, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; | ||
import {Diagnostic} from '../interfaces'; | ||
|
||
interface DiagnosticWithDiffOptions { | ||
checker: TypeChecker; | ||
node: Node; | ||
message: string; | ||
expectedType: Type | string; | ||
receivedType: Type | string; | ||
severity?: Diagnostic['severity']; | ||
} | ||
|
||
const typeToStringFormatFlags = | ||
TypeFormatFlags.NoTruncation | | ||
TypeFormatFlags.WriteArrayAsGenericType | | ||
TypeFormatFlags.UseStructuralFallback | | ||
TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | | ||
TypeFormatFlags.NoTypeReduction | | ||
TypeFormatFlags.AllowUniqueESSymbolType | | ||
TypeFormatFlags.InArrayType | | ||
TypeFormatFlags.InElementType | | ||
TypeFormatFlags.InFirstTypeArgument | | ||
TypeFormatFlags.InTypeAlias; | ||
|
||
/** | ||
* Create a diagnostic with type error diffs from the given `options`, see {@link DiagnosticWithDiffOptions}. | ||
* | ||
* @param options - Options for creating the diagnostic. | ||
* @returns Diagnostic with diffs | ||
*/ | ||
export default (options: DiagnosticWithDiffOptions): Diagnostic => { | ||
const {checker, node, expectedType, receivedType} = options; | ||
const position = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); | ||
const message = options.message | ||
.replace('{expectedType}', typeof expectedType === 'string' ? expectedType : checker.typeToString(expectedType)) | ||
.replace('{receivedType}', typeof receivedType === 'string' ? receivedType : checker.typeToString(receivedType)); | ||
|
||
return { | ||
fileName: node.getSourceFile().fileName, | ||
message, | ||
severity: options.severity ?? 'error', | ||
line: position.line + 1, | ||
column: position.character, | ||
diff: { | ||
expected: typeof expectedType === 'string' ? expectedType : checker.typeToString(expectedType, node, typeToStringFormatFlags), | ||
received: typeof receivedType === 'string' ? receivedType : checker.typeToString(receivedType, node, typeToStringFormatFlags) | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import {verifyWithDiff} from './fixtures/utils'; | ||
import execa, {ExecaError} from 'execa'; | ||
import path from 'path'; | ||
import test from 'ava'; | ||
import tsd from '..'; | ||
|
||
test('diff', async t => { | ||
const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/diff')}); | ||
|
||
verifyWithDiff(t, diagnostics, [ | ||
[8, 0, 'error', 'Parameter type `{ life?: number | undefined; }` is declared too wide for argument type `{ life: number; }`.', { | ||
expected: '{ life?: number | undefined; }', | ||
received: '{ life: number; }', | ||
}], | ||
[9, 0, 'error', 'Parameter type `FooFunction` is not identical to argument type `() => number`.', { | ||
expected: '(x?: string | undefined) => number', | ||
received: '() => number', | ||
}], | ||
[10, 0, 'error', 'Parameter type `FooType` is declared too wide for argument type `Required<FooType>`.', { | ||
expected: '{ foo?: "foo" | undefined; }', | ||
received: '{ foo: "foo"; }', | ||
}], | ||
[11, 0, 'error', 'Parameter type `Partial<FooInterface>` is declared too wide for argument type `Required<FooInterface>`.', { | ||
expected: '{ [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', | ||
received: '{ [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', | ||
}], | ||
[13, 0, 'error', 'Argument of type `{ life: number; }` is assignable to parameter of type `{ life?: number | undefined; }`.', { | ||
expected: '{ life?: number | undefined; }', | ||
received: '{ life: number; }', | ||
}], | ||
[18, 0, 'error', 'Documentation comment `This is a comment.` for expression `commented` does not include expected `This is not the same comment!`.', { | ||
expected: 'This is not the same comment!', | ||
received: 'This is a comment.', | ||
}] | ||
]); | ||
}); | ||
|
||
test('diff cli', async t => { | ||
const file = path.join(__dirname, 'fixtures/diff'); | ||
|
||
const {exitCode, stderr} = await t.throwsAsync<ExecaError>(execa('dist/cli.js', [file, '--show-diff'])); | ||
|
||
t.is(exitCode, 1); | ||
|
||
const expectedLines = [ | ||
'✖ 8:0 Parameter type { life?: number | undefined; } is declared too wide for argument type { life: number; }.', | ||
'', | ||
'- { life?: number | undefined; }', | ||
'+ { life: number; }', | ||
'✖ 9:0 Parameter type FooFunction is not identical to argument type () => number.', | ||
'', | ||
'- (x?: string | undefined) => number', | ||
'+ () => number', | ||
'✖ 10:0 Parameter type FooType is declared too wide for argument type Required<FooType>.', | ||
'', | ||
'- { foo?: "foo" | undefined; }', | ||
'+ { foo: "foo"; }', | ||
'✖ 11:0 Parameter type Partial<FooInterface> is declared too wide for argument type Required<FooInterface>.', | ||
'', | ||
'- { [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', | ||
'+ { [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', | ||
'✖ 13:0 Argument of type { life: number; } is assignable to parameter of type { life?: number | undefined; }.', | ||
'', | ||
'- { life?: number | undefined; }', | ||
'+ { life: number; }', | ||
'✖ 18:0 Documentation comment This is a comment. for expression commented does not include expected This is not the same comment!.', | ||
'', | ||
'- This is not the same comment!', | ||
'+ This is a comment.', | ||
'', | ||
'6 errors' | ||
]; | ||
|
||
// NOTE: If lines are added to the output in the future startLine and endLine should be adjusted. | ||
const startLine = 2; // Skip tsd error message and file location. | ||
const endLine = startLine + expectedLines.length; // Grab diff output only and skip stack trace. | ||
|
||
const receivedLines = stderr.trim().split('\n').slice(startLine, endLine).map(line => line.trim()); | ||
|
||
t.deepEqual(receivedLines, expectedLines); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export type FooType = {foo?: 'foo'}; | ||
|
||
export interface FooInterface { | ||
[x: string]: unknown; | ||
readonly protected: boolean; | ||
fooType?: FooType; | ||
id: 'foo-interface'; | ||
} | ||
|
||
export type FooFunction = (x?: string) => number; | ||
|
||
declare const foo: <T>(foo: T) => T; | ||
|
||
export default foo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports.default = (foo) => { | ||
return foo; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {expectDocCommentIncludes, expectNotAssignable, expectType} from '../../..'; | ||
import foo, { FooFunction, FooInterface, FooType } from '.'; | ||
|
||
// Should pass | ||
expectType<{life: number}>(foo({life: 42})); | ||
|
||
// Should fail | ||
expectType<{life?: number}>(foo({life: 42})); | ||
expectType<FooFunction>(() => 42); | ||
expectType<FooType>({} as Required<FooType>); | ||
expectType<Partial<FooInterface>>({} as Required<FooInterface>); | ||
|
||
expectNotAssignable<{life?: number}>(foo({life: 42})); | ||
|
||
/** This is a comment. */ | ||
const commented = 42; | ||
|
||
expectDocCommentIncludes<'This is not the same comment!'>(commented); |
Oops, something went wrong.