mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Merge branch 'master' into forwardRefsInEnumInitializers
This commit is contained in:
22
tests/baselines/reference/aliasesInSystemModule1.errors.txt
Normal file
22
tests/baselines/reference/aliasesInSystemModule1.errors.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
tests/cases/compiler/aliasesInSystemModule1.ts(2,24): error TS2307: Cannot find module 'foo'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/aliasesInSystemModule1.ts (1 errors) ====
|
||||
|
||||
import alias = require('foo');
|
||||
~~~~~
|
||||
!!! error TS2307: Cannot find module 'foo'.
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
|
||||
42
tests/baselines/reference/aliasesInSystemModule1.js
Normal file
42
tests/baselines/reference/aliasesInSystemModule1.js
Normal file
@@ -0,0 +1,42 @@
|
||||
//// [aliasesInSystemModule1.ts]
|
||||
|
||||
import alias = require('foo');
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
|
||||
|
||||
//// [aliasesInSystemModule1.js]
|
||||
System.register(['foo'], function(exports_1) {
|
||||
var alias;
|
||||
var cls, cls2, x, y, z, M;
|
||||
return {
|
||||
setters:[
|
||||
function (_alias) {
|
||||
alias = _alias;
|
||||
}],
|
||||
execute: function() {
|
||||
cls = alias.Class;
|
||||
exports_1("cls2", cls2 = alias.Class);
|
||||
x = new alias.Class();
|
||||
y = new cls();
|
||||
z = new cls2();
|
||||
(function (M) {
|
||||
M.cls = alias.Class;
|
||||
var x = new alias.Class();
|
||||
var y = new M.cls();
|
||||
var z = new cls2();
|
||||
})(M || (M = {}));
|
||||
}
|
||||
}
|
||||
});
|
||||
21
tests/baselines/reference/aliasesInSystemModule2.errors.txt
Normal file
21
tests/baselines/reference/aliasesInSystemModule2.errors.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
tests/cases/compiler/aliasesInSystemModule2.ts(2,21): error TS2307: Cannot find module 'foo'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/aliasesInSystemModule2.ts (1 errors) ====
|
||||
|
||||
import {alias} from "foo";
|
||||
~~~~~
|
||||
!!! error TS2307: Cannot find module 'foo'.
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
41
tests/baselines/reference/aliasesInSystemModule2.js
Normal file
41
tests/baselines/reference/aliasesInSystemModule2.js
Normal file
@@ -0,0 +1,41 @@
|
||||
//// [aliasesInSystemModule2.ts]
|
||||
|
||||
import {alias} from "foo";
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
|
||||
//// [aliasesInSystemModule2.js]
|
||||
System.register(["foo"], function(exports_1) {
|
||||
var foo_1;
|
||||
var cls, cls2, x, y, z, M;
|
||||
return {
|
||||
setters:[
|
||||
function (_foo_1) {
|
||||
foo_1 = _foo_1;
|
||||
}],
|
||||
execute: function() {
|
||||
cls = foo_1.alias.Class;
|
||||
exports_1("cls2", cls2 = foo_1.alias.Class);
|
||||
x = new foo_1.alias.Class();
|
||||
y = new cls();
|
||||
z = new cls2();
|
||||
(function (M) {
|
||||
M.cls = foo_1.alias.Class;
|
||||
var x = new foo_1.alias.Class();
|
||||
var y = new M.cls();
|
||||
var z = new cls2();
|
||||
})(M || (M = {}));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
|
||||
|
||||
|
||||
!!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
|
||||
==== tests/cases/compiler/isolatedModulesSourceMap.ts (0 errors) ====
|
||||
|
||||
export var x;
|
||||
@@ -1,7 +1,7 @@
|
||||
//// [isolatedModulesSourceMap.ts]
|
||||
|
||||
export var x;
|
||||
export var x = 1;
|
||||
|
||||
//// [isolatedModulesSourceMap.js]
|
||||
export var x;
|
||||
export var x = 1;
|
||||
//# sourceMappingURL=isolatedModulesSourceMap.js.map
|
||||
@@ -1,2 +1,2 @@
|
||||
//// [isolatedModulesSourceMap.js.map]
|
||||
{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"}
|
||||
{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,GAAG,CAAC,CAAC"}
|
||||
@@ -8,20 +8,26 @@ sources: isolatedModulesSourceMap.ts
|
||||
emittedFile:tests/cases/compiler/isolatedModulesSourceMap.js
|
||||
sourceFile:isolatedModulesSourceMap.ts
|
||||
-------------------------------------------------------------------
|
||||
>>>export var x;
|
||||
>>>export var x = 1;
|
||||
1 >
|
||||
2 >^^^^^^^^^^^
|
||||
3 > ^
|
||||
4 > ^
|
||||
5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
|
||||
4 > ^^^
|
||||
5 > ^
|
||||
6 > ^
|
||||
7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
|
||||
1 >
|
||||
>
|
||||
2 >export var
|
||||
3 > x
|
||||
4 > ;
|
||||
4 > =
|
||||
5 > 1
|
||||
6 > ;
|
||||
1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
|
||||
2 >Emitted(1, 12) Source(2, 12) + SourceIndex(0)
|
||||
3 >Emitted(1, 13) Source(2, 13) + SourceIndex(0)
|
||||
4 >Emitted(1, 14) Source(2, 14) + SourceIndex(0)
|
||||
4 >Emitted(1, 16) Source(2, 16) + SourceIndex(0)
|
||||
5 >Emitted(1, 17) Source(2, 17) + SourceIndex(0)
|
||||
6 >Emitted(1, 18) Source(2, 18) + SourceIndex(0)
|
||||
---
|
||||
>>>//# sourceMappingURL=isolatedModulesSourceMap.js.map
|
||||
@@ -0,0 +1,5 @@
|
||||
=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
|
||||
|
||||
export var x = 1;
|
||||
>x : Symbol(x, Decl(isolatedModulesSourceMap.ts, 1, 10))
|
||||
|
||||
6
tests/baselines/reference/isolatedModulesSourceMap.types
Normal file
6
tests/baselines/reference/isolatedModulesSourceMap.types
Normal file
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
|
||||
|
||||
export var x = 1;
|
||||
>x : number
|
||||
>1 : number
|
||||
|
||||
21
tests/baselines/reference/jsxImportInAttribute.js
Normal file
21
tests/baselines/reference/jsxImportInAttribute.js
Normal file
@@ -0,0 +1,21 @@
|
||||
//// [tests/cases/compiler/jsxImportInAttribute.tsx] ////
|
||||
|
||||
//// [component.d.ts]
|
||||
|
||||
declare module "Test" {
|
||||
export default class Text { }
|
||||
}
|
||||
|
||||
//// [consumer.tsx]
|
||||
/// <reference path="component.d.ts" />
|
||||
import Test from 'Test';
|
||||
|
||||
let x = Test; // emit test_1.default
|
||||
<anything attr={Test} />; // ?
|
||||
|
||||
|
||||
//// [consumer.jsx]
|
||||
/// <reference path="component.d.ts" />
|
||||
var Test_1 = require('Test');
|
||||
var x = Test_1["default"]; // emit test_1.default
|
||||
<anything attr={Test_1["default"]}/>; // ?
|
||||
19
tests/baselines/reference/jsxImportInAttribute.symbols
Normal file
19
tests/baselines/reference/jsxImportInAttribute.symbols
Normal file
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/consumer.tsx ===
|
||||
/// <reference path="component.d.ts" />
|
||||
import Test from 'Test';
|
||||
>Test : Symbol(Test, Decl(consumer.tsx, 1, 6))
|
||||
|
||||
let x = Test; // emit test_1.default
|
||||
>x : Symbol(x, Decl(consumer.tsx, 3, 3))
|
||||
>Test : Symbol(Test, Decl(consumer.tsx, 1, 6))
|
||||
|
||||
<anything attr={Test} />; // ?
|
||||
>attr : Symbol(unknown)
|
||||
|
||||
=== tests/cases/compiler/component.d.ts ===
|
||||
|
||||
declare module "Test" {
|
||||
export default class Text { }
|
||||
>Text : Symbol(Text, Decl(component.d.ts, 1, 23))
|
||||
}
|
||||
|
||||
22
tests/baselines/reference/jsxImportInAttribute.types
Normal file
22
tests/baselines/reference/jsxImportInAttribute.types
Normal file
@@ -0,0 +1,22 @@
|
||||
=== tests/cases/compiler/consumer.tsx ===
|
||||
/// <reference path="component.d.ts" />
|
||||
import Test from 'Test';
|
||||
>Test : typeof Test
|
||||
|
||||
let x = Test; // emit test_1.default
|
||||
>x : typeof Test
|
||||
>Test : typeof Test
|
||||
|
||||
<anything attr={Test} />; // ?
|
||||
><anything attr={Test} /> : any
|
||||
>anything : any
|
||||
>attr : any
|
||||
>Test : any
|
||||
|
||||
=== tests/cases/compiler/component.d.ts ===
|
||||
|
||||
declare module "Test" {
|
||||
export default class Text { }
|
||||
>Text : Text
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
tests/cases/compiler/strictModeInConstructor.ts(9,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
|
||||
tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
|
||||
|
||||
|
||||
==== tests/cases/compiler/strictModeInConstructor.ts (2 errors) ====
|
||||
==== tests/cases/compiler/strictModeInConstructor.ts (1 errors) ====
|
||||
class A {
|
||||
}
|
||||
|
||||
@@ -12,14 +11,9 @@ tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' c
|
||||
public s: number = 9;
|
||||
|
||||
constructor () {
|
||||
~~~~~~~~~~~~~~~~
|
||||
"use strict"; // No error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
super();
|
||||
~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
|
||||
}
|
||||
|
||||
class C extends A {
|
||||
|
||||
18
tests/cases/compiler/aliasesInSystemModule1.ts
Normal file
18
tests/cases/compiler/aliasesInSystemModule1.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
// @module: system
|
||||
// @isolatedModules: true
|
||||
|
||||
import alias = require('foo');
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
|
||||
17
tests/cases/compiler/aliasesInSystemModule2.ts
Normal file
17
tests/cases/compiler/aliasesInSystemModule2.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @module: system
|
||||
// @isolatedModules: true
|
||||
|
||||
import {alias} from "foo";
|
||||
import cls = alias.Class;
|
||||
export import cls2 = alias.Class;
|
||||
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
|
||||
module M {
|
||||
export import cls = alias.Class;
|
||||
let x = new alias.Class();
|
||||
let y = new cls();
|
||||
let z = new cls2();
|
||||
}
|
||||
@@ -3,4 +3,4 @@
|
||||
// @target: es6
|
||||
|
||||
// @filename: file1.ts
|
||||
export var x;
|
||||
export var x = 1;
|
||||
14
tests/cases/compiler/jsxImportInAttribute.tsx
Normal file
14
tests/cases/compiler/jsxImportInAttribute.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
//@jsx: preserve
|
||||
//@module: commonjs
|
||||
|
||||
//@filename: component.d.ts
|
||||
declare module "Test" {
|
||||
export default class Text { }
|
||||
}
|
||||
|
||||
//@filename: consumer.tsx
|
||||
/// <reference path="component.d.ts" />
|
||||
import Test from 'Test';
|
||||
|
||||
let x = Test; // emit test_1.default
|
||||
<anything attr={Test} />; // ?
|
||||
@@ -1,7 +1,8 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// /*1*/function parseInt(s/*2*/:string):number;
|
||||
|
||||
goTo.marker('2');
|
||||
edit.deleteAtCaret(':string'.length);
|
||||
goTo.marker('1');
|
||||
edit.insert('declare ');
|
||||
|
||||
edit.insert('declare ');
|
||||
@@ -29,7 +29,34 @@
|
||||
// type 'fs.' as an alternate way of accessing the top-level objects
|
||||
// (e.g. 'fs.goTo.eof();')
|
||||
|
||||
//---------------------------------------
|
||||
// For API editors:
|
||||
// When editting this file, and only while editing this file, enable the reference comments
|
||||
// and comment out the declarations in this section to get proper type information.
|
||||
// Undo these changes before compiling/committing/editing any other fourslash tests.
|
||||
// The test suite will likely crash if you try 'jake runtests' with reference comments enabled.
|
||||
//
|
||||
// Explanation:
|
||||
// We want type-completion while we edit this file, but at compile time/while editting fourslash tests,
|
||||
// we don't want to include the following reference because we are compiling this file in "--out" mode and don't want to rope
|
||||
// in the entire codebase into the compilation each fourslash test. Additionally, we don't want to expose the
|
||||
// src/harness/fourslash.ts API's (or the rest of the compiler) because they are unstable and complicate the
|
||||
// fourslash testing DSL. Finally, in this case, runtime reflection is (much) faster.
|
||||
//
|
||||
// TODO: figure out a better solution to the API exposure problem.
|
||||
|
||||
// /// <reference path="../../../built/local/typescriptServices.d.ts"/>
|
||||
// /// <reference path="../../../src/harness/fourslash.ts"/>
|
||||
|
||||
declare var FourSlash;
|
||||
module ts {
|
||||
export interface SymbolDisplayPart {
|
||||
text: string;
|
||||
kind: string;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
|
||||
// Return code used by getEmitOutput function to indicate status of the function
|
||||
// It is a duplicate of the one in types.ts to expose it to testcases in fourslash
|
||||
@@ -42,7 +69,6 @@ enum EmitReturnStatus {
|
||||
}
|
||||
|
||||
module FourSlashInterface {
|
||||
declare var FourSlash;
|
||||
|
||||
export interface Marker {
|
||||
fileName: string;
|
||||
@@ -201,15 +227,6 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
|
||||
}
|
||||
|
||||
public implementorsCountIs(count: number) {
|
||||
FourSlash.currentTestState.verifyImplementorsCountIs(count);
|
||||
}
|
||||
|
||||
// Add tests for this.
|
||||
public currentParameterIsVariable() {
|
||||
FourSlash.currentTestState.verifyCurrentParameterIsVariable(!this.negative);
|
||||
}
|
||||
|
||||
public signatureHelpPresent() {
|
||||
FourSlash.currentTestState.verifySignatureHelpPresent(!this.negative);
|
||||
}
|
||||
@@ -361,14 +378,11 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifyNoMatchingBracePosition(bracePosition);
|
||||
}
|
||||
|
||||
public setVerifyDocComments(val: boolean) {
|
||||
FourSlash.currentTestState.setVerifyDocComments(val);
|
||||
}
|
||||
|
||||
public getScriptLexicalStructureListCount(count: number) {
|
||||
FourSlash.currentTestState.verifyGetScriptLexicalStructureListCount(count);
|
||||
}
|
||||
|
||||
// TODO: figure out what to do with the unused arguments.
|
||||
public getScriptLexicalStructureListContains(
|
||||
name: string,
|
||||
kind: string,
|
||||
@@ -376,13 +390,7 @@ module FourSlashInterface {
|
||||
parentName?: string,
|
||||
isAdditionalSpan?: boolean,
|
||||
markerPosition?: number) {
|
||||
FourSlash.currentTestState.verifGetScriptLexicalStructureListContains(
|
||||
name,
|
||||
kind,
|
||||
fileName,
|
||||
parentName,
|
||||
isAdditionalSpan,
|
||||
markerPosition);
|
||||
FourSlash.currentTestState.verifyGetScriptLexicalStructureListContains(name, kind);
|
||||
}
|
||||
|
||||
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) {
|
||||
@@ -698,12 +706,7 @@ module fs {
|
||||
export var format = new FourSlashInterface.format();
|
||||
export var cancellation = new FourSlashInterface.cancellation();
|
||||
}
|
||||
module ts {
|
||||
export interface SymbolDisplayPart {
|
||||
text: string;
|
||||
kind: string;
|
||||
}
|
||||
}
|
||||
|
||||
function verifyOperationIsCancelled(f) {
|
||||
FourSlash.verifyOperationIsCancelled(f);
|
||||
}
|
||||
|
||||
447
tests/cases/unittests/session.ts
Normal file
447
tests/cases/unittests/session.ts
Normal file
@@ -0,0 +1,447 @@
|
||||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
let lastWrittenToHost: string;
|
||||
const mockHost: ServerHost = {
|
||||
args: [],
|
||||
newLine: "\n",
|
||||
useCaseSensitiveFileNames: true,
|
||||
write(s): void { lastWrittenToHost = s; },
|
||||
readFile(): string { return void 0; },
|
||||
writeFile(): void {},
|
||||
resolvePath(): string { return void 0; },
|
||||
fileExists: () => false,
|
||||
directoryExists: () => false,
|
||||
createDirectory(): void {},
|
||||
getExecutingFilePath(): string { return void 0; },
|
||||
getCurrentDirectory(): string { return void 0; },
|
||||
readDirectory(): string[] { return []; },
|
||||
exit(): void {}
|
||||
};
|
||||
const mockLogger: Logger = {
|
||||
close(): void {},
|
||||
isVerbose(): boolean { return false; },
|
||||
loggingEnabled(): boolean { return false; },
|
||||
perftrc(s: string): void {},
|
||||
info(s: string): void {},
|
||||
startGroup(): void {},
|
||||
endGroup(): void {},
|
||||
msg(s: string, type?: string): void {},
|
||||
};
|
||||
|
||||
describe("the Session class", () => {
|
||||
let session: Session;
|
||||
let lastSent: protocol.Message;
|
||||
|
||||
beforeEach(() => {
|
||||
session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
|
||||
session.send = (msg: protocol.Message) => {
|
||||
lastSent = msg;
|
||||
};
|
||||
});
|
||||
|
||||
describe("executeCommand", () => {
|
||||
it("should throw when commands are executed with invalid arguments", () => {
|
||||
const req: protocol.FileRequest = {
|
||||
command: CommandNames.Open,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
arguments: {
|
||||
file: undefined
|
||||
}
|
||||
};
|
||||
|
||||
expect(() => session.executeCommand(req)).to.throw();
|
||||
});
|
||||
it("should output an error response when a command does not exist", () => {
|
||||
const req: protocol.Request = {
|
||||
command: "foobar",
|
||||
seq: 0,
|
||||
type: "command"
|
||||
};
|
||||
|
||||
session.executeCommand(req);
|
||||
|
||||
expect(lastSent).to.deep.equal(<protocol.Response>{
|
||||
command: CommandNames.Unknown,
|
||||
type: "response",
|
||||
seq: 0,
|
||||
message: "Unrecognized JSON command: foobar",
|
||||
request_seq: 0,
|
||||
success: false
|
||||
});
|
||||
});
|
||||
it("should return a tuple containing the response and if a response is required on success", () => {
|
||||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
newLineCharacter: "`n"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(session.executeCommand(req)).to.deep.equal({
|
||||
responseRequired: false
|
||||
});
|
||||
expect(lastSent).to.deep.equal({
|
||||
command: CommandNames.Configure,
|
||||
type: "response",
|
||||
success: true,
|
||||
request_seq: 0,
|
||||
seq: 0,
|
||||
body: undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("onMessage", () => {
|
||||
it("should not throw when commands are executed with invalid arguments", () => {
|
||||
let i = 0;
|
||||
for (name in CommandNames) {
|
||||
if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) {
|
||||
continue;
|
||||
}
|
||||
const req: protocol.Request = {
|
||||
command: name,
|
||||
seq: i++,
|
||||
type: "command"
|
||||
};
|
||||
session.onMessage(JSON.stringify(req));
|
||||
req.seq = i++;
|
||||
req.arguments = {};
|
||||
session.onMessage(JSON.stringify(req));
|
||||
req.seq = i++;
|
||||
req.arguments = null;
|
||||
session.onMessage(JSON.stringify(req));
|
||||
req.seq = i++;
|
||||
req.arguments = "";
|
||||
session.onMessage(JSON.stringify(req));
|
||||
req.seq = i++;
|
||||
req.arguments = 0;
|
||||
session.onMessage(JSON.stringify(req));
|
||||
req.seq = i++;
|
||||
req.arguments = [];
|
||||
session.onMessage(JSON.stringify(req));
|
||||
}
|
||||
session.onMessage("GARBAGE NON_JSON DATA");
|
||||
});
|
||||
it("should output the response for a correctly handled message", () => {
|
||||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
newLineCharacter: "`n"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
session.onMessage(JSON.stringify(req));
|
||||
|
||||
expect(lastSent).to.deep.equal(<protocol.ConfigureResponse>{
|
||||
command: CommandNames.Configure,
|
||||
type: "response",
|
||||
success: true,
|
||||
request_seq: 0,
|
||||
seq: 0,
|
||||
body: undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("send", () => {
|
||||
it("is an overrideable handle which sends protocol messages over the wire", () => {
|
||||
const msg = {seq: 0, type: "none"};
|
||||
const strmsg = JSON.stringify(msg);
|
||||
const len = 1 + Buffer.byteLength(strmsg, "utf8");
|
||||
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
|
||||
|
||||
session.send = Session.prototype.send;
|
||||
assert(session.send);
|
||||
expect(session.send(msg)).to.not.exist;
|
||||
expect(lastWrittenToHost).to.equal(resultMsg);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addProtocolHandler", () => {
|
||||
it("can add protocol handlers", () => {
|
||||
const respBody = {
|
||||
item: false
|
||||
};
|
||||
const command = "newhandle";
|
||||
const result = {
|
||||
response: respBody,
|
||||
responseRequired: true
|
||||
};
|
||||
|
||||
session.addProtocolHandler(command, (req) => result);
|
||||
|
||||
expect(session.executeCommand({
|
||||
command,
|
||||
seq: 0,
|
||||
type: "command"
|
||||
})).to.deep.equal(result);
|
||||
});
|
||||
it("throws when a duplicate handler is passed", () => {
|
||||
const respBody = {
|
||||
item: false
|
||||
};
|
||||
const resp = {
|
||||
response: respBody,
|
||||
responseRequired: true
|
||||
};
|
||||
const command = "newhandle";
|
||||
|
||||
session.addProtocolHandler(command, (req) => resp);
|
||||
|
||||
expect(() => session.addProtocolHandler(command, (req) => resp))
|
||||
.to.throw(`Protocol handler already exists for command "${command}"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("event", () => {
|
||||
it("can format event responses and send them", () => {
|
||||
const evt = "notify-test";
|
||||
const info = {
|
||||
test: true
|
||||
};
|
||||
|
||||
session.event(info, evt);
|
||||
|
||||
expect(lastSent).to.deep.equal({
|
||||
type: "event",
|
||||
seq: 0,
|
||||
event: evt,
|
||||
body: info
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("output", () => {
|
||||
it("can format command responses and send them", () => {
|
||||
const body = {
|
||||
block: {
|
||||
key: "value"
|
||||
}
|
||||
};
|
||||
const command = "test";
|
||||
|
||||
session.output(body, command);
|
||||
|
||||
expect(lastSent).to.deep.equal({
|
||||
seq: 0,
|
||||
request_seq: 0,
|
||||
type: "response",
|
||||
command,
|
||||
body: body,
|
||||
success: true
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("how Session is extendable via subclassing", () => {
|
||||
class TestSession extends Session {
|
||||
lastSent: protocol.Message;
|
||||
customHandler = "testhandler";
|
||||
constructor() {
|
||||
super(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
|
||||
this.addProtocolHandler(this.customHandler, () => {
|
||||
return {response: undefined, responseRequired: true};
|
||||
});
|
||||
}
|
||||
send(msg: protocol.Message) {
|
||||
this.lastSent = msg;
|
||||
}
|
||||
};
|
||||
|
||||
it("can override methods such as send", () => {
|
||||
const session = new TestSession();
|
||||
const body = {
|
||||
block: {
|
||||
key: "value"
|
||||
}
|
||||
};
|
||||
const command = "test";
|
||||
|
||||
session.output(body, command);
|
||||
|
||||
expect(session.lastSent).to.deep.equal({
|
||||
seq: 0,
|
||||
request_seq: 0,
|
||||
type: "response",
|
||||
command,
|
||||
body: body,
|
||||
success: true
|
||||
});
|
||||
});
|
||||
it("can add and respond to new protocol handlers", () => {
|
||||
const session = new TestSession();
|
||||
|
||||
expect(session.executeCommand({
|
||||
seq: 0,
|
||||
type: "command",
|
||||
command: session.customHandler
|
||||
})).to.deep.equal({
|
||||
response: undefined,
|
||||
responseRequired: true
|
||||
});
|
||||
});
|
||||
it("has access to the project service", () => {
|
||||
class ServiceSession extends TestSession {
|
||||
constructor() {
|
||||
super();
|
||||
assert(this.projectService);
|
||||
expect(this.projectService).to.be.instanceOf(ProjectService);
|
||||
}
|
||||
};
|
||||
new ServiceSession();
|
||||
});
|
||||
});
|
||||
|
||||
describe("an example of using the Session API to create an in-process server", () => {
|
||||
class InProcSession extends Session {
|
||||
private queue: protocol.Request[] = [];
|
||||
constructor(private client: InProcClient) {
|
||||
super(mockHost, Buffer.byteLength, process.hrtime, mockLogger);
|
||||
this.addProtocolHandler("echo", (req: protocol.Request) => ({
|
||||
response: req.arguments,
|
||||
responseRequired: true
|
||||
}));
|
||||
}
|
||||
|
||||
send(msg: protocol.Message) {
|
||||
this.client.handle(msg);
|
||||
}
|
||||
|
||||
enqueue(msg: protocol.Request) {
|
||||
this.queue.unshift(msg);
|
||||
}
|
||||
|
||||
handleRequest(msg: protocol.Request) {
|
||||
let response: protocol.Response;
|
||||
try {
|
||||
({response} = this.executeCommand(msg));
|
||||
}
|
||||
catch (e) {
|
||||
this.output(undefined, msg.command, msg.seq, e.toString());
|
||||
return;
|
||||
}
|
||||
if (response) {
|
||||
this.output(response, msg.command, msg.seq);
|
||||
}
|
||||
}
|
||||
|
||||
consumeQueue() {
|
||||
while (this.queue.length > 0) {
|
||||
const elem = this.queue.pop();
|
||||
this.handleRequest(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InProcClient {
|
||||
private server: InProcSession;
|
||||
private seq = 0;
|
||||
private callbacks: ts.Map<(resp: protocol.Response) => void> = {};
|
||||
private eventHandlers: ts.Map<(args: any) => void> = {};
|
||||
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
const response = <protocol.Response>msg;
|
||||
if (this.callbacks[response.request_seq]) {
|
||||
this.callbacks[response.request_seq](response);
|
||||
delete this.callbacks[response.request_seq];
|
||||
}
|
||||
}
|
||||
else if (msg.type === "event") {
|
||||
const event = <protocol.Event>msg;
|
||||
this.emit(event.event, event.body);
|
||||
}
|
||||
}
|
||||
|
||||
emit(name: string, args: any): void {
|
||||
if (this.eventHandlers[name]) {
|
||||
this.eventHandlers[name](args);
|
||||
}
|
||||
}
|
||||
|
||||
on(name: string, handler: (args: any) => void): void {
|
||||
this.eventHandlers[name] = handler;
|
||||
}
|
||||
|
||||
connect(session: InProcSession): void {
|
||||
this.server = session;
|
||||
}
|
||||
|
||||
execute(command: string, args: any, callback: (resp: protocol.Response) => void): void {
|
||||
if (!this.server) {
|
||||
return;
|
||||
}
|
||||
this.seq++;
|
||||
this.server.enqueue({
|
||||
seq: this.seq,
|
||||
type: "command",
|
||||
command,
|
||||
arguments: args
|
||||
});
|
||||
this.callbacks[this.seq] = callback;
|
||||
}
|
||||
};
|
||||
|
||||
it("can be constructed and respond to commands", (done) => {
|
||||
const cli = new InProcClient();
|
||||
const session = new InProcSession(cli);
|
||||
const toEcho = {
|
||||
data: true
|
||||
};
|
||||
const toEvent = {
|
||||
data: false
|
||||
};
|
||||
let responses = 0;
|
||||
|
||||
// Connect the client
|
||||
cli.connect(session);
|
||||
|
||||
// Add an event handler
|
||||
cli.on("testevent", (eventinfo) => {
|
||||
expect(eventinfo).to.equal(toEvent);
|
||||
responses++;
|
||||
expect(responses).to.equal(1);
|
||||
});
|
||||
|
||||
// Trigger said event from the server
|
||||
session.event(toEvent, "testevent");
|
||||
|
||||
// Queue an echo command
|
||||
cli.execute("echo", toEcho, (resp) => {
|
||||
assert(resp.success, resp.message);
|
||||
responses++;
|
||||
expect(responses).to.equal(2);
|
||||
expect(resp.body).to.deep.equal(toEcho);
|
||||
});
|
||||
|
||||
// Queue a configure command
|
||||
cli.execute("configure", {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
newLineCharacter: "`n"
|
||||
}
|
||||
}, (resp) => {
|
||||
assert(resp.success, resp.message);
|
||||
responses++;
|
||||
expect(responses).to.equal(3);
|
||||
done();
|
||||
});
|
||||
|
||||
// Consume the queue and trigger the callbacks
|
||||
session.consumeQueue();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -2,58 +2,120 @@
|
||||
|
||||
module ts {
|
||||
describe("Transpile", () => {
|
||||
|
||||
function runTest(input: string, compilerOptions: ts.CompilerOptions = {}, fileName?: string, moduleName?: string, expectedOutput?: string, expectedDiagnosticCodes: number[] = []): void {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
let result = transpile(input, compilerOptions, fileName || "file.ts", diagnostics, moduleName);
|
||||
|
||||
|
||||
interface TranspileTestSettings {
|
||||
options?: TranspileOptions;
|
||||
expectedOutput?: string;
|
||||
expectedDiagnosticCodes?: number[];
|
||||
}
|
||||
|
||||
function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) {
|
||||
if(!expectedDiagnosticCodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < expectedDiagnosticCodes.length; i++) {
|
||||
assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`);
|
||||
}
|
||||
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
|
||||
|
||||
if (expectedOutput !== undefined) {
|
||||
assert.equal(result, expectedOutput);
|
||||
}
|
||||
assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
|
||||
}
|
||||
|
||||
function test(input: string, testSettings: TranspileTestSettings): void {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
|
||||
let transpileOptions: TranspileOptions = testSettings.options || {};
|
||||
let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName);
|
||||
|
||||
transpileOptions.reportDiagnostics = true;
|
||||
let transpileModuleResult = transpileModule(input, transpileOptions);
|
||||
|
||||
checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes);
|
||||
checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes);
|
||||
|
||||
if (testSettings.expectedOutput !== undefined) {
|
||||
assert.equal(transpileResult, testSettings.expectedOutput);
|
||||
assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput);
|
||||
}
|
||||
|
||||
// check source maps
|
||||
if (!transpileOptions.compilerOptions) {
|
||||
transpileOptions.compilerOptions = {};
|
||||
}
|
||||
|
||||
if (!transpileOptions.fileName) {
|
||||
transpileOptions.fileName = "file.ts";
|
||||
}
|
||||
|
||||
transpileOptions.compilerOptions.sourceMap = true;
|
||||
let transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions);
|
||||
assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined);
|
||||
|
||||
let expectedSourceMapFileName = removeFileExtension(transpileOptions.fileName) + ".js.map";
|
||||
let expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`;
|
||||
|
||||
if (testSettings.expectedOutput !== undefined) {
|
||||
assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine);
|
||||
}
|
||||
else {
|
||||
// expected output is not set, just verify that output text has sourceMappingURL as a last line
|
||||
let output = transpileModuleResultWithSourceMap.outputText;
|
||||
assert.isTrue(output.length >= expectedSourceMappingUrlLine.length);
|
||||
if (output.length === expectedSourceMappingUrlLine.length) {
|
||||
assert.equal(output, expectedSourceMappingUrlLine);
|
||||
}
|
||||
else {
|
||||
let suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine
|
||||
assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
it("Generates correct compilerOptions diagnostics", () => {
|
||||
// Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher."
|
||||
runTest(`var x = 0;`, {}, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [5047]);
|
||||
test(`var x = 0;`, { expectedDiagnosticCodes: [5047] });
|
||||
});
|
||||
|
||||
it("Generates no diagnostics with valid inputs", () => {
|
||||
// No errors
|
||||
runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
|
||||
test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
|
||||
});
|
||||
|
||||
it("Generates no diagnostics for missing file references", () => {
|
||||
runTest(`/// <reference path="file2.ts" />
|
||||
var x = 0;`,
|
||||
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
|
||||
test(`/// <reference path="file2.ts" />
|
||||
var x = 0;`,
|
||||
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
|
||||
});
|
||||
|
||||
it("Generates no diagnostics for missing module imports", () => {
|
||||
runTest(`import {a} from "module2";`,
|
||||
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined,/*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
|
||||
test(`import {a} from "module2";`,
|
||||
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
|
||||
});
|
||||
|
||||
it("Generates expected syntactic diagnostics", () => {
|
||||
runTest(`a b`,
|
||||
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [1005]); /// 1005: ';' Expected
|
||||
test(`a b`,
|
||||
{ options: { compilerOptions: { module: ModuleKind.CommonJS } }, expectedDiagnosticCodes: [1005] }); /// 1005: ';' Expected
|
||||
});
|
||||
|
||||
it("Does not generate semantic diagnostics", () => {
|
||||
runTest(`var x: string = 0;`,
|
||||
{ module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
|
||||
test(`var x: string = 0;`,
|
||||
{ options: { compilerOptions: { module: ModuleKind.CommonJS } } });
|
||||
});
|
||||
|
||||
it("Generates module output", () => {
|
||||
runTest(`var x = 0;`, { module: ModuleKind.AMD }, /*fileName*/ undefined, /*moduleName*/undefined, `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`);
|
||||
test(`var x = 0;`,
|
||||
{
|
||||
options: { compilerOptions: { module: ModuleKind.AMD } },
|
||||
expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`
|
||||
});
|
||||
});
|
||||
|
||||
it("Uses correct newLine character", () => {
|
||||
runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, /*moduleName*/undefined, `var x = 0;\n`, /*expectedDiagnosticCodes*/ []);
|
||||
test(`var x = 0;`,
|
||||
{
|
||||
options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } },
|
||||
expectedOutput: `var x = 0;\n`
|
||||
});
|
||||
});
|
||||
|
||||
it("Sets module name", () => {
|
||||
@@ -66,12 +128,15 @@ var x = 0;`,
|
||||
` }\n` +
|
||||
` }\n` +
|
||||
`});\n`;
|
||||
runTest("var x = 1;", { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, "NamedModule", output)
|
||||
test("var x = 1;",
|
||||
{
|
||||
options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" },
|
||||
expectedOutput: output
|
||||
})
|
||||
});
|
||||
|
||||
it("No extra errors for file without extension", () => {
|
||||
runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, "file", /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/[]);
|
||||
test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } });
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user