test(language-service): test `@angular/language-service` can be loaded by tsserver.js (#14721)
This commit is contained in:
parent
79fc1e3959
commit
7a66a4115b
|
@ -0,0 +1 @@
|
|||
*.js
|
|
@ -0,0 +1,36 @@
|
|||
# Angular Language Service Test
|
||||
|
||||
This directory is an integration test for `@angular/language-service` to ensure
|
||||
that various versions of the server can be loaded in the supported versions of
|
||||
TypeScript's language service.
|
||||
|
||||
## New supported version of TypeScript
|
||||
|
||||
To add a new supported version of TypeScript:
|
||||
|
||||
1) Create directory in `typescripts` to hold the new version following the pattern
|
||||
of the other versions.
|
||||
2) Add the directory name to the end of the `TYPESCRIPTS` variable in the
|
||||
`scripts/env.sh` file.
|
||||
3) Run `scripts/update_golden.sh` to generate the expected files.
|
||||
4) Verify the expected output is reasonable by comparing to a known good output
|
||||
from a previous version.
|
||||
|
||||
## Update golden files
|
||||
|
||||
If the expected output needs to be updated run `scripts/update_golden.sh` to
|
||||
update the expected output of the server.
|
||||
|
||||
## Adding a new fixture
|
||||
|
||||
Currently there is no automated way to produce a new fixture. The way the
|
||||
current fixtures were created was to hack a version of tsserver.js to write the
|
||||
commands from `VSCode` to a file while performing the operation to be tested.
|
||||
I also hand modified the input to remove superfluous request.
|
||||
|
||||
Once a new fixture is created:
|
||||
|
||||
1) Add the fixture base name (without the .json) to `FIXTURES` in
|
||||
`scripts/env.sh`.
|
||||
2) Run `scripts/udpate_golden.sh` to produce the expected output files.
|
||||
3) Hand validate the expected output is reasonable.
|
|
@ -0,0 +1,260 @@
|
|||
[
|
||||
{
|
||||
"type": "response",
|
||||
"command": "configure",
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"success": true,
|
||||
"body": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "completions",
|
||||
"success": true,
|
||||
"body": [
|
||||
{
|
||||
"name": "anchor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "anchor"
|
||||
},
|
||||
{
|
||||
"name": "big",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "big"
|
||||
},
|
||||
{
|
||||
"name": "blink",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "blink"
|
||||
},
|
||||
{
|
||||
"name": "bold",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "bold"
|
||||
},
|
||||
{
|
||||
"name": "charAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charAt"
|
||||
},
|
||||
{
|
||||
"name": "charCodeAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charCodeAt"
|
||||
},
|
||||
{
|
||||
"name": "codePointAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "codePointAt"
|
||||
},
|
||||
{
|
||||
"name": "concat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "concat"
|
||||
},
|
||||
{
|
||||
"name": "endsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "endsWith"
|
||||
},
|
||||
{
|
||||
"name": "fixed",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fixed"
|
||||
},
|
||||
{
|
||||
"name": "fontcolor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontcolor"
|
||||
},
|
||||
{
|
||||
"name": "fontsize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontsize"
|
||||
},
|
||||
{
|
||||
"name": "includes",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "includes"
|
||||
},
|
||||
{
|
||||
"name": "indexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "indexOf"
|
||||
},
|
||||
{
|
||||
"name": "italics",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "italics"
|
||||
},
|
||||
{
|
||||
"name": "lastIndexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "lastIndexOf"
|
||||
},
|
||||
{
|
||||
"name": "length",
|
||||
"kind": "property",
|
||||
"kindModifiers": "",
|
||||
"sortText": "length"
|
||||
},
|
||||
{
|
||||
"name": "link",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "link"
|
||||
},
|
||||
{
|
||||
"name": "localeCompare",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "localeCompare"
|
||||
},
|
||||
{
|
||||
"name": "match",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "match"
|
||||
},
|
||||
{
|
||||
"name": "normalize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "normalize"
|
||||
},
|
||||
{
|
||||
"name": "repeat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "repeat"
|
||||
},
|
||||
{
|
||||
"name": "replace",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "replace"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "search"
|
||||
},
|
||||
{
|
||||
"name": "slice",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "slice"
|
||||
},
|
||||
{
|
||||
"name": "small",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "small"
|
||||
},
|
||||
{
|
||||
"name": "split",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "split"
|
||||
},
|
||||
{
|
||||
"name": "startsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "startsWith"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "strike"
|
||||
},
|
||||
{
|
||||
"name": "sub",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sub"
|
||||
},
|
||||
{
|
||||
"name": "substr",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substr"
|
||||
},
|
||||
{
|
||||
"name": "substring",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substring"
|
||||
},
|
||||
{
|
||||
"name": "sup",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sup"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "toLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toString",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toString"
|
||||
},
|
||||
{
|
||||
"name": "toUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "trim",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "trim"
|
||||
},
|
||||
{
|
||||
"name": "valueOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "valueOf"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,68 @@
|
|||
[
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "request",
|
||||
"command": "configure",
|
||||
"arguments": {
|
||||
"hostInfo": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 1,
|
||||
"type": "request",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"module": "CommonJS",
|
||||
"target": "ES6",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowNonTsExtensions": true,
|
||||
"allowJs": true,
|
||||
"jsx": "Preserve"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 4,
|
||||
"type": "request",
|
||||
"command": "open",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"fileContent": "import { Component } from '@angular/core';\n\n@Component({\n selector: 'my-app',\n template: `<h1>Hello {{name}}</h1>`,\n})\nexport class AppComponent { name = 'Angular'; }\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 7,
|
||||
"type": "request",
|
||||
"command": "geterr",
|
||||
"arguments": {
|
||||
"delay": 0,
|
||||
"files": [
|
||||
"$$PWD$$/project/app/app.component.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 12,
|
||||
"type": "request",
|
||||
"command": "change",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"line": 5,
|
||||
"offset": 30,
|
||||
"endLine": 5,
|
||||
"endOffset": 30,
|
||||
"insertString": "."
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 13,
|
||||
"type": "request",
|
||||
"command": "completions",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"line": 5,
|
||||
"offset": 31
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,13 @@
|
|||
[
|
||||
{
|
||||
"type": "response",
|
||||
"command": "configure",
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"success": true,
|
||||
"body": true
|
||||
}
|
||||
]
|
|
@ -0,0 +1,45 @@
|
|||
[
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "request",
|
||||
"command": "configure",
|
||||
"arguments": {
|
||||
"hostInfo": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 1,
|
||||
"type": "request",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"module": "CommonJS",
|
||||
"target": "ES6",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowNonTsExtensions": true,
|
||||
"allowJs": true,
|
||||
"jsx": "Preserve"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 2,
|
||||
"type": "request",
|
||||
"command": "open",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/app/app.module.ts",
|
||||
"fileContent": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 3,
|
||||
"type": "request",
|
||||
"command": "geterr",
|
||||
"arguments": {
|
||||
"delay": 0,
|
||||
"files": [
|
||||
"$$PWD$$/app/app.module.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "language_service_plugin",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"decription": "Angular Langauge Service plugin integration test",
|
||||
"dependencies": {
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/language-service": "file:../../dist/packages-dist/language-service",
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
|
||||
"@angular/tsc-wrapped": "file:../../dist/tools/@angular/tsc-wrapped",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/node": "^7.0.5",
|
||||
"minimist": "^1.2.0",
|
||||
"rxjs": "file:../../node_modules/rxjs",
|
||||
"typescript": "^2.1.5",
|
||||
"zone.js": "0.7.6"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "scripts/install.sh",
|
||||
"test": "tsc -p tools && scripts/test.sh"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `<h1>Hello {{name}}</h1>`,
|
||||
})
|
||||
export class AppComponent { name = 'Angular'; }
|
|
@ -0,0 +1,11 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule ],
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
|
@ -0,0 +1,5 @@
|
|||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"plugins": [
|
||||
{ "name": "@angular/language-service" }
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
TYPESCRIPTS=2.3
|
||||
FIXTURES="smokeTest getCompletions"
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
source scripts/env.sh
|
||||
|
||||
# Setup TypeScripts
|
||||
for TYPESCRIPT in ${TYPESCRIPTS[@]}
|
||||
do
|
||||
(
|
||||
cd typescripts/$TYPESCRIPT
|
||||
yarn
|
||||
)
|
||||
done
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
source scripts/env.sh
|
||||
|
||||
HOST="node tools/typescript_host.js"
|
||||
VALIDATE="node tools/typescript_validator.js"
|
||||
|
||||
for TYPESCRIPT in ${TYPESCRIPTS[@]}
|
||||
do
|
||||
SERVER="node typescripts/$TYPESCRIPT/node_modules/typescript/lib/tsserver.js"
|
||||
for FIXTURE_BASE in ${FIXTURES[@]}
|
||||
do
|
||||
FIXTURE=fixtures/$FIXTURE_BASE.json
|
||||
EXPECTED=fixtures/$FIXTURE_BASE-expected-$TYPESCRIPT.json
|
||||
if [[ ${UPDATE_GOLDEN} == true ]]; then
|
||||
$HOST --file $FIXTURE --pwd $(pwd) | $SERVER | $VALIDATE --golden > $EXPECTED
|
||||
else
|
||||
$HOST --file $FIXTURE --pwd $(pwd) | $SERVER | $VALIDATE --expect $EXPECTED
|
||||
fi
|
||||
done
|
||||
done
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
|
||||
UPDATE_GOLDEN=true scripts/test.sh
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": false,
|
||||
"lib": ["es2015", "dom"],
|
||||
"types": [
|
||||
"node",
|
||||
"minimist"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"typescript_host.ts",
|
||||
"typescript_validator.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
import * as fs from 'fs';
|
||||
import * as minimist from 'minimist';
|
||||
|
||||
const RE_PWD = /\$\$PWD\$\$/g;
|
||||
|
||||
let errorsDetected = false;
|
||||
|
||||
function reportError(arg: string): boolean {
|
||||
console.error(`Unknown argument: ${arg}`);
|
||||
errorsDetected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log('TypeScript Host')
|
||||
console.log(`${process.argv[1]} --file <file-name> [--pwd <pwd>]`);
|
||||
console.log(`
|
||||
Send JSON message using the JSON RPC protocol to stdout.
|
||||
`)
|
||||
}
|
||||
|
||||
let args = minimist(process.argv.slice(2), { string: ['file', 'pwd'], unknown: reportError });
|
||||
|
||||
if (errorsDetected) {
|
||||
help();
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const file = args['file'];
|
||||
if (!file) {
|
||||
console.log('stdin form not supported yet.')
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Sender
|
||||
const pending: string[] = [];
|
||||
let writing = false;
|
||||
|
||||
function writeMessage(message: string) {
|
||||
writing = true;
|
||||
process.stdout.write(message + '\n', checkPending);
|
||||
}
|
||||
|
||||
function checkPending() {
|
||||
writing = false;
|
||||
if (pending.length) {
|
||||
writeMessage(pending.shift());
|
||||
}
|
||||
}
|
||||
|
||||
function send(message: string) {
|
||||
if (writing) {
|
||||
pending.push(message);
|
||||
} else {
|
||||
writeMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let content = fs.readFileSync(file, 'utf8');
|
||||
if (args['pwd']) {
|
||||
content = content.replace(RE_PWD, args['pwd']);
|
||||
}
|
||||
|
||||
const json = JSON.parse(content);
|
||||
|
||||
if (Array.isArray(json)) {
|
||||
for (const message of json) {
|
||||
send(JSON.stringify(message));
|
||||
}
|
||||
} else {
|
||||
throw Error('Expected an array for input messages.')
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(`Error: ${e.message}`);
|
||||
process.exit(2);
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
import * as fs from 'fs';
|
||||
import * as minimist from 'minimist';
|
||||
|
||||
let errorsDetected = false;
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
function reportError(arg: string): boolean {
|
||||
console.error(`Unknown argument: ${arg}`);
|
||||
errorsDetected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log('TypeScript Validator')
|
||||
console.log(`${process.argv[1]} [--expect <file-name> | --golden] [--pwd <dir>]`);
|
||||
console.log(`
|
||||
Validate that the emitted output produces the expect JSON.`)
|
||||
}
|
||||
|
||||
let args = minimist(process.argv.slice(2), { string: ['expect', 'pwd'], boolean: ['golden'], unknown: reportError });
|
||||
|
||||
if (!args.golden && !args.expect) {
|
||||
console.log('Expected -golden or -expect');
|
||||
errorsDetected = true;
|
||||
}
|
||||
|
||||
if (args.golden && args.expect) {
|
||||
console.log('Expected -golded or -expect but not both');
|
||||
errorsDetected = true;
|
||||
}
|
||||
|
||||
if (errorsDetected) {
|
||||
help();
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var expected: any;
|
||||
if (args.expect) {
|
||||
expected = JSON.parse(fs.readFileSync(args.expect, 'utf8'));
|
||||
}
|
||||
|
||||
// Reader
|
||||
let pending = Buffer.alloc(0);
|
||||
|
||||
const prefix = 'Content-Length: ';
|
||||
|
||||
function tryReadMessage(cb: (message: any) => void) {
|
||||
const firstLine = pending.indexOf(10);
|
||||
if (firstLine >= 1) {
|
||||
const line = pending.toString('utf8', 0, firstLine);
|
||||
if (!line.startsWith(prefix)) {
|
||||
throw Error(`Unexpected input: ${line}`);
|
||||
}
|
||||
const length = +line.substring(prefix.length, firstLine - 1);
|
||||
const dataStart = firstLine + 2;
|
||||
const messageText = pending.toString('utf8', dataStart, dataStart + length);
|
||||
const message = JSON.parse(messageText);
|
||||
pending = pending.slice(dataStart + length + 1);
|
||||
cb(message);
|
||||
tryReadMessage(cb);
|
||||
}
|
||||
}
|
||||
|
||||
function collect(cb: (error: any, messages: any[]) => void) {
|
||||
const result: any[] = [];
|
||||
|
||||
function report(error: any, messages: any[]) {
|
||||
cb(error, messages);
|
||||
cb = () => {};
|
||||
}
|
||||
|
||||
process.stdin.on('error', report);
|
||||
process.stdin.on('data', (data: Buffer) => {
|
||||
try {
|
||||
pending = Buffer.concat([pending, data], pending.length + data.length);
|
||||
tryReadMessage((message: any) => {
|
||||
result.push(message);
|
||||
});
|
||||
} catch (e) {
|
||||
report(e, []);
|
||||
}
|
||||
});
|
||||
|
||||
process.stdin.on('close', () => {
|
||||
report(null, result);
|
||||
});
|
||||
}
|
||||
|
||||
function sanitize(messages: any[]): any[] {
|
||||
return messages.filter((message: any) => {
|
||||
return message && message.type == 'response';
|
||||
}).map((message: any) => {
|
||||
// Only preserve a fixed set of fields.
|
||||
const result: any = {};
|
||||
if (message.type != null) result.type = message.type;
|
||||
if (message.command != null) result.command = message.command;
|
||||
if (message.success != null) result.success = message.success;
|
||||
if (message.body != null) result.body = message.body;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function isPrimitive(value: any): boolean {
|
||||
return Object(value) !== value;
|
||||
}
|
||||
|
||||
function expectPrimitive(received: any, expected: any) {
|
||||
if (received !== expected) {
|
||||
throw new Error(`Expected ${expected} but received ${received}`);
|
||||
}
|
||||
}
|
||||
|
||||
function expectArray(received: any, expected: any[]) {
|
||||
if (!Array.isArray(received)) {
|
||||
throw new Error(`Expected an array, received ${JSON.stringify(received)}`);
|
||||
}
|
||||
if (received.length != expected.length) {
|
||||
throw new Error(`Expected an array length ${expected.length}, received ${JSON.stringify(received)}`);
|
||||
}
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
expect(received[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function expectObject(received: any, expected: any) {
|
||||
for (const name of Object.getOwnPropertyNames(expected)) {
|
||||
if (!received.hasOwnProperty(name)) {
|
||||
throw new Error(`Expected object an object containing a field ${name}, received ${JSON.stringify(expected)}`);
|
||||
}
|
||||
expect(received[name], expected[name]);
|
||||
}
|
||||
}
|
||||
|
||||
function expect(received: any, expected: any) {
|
||||
if (isPrimitive(expected)) {
|
||||
expectPrimitive(received, expected);
|
||||
} else if (Array.isArray(expected)) {
|
||||
expectArray(received, expected);
|
||||
} else {
|
||||
expectObject(received, expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
collect((err: any, messages: any[]) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
if (args.golden) {
|
||||
console.log(JSON.stringify(sanitize(messages), null, ' '));
|
||||
} else {
|
||||
try {
|
||||
expect(sanitize(messages), expected);
|
||||
console.log('PASSED:', Date.now() - start, 'ms');
|
||||
process.exit(0);
|
||||
} catch(e) {
|
||||
console.log('FAILED:', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "2.3",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"typescript": "2.3.0-dev.20170223"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@2.3.0-dev.20170223:
|
||||
version "2.3.0-dev.20170223"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.0-dev.20170223.tgz#286494c36625ea2eb26f963ed205cd9ca5c41447"
|
Loading…
Reference in New Issue