-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add assignability expectations - fixes #39
- Loading branch information
1 parent
206573b
commit 3a375fa
Showing
16 changed files
with
179 additions
and
34 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import {CallExpression} from '../../../../libraries/typescript/lib/typescript'; | ||
import {TypeChecker} from '../../entities/typescript'; | ||
import {Diagnostic} from '../../interfaces'; | ||
import {makeDiagnostic} from '../../utils'; | ||
|
||
/** | ||
* Verifies that the argument of the assertion is not assignable to the generic type of the assertion. | ||
* | ||
* @param checker - The TypeScript type checker. | ||
* @param nodes - The `expectType` AST nodes. | ||
* @return List of custom diagnostics. | ||
*/ | ||
export const isNotAssignable = (checker: TypeChecker, nodes: Set<CallExpression>): Diagnostic[] => { | ||
const diagnostics: Diagnostic[] = []; | ||
|
||
if (!nodes) { | ||
return diagnostics; | ||
} | ||
|
||
for (const node of nodes) { | ||
if (!node.typeArguments) { | ||
// Skip if the node does not have generics | ||
continue; | ||
} | ||
|
||
// Retrieve the type to be expected. This is the type inside the generic. | ||
const expectedType = checker.getTypeFromTypeNode(node.typeArguments[0]); | ||
const argumentType = checker.getTypeAtLocation(node.arguments[0]); | ||
|
||
if (checker.isTypeAssignableTo(argumentType, expectedType)) { | ||
/** | ||
* The argument type is assignable to the expected type, we don't want this so add a diagnostic. | ||
*/ | ||
diagnostics.push(makeDiagnostic(node, `Argument of type \`${checker.typeToString(argumentType)}\` is assignable to parameter of type \`${checker.typeToString(expectedType)}\`.`)); | ||
} | ||
} | ||
|
||
return diagnostics; | ||
}; |
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 |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import * as path from 'path'; | ||
import test from 'ava'; | ||
import {verify} from './fixtures/utils'; | ||
import tsd from '..'; | ||
|
||
test('assignable', async t => { | ||
const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/assignability/assignable')}); | ||
|
||
verify(t, diagnostics, [ | ||
[8, 26, 'error', 'Argument of type \'string\' is not assignable to parameter of type \'boolean\'.'] | ||
]); | ||
}); | ||
|
||
test('not assignable', async t => { | ||
const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/assignability/not-assignable')}); | ||
|
||
verify(t, diagnostics, [ | ||
[4, 0, 'error', 'Argument of type `string` is assignable to parameter of type `string | number`.'], | ||
[5, 0, 'error', 'Argument of type `string` is assignable to parameter of type `any`.'], | ||
]); | ||
}); |
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,6 @@ | ||
declare const concat: { | ||
(foo: string, bar: string): string; | ||
(foo: number, bar: number): number; | ||
}; | ||
|
||
export default concat; |
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, bar) => { | ||
return foo + bar; | ||
}; |
8 changes: 8 additions & 0 deletions
8
source/test/fixtures/assignability/assignable/index.test-d.ts
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,8 @@ | ||
import {expectAssignable} from '../../../..'; | ||
import concat from '.'; | ||
|
||
expectAssignable<string | number>(concat('foo', 'bar')); | ||
expectAssignable<string | number>(concat(1, 2)); | ||
expectAssignable<any>(concat(1, 2)); | ||
|
||
expectAssignable<boolean>(concat('unicorn', 'rainbow')); |
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 @@ | ||
{ | ||
"name": "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,6 @@ | ||
declare const concat: { | ||
(foo: string, bar: string): string; | ||
(foo: number, bar: number): number; | ||
}; | ||
|
||
export default concat; |
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, bar) => { | ||
return foo + bar; | ||
}; |
8 changes: 8 additions & 0 deletions
8
source/test/fixtures/assignability/not-assignable/index.test-d.ts
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,8 @@ | ||
import {expectNotAssignable} from '../../../..'; | ||
import concat from '.'; | ||
|
||
expectNotAssignable<string | number>(concat('foo', 'bar')); | ||
expectNotAssignable<any>(concat('foo', 'bar')); | ||
|
||
expectNotAssignable<boolean>(concat('unicorn', 'rainbow')); | ||
expectNotAssignable<symbol>(concat('unicorn', 'rainbow')); |
3 changes: 3 additions & 0 deletions
3
source/test/fixtures/assignability/not-assignable/package.json
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 @@ | ||
{ | ||
"name": "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,30 @@ | ||
import {ExecutionContext} from 'ava'; | ||
import {Diagnostic} from '../../lib/interfaces'; | ||
|
||
type Expectation = [number, number, 'error' | 'warning', string, (string | RegExp)?]; | ||
|
||
/** | ||
* Verify a list of diagnostics. | ||
* | ||
* @param t - The AVA execution context. | ||
* @param diagnostics - List of diagnostics to verify. | ||
* @param expectations - Expected diagnostics. | ||
*/ | ||
export const verify = (t: ExecutionContext, diagnostics: Diagnostic[], expectations: Expectation[]) => { | ||
t.true(diagnostics.length === expectations.length); | ||
|
||
for (const [index, diagnostic] of diagnostics.entries()) { | ||
t.is(diagnostic.line, expectations[index][0]); | ||
t.is(diagnostic.column, expectations[index][1]); | ||
t.is(diagnostic.severity, expectations[index][2]); | ||
t.is(diagnostic.message, expectations[index][3]); | ||
|
||
const filename = expectations[index][4]; | ||
|
||
if (typeof filename === 'string') { | ||
t.is(diagnostic.fileName, filename); | ||
} else if (typeof filename === 'object') { | ||
t.regex(diagnostic.fileName, filename); | ||
} | ||
} | ||
}; |
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