import { flattenDiagnosticMessageText , createProgram , Diagnostic as TSDiagnostic } from '@tsd/typescript' ; import { ExpectedError , extractAssertions , parseErrorAssertionToLocation } from './parser' ; import { Diagnostic , DiagnosticCode , Context , Location } from './interfaces' ; import { handle } from './assertions' ; const ignoredDiagnostics = new Set < number > ( [ DiagnosticCode . AwaitExpressionOnlyAllowedWithinAsyncFunction , DiagnosticCode . TopLevelAwaitOnlyAllowedWhenModuleESNextOrSystem ] ) ; const expectErrordiagnosticCodesToIgnore = new Set < DiagnosticCode > ( [ DiagnosticCode . ArgumentTypeIsNotAssignableToParameterType , DiagnosticCode . PropertyDoesNotExistOnType , DiagnosticCode . CannotAssignToReadOnlyProperty , DiagnosticCode . TypeIsNotAssignableToOtherType , DiagnosticCode . TypeDoesNotSatisfyTheConstraint , DiagnosticCode . GenericTypeRequiresTypeArguments , DiagnosticCode . ExpectedArgumentsButGotOther , DiagnosticCode . ExpectedAtLeastArgumentsButGotOther , DiagnosticCode . NoOverloadExpectsCountOfArguments , DiagnosticCode . NoOverloadExpectsCountOfTypeArguments , DiagnosticCode . NoOverloadMatches , DiagnosticCode . PropertyMissingInType1ButRequiredInType2 , DiagnosticCode . TypeHasNoPropertiesInCommonWith , DiagnosticCode . ThisContextOfTypeNotAssignableToMethodOfThisType , DiagnosticCode . ValueOfTypeNotCallable , DiagnosticCode . ExpressionNotCallable , DiagnosticCode . OnlyVoidFunctionIsNewCallable , DiagnosticCode . ExpressionNotConstructable , DiagnosticCode . NewExpressionTargetLackingConstructSignatureHasAnyType , DiagnosticCode . MemberCannotHaveOverrideModifierBecauseItIsNotDeclaredInBaseClass , DiagnosticCode . MemberMustHaveOverrideModifier , DiagnosticCode . StringLiteralTypeIsNotAssignableToUnionTypeWithSuggestion , ] ) ; type IgnoreDiagnosticResult = 'preserve' | 'ignore' | Location ; param diagnostic param expectedErrors returns const ignoreDiagnostic = ( diagnostic , expectedErrors ) : IgnoreDiagnosticResult => { if ( ignoredDiagnostics . has ( diagnostic . code ) ) { return 'ignore' ; } if ( ! expectErrordiagnosticCodesToIgnore . has ( diagnostic . code ) ) { return 'preserve' ; } const diagnosticFileName = diagnostic . file ! . fileName ; for ( const [ location ] of expectedErrors ) { const start = diagnostic . start ! ; if ( diagnosticFileName === location . fileName && start > location . start && start < location . end ) { return location ; } } return 'preserve' ; } ; param context returns export const getDiagnostics = ( context ) : Diagnostic [ ] => { const diagnostics = [ ] ; const program = createProgram ( context . testFiles , context . config . compilerOptions ) ; const tsDiagnostics = program . getSemanticDiagnostics ( ) . concat ( program . getSyntacticDiagnostics ( ) ) ; const assertions = extractAssertions ( program ) ; diagnostics . push ( ... handle ( program . getTypeChecker ( ) , assertions ) ) ; const expectedErrors = parseErrorAssertionToLocation ( assertions ) ; const expectedErrorsLocationsWithFoundDiagnostics = [ ] ; for ( const diagnostic of tsDiagnostics ) { if ( ! diagnostic . file || /[/\\]node_modules[/\\]/ . test ( diagnostic . file . fileName ) ) { continue ; } const ignoreDiagnosticResult = ignoreDiagnostic ( diagnostic , expectedErrors ) ; if ( ignoreDiagnosticResult !== 'preserve' ) { if ( ignoreDiagnosticResult !== 'ignore' ) { expectedErrorsLocationsWithFoundDiagnostics . push ( ignoreDiagnosticResult ) ; } continue ; } const position = diagnostic . file . getLineAndCharacterOfPosition ( diagnostic . start ! ) ; diagnostics . push ( { fileName : diagnostic . file . fileName , message : flattenDiagnosticMessageText ( diagnostic . messageText , '\n' ) , severity : 'error' , line : position . line + 1 , column : position . character } ) ; } for ( const errorLocationToRemove of expectedErrorsLocationsWithFoundDiagnostics ) { expectedErrors . delete ( errorLocationToRemove ) ; } for ( const [ , diagnostic ] of expectedErrors ) { diagnostics . push ( { ... diagnostic , message : 'Expected an error, but found none.' , severity : 'error' } ) ; } return diagnostics ; } ;