test(language-service): test @angular/language-service
can be loaded by tsserver.js (#14721)
This commit is contained in:

committed by
Igor Minar

parent
79fc1e3959
commit
7a66a4115b
18
integration/language_service_plugin/tools/tsconfig.json
Normal file
18
integration/language_service_plugin/tools/tsconfig.json
Normal file
@ -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"
|
||||
]
|
||||
}
|
77
integration/language_service_plugin/tools/typescript_host.ts
Normal file
77
integration/language_service_plugin/tools/typescript_host.ts
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user