Skip to content

Commit 4bf47fe

Browse files
author
Andy Hanson
committed
Restore fourslash tests
1 parent 8b7dacf commit 4bf47fe

19 files changed

+546
-16
lines changed

src/harness/client.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ namespace ts.server {
7373
return { span: this.decodeSpan(codeEdit, fileName), newText: codeEdit.newText };
7474
}
7575

76-
private processRequest<T extends protocol.Request>(command: string, args?: T["arguments"]): T {
76+
private processRequest<T extends protocol.Request>(command: string, args: T["arguments"]): T {
7777
const request: protocol.Request = {
7878
seq: this.sequence,
7979
type: "request",
@@ -278,17 +278,18 @@ namespace ts.server {
278278

279279
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.DefinitionAndBoundSpan, args);
280280
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
281+
const body = Debug.assertDefined(response.body); // TODO: GH#18217
281282

282283
return {
283-
definitions: response.body!.definitions.map(entry => ({ // TODO: GH#18217
284+
definitions: body.definitions.map(entry => ({
284285
containerKind: ScriptElementKind.unknown,
285286
containerName: "",
286287
fileName: entry.file,
287288
textSpan: this.decodeSpan(entry),
288289
kind: ScriptElementKind.unknown,
289290
name: ""
290291
})),
291-
textSpan: this.decodeSpan(response.body!.textSpan, request.arguments.file)
292+
textSpan: this.decodeSpan(body.textSpan, request.arguments.file)
292293
};
293294
}
294295

@@ -341,8 +342,10 @@ namespace ts.server {
341342
}));
342343
}
343344

344-
getEmitOutput(_fileName: string): EmitOutput {
345-
return notImplemented();
345+
getEmitOutput(file: string): EmitOutput {
346+
const request = this.processRequest<protocol.EmitOutputRequest>(protocol.CommandTypes.EmitOutput, { file });
347+
const response = this.processResponse<protocol.EmitOutputResponse>(request);
348+
return response.body;
346349
}
347350

348351
getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] {

src/harness/fourslash.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ Actual: ${stringify(fullActual)}`);
16391639
});
16401640
}
16411641

1642-
public baselineGetEmitOutput(insertResultsIntoVfs?: boolean) {
1642+
private getEmitFiles(): ReadonlyArray<FourSlashFile> {
16431643
// Find file to be emitted
16441644
const emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on
16451645

@@ -1656,12 +1656,31 @@ Actual: ${stringify(fullActual)}`);
16561656
this.raiseError("No emitThisFile is specified in the test file");
16571657
}
16581658

1659+
return emitFiles;
1660+
}
1661+
1662+
public verifyGetEmitOutput(expectedOutputFiles: ReadonlyArray<string>): void {
1663+
const outputFiles = ts.flatMap(this.getEmitFiles(), e => this.languageService.getEmitOutput(e.fileName).outputFiles);
1664+
1665+
assert.deepEqual(outputFiles.map(f => f.name), expectedOutputFiles);
1666+
1667+
for (const { name, text } of outputFiles) {
1668+
const fromTestFile = this.getFileContent(name);
1669+
if (fromTestFile !== text) {
1670+
this.raiseError("Emit output is not as expected: " + showTextDiff(fromTestFile, text));
1671+
}
1672+
}
1673+
}
1674+
1675+
public baselineGetEmitOutput(insertResultsIntoVfs?: boolean) {
1676+
ts.Debug.assert(this.testType !== FourSlashTestType.Server, "Use verifyGetEmitOutput -- insertResultIntoVfs doesn't work with server");
1677+
16591678
Harness.Baseline.runBaseline(
1660-
this.testData.globalOptions[MetadataOptionNames.baselineFile],
1679+
ts.Debug.assertDefined(this.testData.globalOptions[MetadataOptionNames.baselineFile]),
16611680
() => {
16621681
let resultString = "";
16631682
// Loop through all the emittedFiles and emit them one by one
1664-
emitFiles.forEach(emitFile => {
1683+
for (const emitFile of this.getEmitFiles()) {
16651684
const emitOutput = this.languageService.getEmitOutput(emitFile.fileName);
16661685
// Print emitOutputStatus in readable format
16671686
resultString += "EmitSkipped: " + emitOutput.emitSkipped + Harness.IO.newLine();
@@ -1687,13 +1706,13 @@ Actual: ${stringify(fullActual)}`);
16871706

16881707
for (const outputFile of emitOutput.outputFiles) {
16891708
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
1690-
resultString = resultString + fileName + outputFile.text;
1709+
resultString = resultString + Harness.IO.newLine() + fileName + outputFile.text;
16911710
if (insertResultsIntoVfs) {
16921711
this.languageServiceAdapterHost.addScript(ts.getNormalizedAbsolutePath(outputFile.name, "/"), outputFile.text, /*isRootFile*/ true);
16931712
}
16941713
}
16951714
resultString += Harness.IO.newLine();
1696-
});
1715+
}
16971716

16981717
return resultString;
16991718
});
@@ -3567,8 +3586,13 @@ ${code}
35673586

35683587
function getNonFileNameOptionInObject(optionObject: { [s: string]: string }): string | undefined {
35693588
for (const option in optionObject) {
3570-
if (option !== MetadataOptionNames.fileName) {
3571-
return option;
3589+
switch (option) {
3590+
case MetadataOptionNames.fileName:
3591+
case MetadataOptionNames.baselineFile:
3592+
case MetadataOptionNames.emitThisFile:
3593+
break;
3594+
default:
3595+
return option;
35723596
}
35733597
}
35743598
return undefined;
@@ -4278,6 +4302,10 @@ namespace FourSlashInterface {
42784302
this.state.baselineCurrentFileNameOrDottedNameSpans();
42794303
}
42804304

4305+
public getEmitOutput(expectedOutputFiles: ReadonlyArray<string>): void {
4306+
this.state.verifyGetEmitOutput(expectedOutputFiles);
4307+
}
4308+
42814309
public baselineGetEmitOutput(insertResultsIntoVfs?: boolean) {
42824310
this.state.baselineGetEmitOutput(insertResultsIntoVfs);
42834311
}

src/harness/harnessLanguageService.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ namespace Harness.LanguageService {
180180

181181
public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void { /*overridden*/ }
182182

183+
183184
/**
184185
* @param line 0 based index
185186
* @param col 0 based index
@@ -707,7 +708,9 @@ namespace Harness.LanguageService {
707708
return ts.sys.getEnvironmentVariable(name);
708709
}
709710

710-
readDirectory() { return ts.notImplemented(); }
711+
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
712+
return this.host.readDirectory(path, extensions, exclude, include, depth);
713+
}
711714

712715
watchFile(): ts.FileWatcher {
713716
return { close: ts.noop };

src/server/protocol.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ namespace ts.server.protocol {
3434
Implementation = "implementation",
3535
/* @internal */
3636
ImplementationFull = "implementation-full",
37+
/* @internal */
38+
EmitOutput = "emit-output",
3739
Exit = "exit",
3840
Format = "format",
3941
Formatonkey = "formatonkey",
@@ -802,6 +804,13 @@ namespace ts.server.protocol {
802804
readonly body: DefinitionInfoAndBoundSpan;
803805
}
804806

807+
/** @internal */
808+
export interface EmitOutputRequest extends FileRequest {}
809+
/** @internal */
810+
export interface EmitOutputResponse extends Response {
811+
readonly body: EmitOutput;
812+
}
813+
805814
/**
806815
* Go to type request; value of command field is
807816
* "typeDefinition". Return response giving the file locations that

src/server/session.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ namespace ts.server {
781781
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
782782
const { file, project } = this.getFileAndProject(args);
783783
const position = this.getPositionInFile(args, file);
784-
const scriptInfo = project.getScriptInfo(file)!;
784+
const scriptInfo = Debug.assertDefined(project.getScriptInfo(file));
785785

786786
const unmappedDefinitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
787787

@@ -808,6 +808,11 @@ namespace ts.server {
808808
};
809809
}
810810

811+
private getEmitOutput(args: protocol.FileRequestArgs): EmitOutput {
812+
const { file, project } = this.getFileAndProject(args);
813+
return project.getLanguageService().getEmitOutput(file);
814+
}
815+
811816
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpan> {
812817
return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project));
813818
}
@@ -1998,6 +2003,9 @@ namespace ts.server {
19982003
[CommandNames.DefinitionAndBoundSpanFull]: (request: protocol.DefinitionRequest) => {
19992004
return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false));
20002005
},
2006+
[CommandNames.EmitOutput]: (request: protocol.EmitOutputRequest) => {
2007+
return this.requiredResponse(this.getEmitOutput(request.arguments));
2008+
},
20012009
[CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => {
20022010
return this.requiredResponse(this.getTypeDefinition(request.arguments));
20032011
},

src/services/sourcemaps.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @internal */
22
namespace ts {
33
// Sometimes tools can sometimes see the following line as a source mapping url comment, so we mangle it a bit (the [M])
4-
const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)$/;
4+
const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\s*$/;
55
const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
66
const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/;
77

@@ -60,7 +60,7 @@ namespace ts {
6060
}, mapFileName, maps, getProgram(), sourcemappedFileCache);
6161
}
6262

63-
function getSourceMapper(fileName: string, file: { sourceMapper?: sourcemaps.SourceMapper }) {
63+
function getSourceMapper(fileName: string, file: SourceFileLike): sourcemaps.SourceMapper {
6464
if (!host.readFile || !host.fileExists) {
6565
return file.sourceMapper = sourcemaps.identitySourceMapper;
6666
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10871,6 +10871,8 @@ declare namespace ts {
1087110871
function getParentNodeInSpan(node: Node | undefined, file: SourceFile, span: TextSpan): Node | undefined;
1087210872
function findModifier(node: Node, kind: Modifier["kind"]): Modifier | undefined;
1087310873
function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement): void;
10874+
function textSpansEqual(a: TextSpan | undefined, b: TextSpan | undefined): boolean;
10875+
function documentSpansEqual(a: DocumentSpan, b: DocumentSpan): boolean;
1087410876
}
1087510877
declare namespace ts {
1087610878
function isFirstDeclarationOfSymbolParameter(symbol: Symbol): boolean;
@@ -12289,6 +12291,7 @@ declare namespace ts.server.protocol {
1228912291
DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full",
1229012292
Implementation = "implementation",
1229112293
ImplementationFull = "implementation-full",
12294+
EmitOutput = "emit-output",
1229212295
Exit = "exit",
1229312296
Format = "format",
1229412297
Formatonkey = "formatonkey",
@@ -12617,6 +12620,11 @@ declare namespace ts.server.protocol {
1261712620
interface DefinitionAndBoundSpanResponse extends Response {
1261812621
readonly body: DefinitionInfoAndBoundSpan;
1261912622
}
12623+
interface EmitOutputRequest extends FileRequest {
12624+
}
12625+
interface EmitOutputResponse extends Response {
12626+
readonly body: EmitOutput;
12627+
}
1262012628
interface TypeDefinitionRequest extends FileLocationRequest {
1262112629
command: CommandTypes.TypeDefinition;
1262212630
}
@@ -14097,6 +14105,7 @@ declare namespace ts.server {
1409714105
private getDefinition;
1409814106
private mapDefinitionInfoLocations;
1409914107
private getDefinitionAndBoundSpan;
14108+
private getEmitOutput;
1410014109
private mapDefinitionInfo;
1410114110
private static mapToOriginalLocation;
1410214111
private toFileSpan;

tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
EmitSkipped: false
2+
23
FileName : /tests/cases/fourslash/inputFile1.js
34
var x = 5;
45
var Bar = /** @class */ (function () {
56
function Bar() {
67
}
78
return Bar;
89
}());
10+
911
FileName : /tests/cases/fourslash/inputFile1.d.ts
1012
declare var x: number;
1113
declare class Bar {
@@ -14,13 +16,15 @@ declare class Bar {
1416
}
1517

1618
EmitSkipped: false
19+
1720
FileName : /tests/cases/fourslash/inputFile2.js
1821
var x1 = "hello world";
1922
var Foo = /** @class */ (function () {
2023
function Foo() {
2124
}
2225
return Foo;
2326
}());
27+
2428
FileName : /tests/cases/fourslash/inputFile2.d.ts
2529
declare var x1: string;
2630
declare class Foo {

tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
EmitSkipped: false
2+
23
FileName : declSingleFile.js
34
var x = 5;
45
var Bar = /** @class */ (function () {
@@ -12,6 +13,7 @@ var Foo = /** @class */ (function () {
1213
}
1314
return Foo;
1415
}());
16+
1517
FileName : declSingleFile.d.ts
1618
declare var x: number;
1719
declare class Bar {

tests/baselines/reference/getEmitOutputWithDeclarationFile.baseline

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
EmitSkipped: false
22

33
EmitSkipped: false
4+
45
FileName : /tests/cases/fourslash/inputFile2.js
56
var x1 = "hello world";
67
var Foo = /** @class */ (function () {

0 commit comments

Comments
 (0)