mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-22 12:03:44 -05:00
@@ -282,6 +282,8 @@ module FourSlash {
|
||||
return new Harness.LanguageService.NativeLanugageServiceAdapter(cancellationToken, compilationOptions);
|
||||
case FourSlashTestType.Shims:
|
||||
return new Harness.LanguageService.ShimLanugageServiceAdapter(cancellationToken, compilationOptions);
|
||||
case FourSlashTestType.Server:
|
||||
return new Harness.LanguageService.ServerLanugageServiceAdapter(cancellationToken, compilationOptions);
|
||||
default:
|
||||
throw new Error("Unknown FourSlash test type: ");
|
||||
}
|
||||
@@ -418,6 +420,9 @@ module FourSlash {
|
||||
this.activeFile = fileToOpen;
|
||||
var fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1);
|
||||
this.scenarioActions.push('<OpenFile FileName="" SrcFileId="' + fileName + '" FileId="' + fileName + '" />');
|
||||
|
||||
// Let the host know that this file is now open
|
||||
this.languageServiceAdapterHost.openFile(fileToOpen.fileName);
|
||||
}
|
||||
|
||||
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
|
||||
@@ -1927,7 +1932,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
var missingItem = { name: name, kind: kind };
|
||||
this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')');
|
||||
this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items, null, " ") + ')');
|
||||
}
|
||||
|
||||
private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
const enum FourSlashTestType {
|
||||
Native,
|
||||
Shims
|
||||
Shims,
|
||||
Server
|
||||
}
|
||||
|
||||
class FourSlashRunner extends RunnerBase {
|
||||
@@ -22,6 +23,10 @@ class FourSlashRunner extends RunnerBase {
|
||||
this.basePath = 'tests/cases/fourslash/shims';
|
||||
this.testSuiteName = 'fourslash-shims';
|
||||
break;
|
||||
case FourSlashTestType.Server:
|
||||
this.basePath = 'tests/cases/fourslash/server';
|
||||
this.testSuiteName = 'fourslash-server';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='..\server\session.ts' />
|
||||
/// <reference path='..\server\client.ts' />
|
||||
/// <reference path='..\server\node.d.ts' />
|
||||
/// <reference path='external\mocha.d.ts'/>
|
||||
/// <reference path='external\chai.d.ts'/>
|
||||
/// <reference path='sourceMapRecorder.ts'/>
|
||||
/// <reference path='runnerbase.ts'/>
|
||||
|
||||
declare var require: any;
|
||||
declare var process: any;
|
||||
var Buffer = require('buffer').Buffer;
|
||||
var Buffer: BufferConstructor = require('buffer').Buffer;
|
||||
|
||||
// this will work in the browser via browserify
|
||||
var _chai: typeof chai = require('chai');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='..\server\client.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
|
||||
module Harness.LanguageService {
|
||||
@@ -23,18 +24,18 @@ module Harness.LanguageService {
|
||||
this.version++;
|
||||
}
|
||||
|
||||
public editContent(minChar: number, limChar: number, newText: string): void {
|
||||
public editContent(start: number, end: number, newText: string): void {
|
||||
// Apply edits
|
||||
var prefix = this.content.substring(0, minChar);
|
||||
var prefix = this.content.substring(0, start);
|
||||
var middle = newText;
|
||||
var suffix = this.content.substring(limChar);
|
||||
var suffix = this.content.substring(end);
|
||||
this.setContent(prefix + middle + suffix);
|
||||
|
||||
// Store edit range + new length of script
|
||||
this.editRanges.push({
|
||||
length: this.content.length,
|
||||
textChangeRange: ts.createTextChangeRange(
|
||||
ts.createTextSpanFromBounds(minChar, limChar), newText.length)
|
||||
ts.createTextSpanFromBounds(start, end), newText.length)
|
||||
});
|
||||
|
||||
// Update version #
|
||||
@@ -145,26 +146,19 @@ module Harness.LanguageService {
|
||||
this.fileNameToScript[fileName] = new ScriptInfo(fileName, content);
|
||||
}
|
||||
|
||||
public updateScript(fileName: string, content: string) {
|
||||
public editScript(fileName: string, start: number, end: number, newText: string) {
|
||||
var script = this.getScriptInfo(fileName);
|
||||
if (script !== null) {
|
||||
script.updateContent(content);
|
||||
return;
|
||||
}
|
||||
|
||||
this.addScript(fileName, content);
|
||||
}
|
||||
|
||||
public editScript(fileName: string, minChar: number, limChar: number, newText: string) {
|
||||
var script = this.getScriptInfo(fileName);
|
||||
if (script !== null) {
|
||||
script.editContent(minChar, limChar, newText);
|
||||
script.editContent(start, end, newText);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error("No script with name '" + fileName + "'");
|
||||
}
|
||||
|
||||
public openFile(fileName: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param line 1 based index
|
||||
* @param col 1 based index
|
||||
@@ -236,8 +230,7 @@ module Harness.LanguageService {
|
||||
getFilenames(): string[] { return this.nativeHost.getFilenames(); }
|
||||
getScriptInfo(fileName: string): ScriptInfo { return this.nativeHost.getScriptInfo(fileName); }
|
||||
addScript(fileName: string, content: string): void { this.nativeHost.addScript(fileName, content); }
|
||||
updateScript(fileName: string, content: string): void { return this.nativeHost.updateScript(fileName, content); }
|
||||
editScript(fileName: string, minChar: number, limChar: number, newText: string): void { this.nativeHost.editScript(fileName, minChar, limChar, newText); }
|
||||
editScript(fileName: string, start: number, end: number, newText: string): void { this.nativeHost.editScript(fileName, start, end, newText); }
|
||||
lineColToPosition(fileName: string, line: number, col: number): number { return this.nativeHost.lineColToPosition(fileName, line, col); }
|
||||
positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter { return this.nativeHost.positionToZeroBasedLineCol(fileName, position); }
|
||||
|
||||
@@ -442,5 +435,156 @@ module Harness.LanguageService {
|
||||
return convertResult;
|
||||
}
|
||||
}
|
||||
|
||||
// Server adapter
|
||||
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
|
||||
private client: ts.server.SessionClient;
|
||||
|
||||
constructor(cancellationToken: ts.CancellationToken, settings: ts.CompilerOptions) {
|
||||
super(cancellationToken, settings);
|
||||
}
|
||||
|
||||
onMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
setClient(client: ts.server.SessionClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
openFile(fileName: string): void {
|
||||
super.openFile(fileName);
|
||||
this.client.openFile(fileName);
|
||||
}
|
||||
|
||||
editScript(fileName: string, start: number, end: number, newText: string) {
|
||||
super.editScript(fileName, start, end, newText);
|
||||
this.client.changeFile(fileName, start, end, newText);
|
||||
}
|
||||
}
|
||||
|
||||
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
|
||||
args: string[] = [];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean = false;
|
||||
|
||||
constructor(private host: NativeLanguageServiceHost) {
|
||||
this.newLine = this.host.getNewLine();
|
||||
}
|
||||
|
||||
onMessage(message: string): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
}
|
||||
|
||||
write(message: string): void {
|
||||
this.writeMessage(message);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
|
||||
fileName = Harness.Compiler.defaultLibFileName;
|
||||
}
|
||||
|
||||
var snapshot = this.host.getScriptSnapshot(fileName);
|
||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
|
||||
writeFile(name: string, text: string, writeByteOrderMark: boolean): void {
|
||||
}
|
||||
|
||||
resolvePath(path: string): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
fileExists(path: string): boolean {
|
||||
return !!this.host.getScriptSnapshot(path);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
getExecutingFilePath(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
exit(exitCode: number): void {
|
||||
}
|
||||
|
||||
createDirectory(directoryName: string): void {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
getCurrentDirectory(): string {
|
||||
return this.host.getCurrentDirectory();
|
||||
}
|
||||
|
||||
readDirectory(path: string, extension?: string): string[] {
|
||||
throw new Error("Not implemented Yet.");
|
||||
}
|
||||
|
||||
watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
|
||||
return { close() { } };
|
||||
}
|
||||
|
||||
close(): void {
|
||||
}
|
||||
|
||||
info(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
msg(message: string) {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
endGroup(): void {
|
||||
}
|
||||
|
||||
perftrc(message: string): void {
|
||||
return this.host.log(message);
|
||||
}
|
||||
|
||||
startGroup(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanugageServiceAdapter implements LanguageServiceAdapter {
|
||||
private host: SessionClientHost;
|
||||
private client: ts.server.SessionClient;
|
||||
constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) {
|
||||
// This is the main host that tests use to direct tests
|
||||
var clientHost = new SessionClientHost(cancellationToken, options);
|
||||
var client = new ts.server.SessionClient(clientHost);
|
||||
|
||||
// This host is just a proxy for the clientHost, it uses the client
|
||||
// host to answer server queries about files on disk
|
||||
var serverHost = new SessionServerHost(clientHost);
|
||||
var server = new ts.server.Session(serverHost, serverHost);
|
||||
|
||||
// Fake the connection between the client and the server
|
||||
serverHost.writeMessage = client.onMessage.bind(client);
|
||||
clientHost.writeMessage = server.onMessage.bind(server);
|
||||
|
||||
// Wire the client to the host to get notifications when a file is open
|
||||
// or edited.
|
||||
clientHost.setClient(client);
|
||||
|
||||
// Set the properties
|
||||
this.client = client;
|
||||
this.host = clientHost;
|
||||
}
|
||||
getHost() { return this.host; }
|
||||
getLanguageService(): ts.LanguageService { return this.client; }
|
||||
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ if (testConfigFile !== '') {
|
||||
case 'fourslash-shims':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case 'fourslash-server':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case 'fourslash-generated':
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
@@ -95,6 +98,7 @@ if (runners.length === 0) {
|
||||
// language services
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
//runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user