Skip to content

Commit ac31d6b

Browse files
authored
chore(ls): add integration tests (#8)
1 parent 845b679 commit ac31d6b

27 files changed

+485
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ client/node_modules/
22
client/out/
33
client/server/
44
server/node_modules/
5+
dist/
56
.DS_Store

scripts/ci/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ echo 'travis_fold:start:build.vsix'
3838
(
3939
mkdir dist
4040
cd client
41-
vsce package --out ../dist/ngls-${SHA}
41+
vsce package --out ../dist/ngls.vsix
4242
)
4343
echo 'travis_fold:end:build.vsix'
4444

scripts/ci/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ set -ex -o pipefail
44

55
echo 'travis_fold:start:TEST'
66

7-
# Add tests here
7+
tests/tests.sh
88

99
echo 'travis_fold:end:TEST'

tests/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
These tests are run in CI in `scripts/ci/test.sh`

tests/assets/completion-golden.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"jsonrpc":"2.0","id":1,"result":[{"label":"toString","kind":2,"detail":"method","sortText":"toString","insertText":"toString"},{"label":"charAt","kind":2,"detail":"method","sortText":"charAt","insertText":"charAt"},{"label":"charCodeAt","kind":2,"detail":"method","sortText":"charCodeAt","insertText":"charCodeAt"},{"label":"concat","kind":2,"detail":"method","sortText":"concat","insertText":"concat"},{"label":"indexOf","kind":2,"detail":"method","sortText":"indexOf","insertText":"indexOf"},{"label":"lastIndexOf","kind":2,"detail":"method","sortText":"lastIndexOf","insertText":"lastIndexOf"},{"label":"localeCompare","kind":2,"detail":"method","sortText":"localeCompare","insertText":"localeCompare"},{"label":"match","kind":2,"detail":"method","sortText":"match","insertText":"match"},{"label":"replace","kind":2,"detail":"method","sortText":"replace","insertText":"replace"},{"label":"search","kind":2,"detail":"method","sortText":"search","insertText":"search"},{"label":"slice","kind":2,"detail":"method","sortText":"slice","insertText":"slice"},{"label":"split","kind":2,"detail":"method","sortText":"split","insertText":"split"},{"label":"substring","kind":2,"detail":"method","sortText":"substring","insertText":"substring"},{"label":"toLowerCase","kind":2,"detail":"method","sortText":"toLowerCase","insertText":"toLowerCase"},{"label":"toLocaleLowerCase","kind":2,"detail":"method","sortText":"toLocaleLowerCase","insertText":"toLocaleLowerCase"},{"label":"toUpperCase","kind":2,"detail":"method","sortText":"toUpperCase","insertText":"toUpperCase"},{"label":"toLocaleUpperCase","kind":2,"detail":"method","sortText":"toLocaleUpperCase","insertText":"toLocaleUpperCase"},{"label":"trim","kind":2,"detail":"method","sortText":"trim","insertText":"trim"},{"label":"length","kind":10,"detail":"property","sortText":"length","insertText":"length"},{"label":"substr","kind":2,"detail":"method","sortText":"substr","insertText":"substr"},{"label":"valueOf","kind":2,"detail":"method","sortText":"valueOf","insertText":"valueOf"},{"label":"codePointAt","kind":2,"detail":"method","sortText":"codePointAt","insertText":"codePointAt"},{"label":"includes","kind":2,"detail":"method","sortText":"includes","insertText":"includes"},{"label":"endsWith","kind":2,"detail":"method","sortText":"endsWith","insertText":"endsWith"},{"label":"normalize","kind":2,"detail":"method","sortText":"normalize","insertText":"normalize"},{"label":"repeat","kind":2,"detail":"method","sortText":"repeat","insertText":"repeat"},{"label":"startsWith","kind":2,"detail":"method","sortText":"startsWith","insertText":"startsWith"},{"label":"anchor","kind":2,"detail":"method","sortText":"anchor","insertText":"anchor"},{"label":"big","kind":2,"detail":"method","sortText":"big","insertText":"big"},{"label":"blink","kind":2,"detail":"method","sortText":"blink","insertText":"blink"},{"label":"bold","kind":2,"detail":"method","sortText":"bold","insertText":"bold"},{"label":"fixed","kind":2,"detail":"method","sortText":"fixed","insertText":"fixed"},{"label":"fontcolor","kind":2,"detail":"method","sortText":"fontcolor","insertText":"fontcolor"},{"label":"fontsize","kind":2,"detail":"method","sortText":"fontsize","insertText":"fontsize"},{"label":"italics","kind":2,"detail":"method","sortText":"italics","insertText":"italics"},{"label":"link","kind":2,"detail":"method","sortText":"link","insertText":"link"},{"label":"small","kind":2,"detail":"method","sortText":"small","insertText":"small"},{"label":"strike","kind":2,"detail":"method","sortText":"strike","insertText":"strike"},{"label":"sub","kind":2,"detail":"method","sortText":"sub","insertText":"sub"},{"label":"sup","kind":2,"detail":"method","sortText":"sup","insertText":"sup"}]},{"jsonrpc":"2.0","id":2,"result":null}]

tests/assets/completion-test.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":76833,"rootPath":"$$PWD$$/project","capabilities":{},"trace":"off"}},
2+
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file://$$PWD$$/project/app/app.component.ts","languageId":"typescript","version":1,"text":"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"}}},
3+
{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file://$$PWD$$/project/app/app.component.ts","version":2},"contentChanges":[{"range":{"start":{"line":4,"character":29},"end":{"line":4,"character":29}},"rangeLength":0,"text":"."}]}},
4+
{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file://$$PWD$$/project/app/app.component.ts"},"position":{"line":4,"character":30}}},
5+
{"jsonrpc":"2.0","id":2,"method":"shutdown"},
6+
{"jsonrpc":"2.0","method":"exit"}]

tests/assets/startup-golden.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"jsonrpc":"2.0","id":2,"result":null}]

tests/assets/startup-test.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":6300,"rootPath":"$$PWD$$/project","capabilities":{},"trace":"off"}},
3+
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file://$$PWD$$/project/app/app.component.ts","languageId":"typescript","version":1,"text":"import { Component } from '@angular/core';\n\n@Component({\n selector: 'my-app',\n template:\n`<h1>Hello {{name}}</h1>`,\n)\nexport class AppComponent { name = 'Angular'; }\n"}}},
4+
{"jsonrpc":"2.0","id":2,"method":"shutdown"},
5+
{"jsonrpc":"2.0","method":"exit"}
6+
]

tests/project/.editorconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
12+
[*.md]
13+
max_line_length = 0
14+
trim_trailing_whitespace = false
15+
16+
# Indentation override
17+
#[lib/**.js]
18+
#[{package.json,.travis.yml}]
19+
#[**/**.js]

tests/project/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.idea
2+
node_modules
3+
jspm_packages
4+
npm-debug.*
5+
link-checker-results.txt
6+
app/**/*.js
7+
*.js.map
8+
e2e/**/*.js
9+
e2e/**/*.js.map
10+
_test-output
11+
_temp

tests/project/.travis.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
dist: trusty
2+
sudo: required
3+
language: node_js
4+
node_js:
5+
- "5"
6+
os:
7+
- linux
8+
env:
9+
global:
10+
- DBUS_SESSION_BUS_ADDRESS=/dev/null
11+
- DISPLAY=:99.0
12+
- CHROME_BIN=chromium-browser
13+
before_script:
14+
- sh -e /etc/init.d/xvfb start
15+
install:
16+
- npm install
17+
script:
18+
- npm run lint
19+
- npm run test-once
20+
- npm run e2e
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { AppComponent } from './app.component';
2+
3+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4+
import { By } from '@angular/platform-browser';
5+
import { DebugElement } from '@angular/core';
6+
7+
describe('AppComponent', function () {
8+
let de: DebugElement;
9+
let comp: AppComponent;
10+
let fixture: ComponentFixture<AppComponent>;
11+
12+
beforeEach(async(() => {
13+
TestBed.configureTestingModule({
14+
declarations: [ AppComponent ]
15+
})
16+
.compileComponents();
17+
}));
18+
19+
beforeEach(() => {
20+
fixture = TestBed.createComponent(AppComponent);
21+
comp = fixture.componentInstance;
22+
de = fixture.debugElement.query(By.css('h1'));
23+
});
24+
25+
it('should create component', () => expect(comp).toBeDefined() );
26+
27+
it('should have expected <h1> text', () => {
28+
fixture.detectChanges();
29+
const h1 = de.nativeElement;
30+
expect(h1.innerText).toMatch(/angular/i,
31+
'<h1> should say something about "Angular"');
32+
});
33+
});

tests/project/app/app.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'my-app',
5+
template: `<h1>Hello {{name}}</h1>`,
6+
})
7+
export class AppComponent { name = 'Angular'; }

tests/project/app/app.module.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
4+
import { AppComponent } from './app.component';
5+
6+
@NgModule({
7+
imports: [ BrowserModule ],
8+
declarations: [ AppComponent ],
9+
bootstrap: [ AppComponent ]
10+
})
11+
export class AppModule { }

tests/project/app/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2+
3+
import { AppModule } from './app.module';
4+
5+
platformBrowserDynamic().bootstrapModule(AppModule);

tests/project/index.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Angular QuickStart</title>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<link rel="stylesheet" href="styles.css">
8+
9+
<!-- Polyfill(s) for older browsers -->
10+
<script src="node_modules/core-js/client/shim.min.js"></script>
11+
12+
<script src="node_modules/zone.js/dist/zone.js"></script>
13+
<script src="node_modules/reflect-metadata/Reflect.js"></script>
14+
<script src="node_modules/systemjs/dist/system.src.js"></script>
15+
16+
<script src="systemjs.config.js"></script>
17+
<script>
18+
System.import('app').catch(function(err){ console.error(err); });
19+
</script>
20+
</head>
21+
22+
<body>
23+
<my-app>Loading AppComponent content here ...</my-app>
24+
</body>
25+
</html>

tests/project/package.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"name": "angular-quickstart",
3+
"version": "1.0.0",
4+
"description": "QuickStart package.json from the documentation, supplemented with testing support",
5+
"scripts": {
6+
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
7+
"e2e": "tsc && concurrently \"http-server -s\" \"protractor protractor.config.js\" --kill-others --success first",
8+
"lint": "tslint ./app/**/*.ts -t verbose",
9+
"lite": "lite-server",
10+
"pree2e": "webdriver-manager update",
11+
"test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
12+
"test-once": "tsc && karma start karma.conf.js --single-run",
13+
"tsc": "tsc",
14+
"tsc:w": "tsc -w"
15+
},
16+
"keywords": [],
17+
"author": "",
18+
"license": "MIT",
19+
"dependencies": {
20+
"@angular/common": "~2.2.0",
21+
"@angular/compiler": "~2.2.0",
22+
"@angular/core": "~2.2.0",
23+
"@angular/forms": "~2.2.0",
24+
"@angular/http": "~2.2.0",
25+
"@angular/platform-browser": "~2.2.0",
26+
"@angular/platform-browser-dynamic": "~2.2.0",
27+
"@angular/router": "~3.2.0",
28+
29+
"angular-in-memory-web-api": "~0.1.15",
30+
"systemjs": "0.19.40",
31+
"core-js": "^2.4.1",
32+
"reflect-metadata": "^0.1.8",
33+
"rxjs": "5.0.0-beta.12",
34+
"zone.js": "^0.6.26"
35+
},
36+
"devDependencies": {
37+
"concurrently": "^3.1.0",
38+
"lite-server": "^2.2.2",
39+
"typescript": "^2.0.10",
40+
41+
"canonical-path": "0.0.2",
42+
"http-server": "^0.9.0",
43+
"tslint": "^3.15.1",
44+
"lodash": "^4.16.4",
45+
"jasmine-core": "~2.4.1",
46+
"karma": "^1.3.0",
47+
"karma-chrome-launcher": "^2.0.0",
48+
"karma-cli": "^1.0.1",
49+
"karma-jasmine": "^1.0.2",
50+
"karma-jasmine-html-reporter": "^0.2.2",
51+
"protractor": "4.0.9",
52+
"webdriver-manager": "10.2.5",
53+
"rimraf": "^2.5.4",
54+
55+
"@types/node": "^6.0.46",
56+
"@types/jasmine": "^2.5.36",
57+
"@types/selenium-webdriver": "^2.53.33"
58+
},
59+
"repository": {}
60+
}

tests/project/styles.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
h1 {
2+
color: #369;
3+
font-family: Arial, Helvetica, sans-serif;
4+
font-size: 250%;
5+
}

tests/project/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"module": "commonjs",
5+
"moduleResolution": "node",
6+
"sourceMap": true,
7+
"emitDecoratorMetadata": true,
8+
"experimentalDecorators": true,
9+
"lib": [ "es2015", "dom" ],
10+
"noImplicitAny": true,
11+
"suppressImplicitAnyIndexErrors": true
12+
}
13+
}

tests/tests.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex -o pipefail
4+
5+
cd $(dirname $0)
6+
7+
echo build the tools
8+
(
9+
cd tools
10+
npm install
11+
$(npm bin)/tsc
12+
)
13+
14+
echo npm install on the project
15+
(
16+
cd project
17+
npm install
18+
)
19+
20+
echo run startup test
21+
(
22+
node tools/dist/mock-host --file assets/startup-test.json --pwd $(pwd) | node ../client/server/server.js --stdio | node tools/dist/validate-expected --expect assets/startup-golden.json
23+
)
24+
25+
echo run completion test
26+
(
27+
node tools/dist/mock-host --file assets/completion-test.json --pwd $(pwd) | node ../client/server/server.js --stdio | node tools/dist/validate-expected --expect assets/completion-golden.json
28+
)

tests/tools/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
dist/

tests/tools/.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
"typescript.tsdk": "node_modules/typescript/lib"
4+
}

tests/tools/adapters/adapters.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type Thenable<T> = PromiseLike<T>;

tests/tools/mock-host/index.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as fs from 'fs';
2+
import * as rpc from 'vscode-jsonrpc';
3+
import * as minimist from 'minimist';
4+
5+
const RE_PWD = /\$\$PWD\$\$/g;
6+
7+
let errorsDetected = false;
8+
9+
function reportError(arg: string): boolean {
10+
console.error(`Unknown argument: ${arg}`);
11+
errorsDetected = true;
12+
return false;
13+
}
14+
15+
function help() {
16+
console.log('Mock host')
17+
console.log(`${process.argv[1]} --file <file-name> [--pwd <pwd>]`);
18+
console.log(`
19+
Send JSON message using the JSON RPC protocol to stdout.
20+
`)
21+
}
22+
23+
let args = minimist(process.argv.slice(2), { string: ['file', 'pwd'], unknown: reportError });
24+
25+
if (errorsDetected) {
26+
help();
27+
process.exit(1);
28+
}
29+
30+
const file = args['file'];
31+
if (!file) {
32+
console.log('stdin form not supported yet.')
33+
process.exit(1);
34+
}
35+
36+
var writer = new rpc.StreamMessageWriter(process.stdout);
37+
38+
try {
39+
let content = fs.readFileSync(file, 'utf8');
40+
if (args['pwd']) {
41+
content = content.replace(RE_PWD, args['pwd']);
42+
}
43+
const json = JSON.parse(content);
44+
45+
if (Array.isArray(json)) {
46+
for (const message of json) {
47+
writer.write(message as any);
48+
}
49+
}
50+
} catch(e) {
51+
console.error(`Error: ${e.message}`);
52+
process.exit(2);
53+
}

tests/tools/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "tools",
3+
"version": "0.0.0",
4+
"description": "Tools package for the Angular language service",
5+
"devDependencies": {
6+
"@types/minimist": "^1.1.29",
7+
"@types/node": "0.0.2",
8+
"minimist": "^1.2.0",
9+
"typescript": "^2.1.4",
10+
"vscode-jsonrpc": "^2.4.0"
11+
}
12+
}

tests/tools/tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"target": "es5",
5+
"noImplicitAny": true,
6+
"sourceMap": true,
7+
"noImplicitThis": true,
8+
"noFallthroughCasesInSwitch": true,
9+
"noUnusedLocals": true,
10+
"noUnusedParameters": true,
11+
"strictNullChecks": true,
12+
"lib": ["es6"],
13+
"outDir": "dist"
14+
}
15+
}

0 commit comments

Comments
 (0)