Skip to content

Commit b393cf0

Browse files
authored
Add in prettier style testing and fix files (#247)
1 parent 940d54f commit b393cf0

22 files changed

+1329
-1058
lines changed

.github/workflows/branch-pr-release.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
pip install cfn-lint
3333
pip install pydot
3434
- run: npm run lint
35+
- run: npm run prettier
36+
if: runner.os == 'Linux'
3537
- run: xvfb-run -a npm run test
3638
if: runner.os == 'Linux'
3739
- run: npm run test
Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
1-
declare module 'node-yaml-parser' {
2-
export function parse(text: string): { readonly documents: YamlDocument[]; readonly lineLengths: number[] };
3-
export function findNodeAtPosition(documents: YamlDocument[], lineLengths: number[], line: number, char: number): YamlMatchedElement;
1+
declare module "node-yaml-parser" {
2+
export function parse(text: string): {
3+
readonly documents: YamlDocument[];
4+
readonly lineLengths: number[];
5+
};
6+
export function findNodeAtPosition(
7+
documents: YamlDocument[],
8+
lineLengths: number[],
9+
line: number,
10+
char: number
11+
): YamlMatchedElement;
412

5-
export interface YamlNode {
6-
readonly kind: string;
7-
readonly raw: string;
8-
readonly startPosition: number;
9-
readonly endPosition: number;
10-
readonly parent?: YamlNode;
11-
}
13+
export interface YamlNode {
14+
readonly kind: string;
15+
readonly raw: string;
16+
readonly startPosition: number;
17+
readonly endPosition: number;
18+
readonly parent?: YamlNode;
19+
}
1220

13-
export interface YamlDocument {
14-
readonly nodes: YamlNode[];
15-
readonly errors: string[];
16-
}
21+
export interface YamlDocument {
22+
readonly nodes: YamlNode[];
23+
readonly errors: string[];
24+
}
1725

18-
export interface YamlMatchedElement {
19-
readonly matchedNode: YamlNode;
20-
readonly matchedDocument: YamlDocument;
21-
}
26+
export interface YamlMatchedElement {
27+
readonly matchedNode: YamlNode;
28+
readonly matchedDocument: YamlDocument;
29+
}
2230

23-
export interface Util {
24-
isKey(node: YamlNode): boolean;
25-
}
31+
export interface Util {
32+
isKey(node: YamlNode): boolean;
33+
}
2634

27-
export const util: Util;
28-
}
35+
export const util: Util;
36+
}

client/src/extension.ts

Lines changed: 136 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -12,119 +12,148 @@ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1212
express or implied. See the License for the specific language governing
1313
permissions and limitations under the License.
1414
*/
15-
'use strict';
16-
17-
import * as path from 'path';
18-
import * as fs from 'fs';
19-
import { workspace, ExtensionContext, window, WebviewPanel, Uri, commands, ViewColumn, window as VsCodeWindow } from 'vscode';
20-
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node';
15+
"use strict";
16+
17+
import * as path from "path";
18+
import * as fs from "fs";
19+
import {
20+
workspace,
21+
ExtensionContext,
22+
window,
23+
WebviewPanel,
24+
Uri,
25+
commands,
26+
ViewColumn,
27+
window as VsCodeWindow,
28+
} from "vscode";
29+
import {
30+
LanguageClient,
31+
LanguageClientOptions,
32+
ServerOptions,
33+
TransportKind,
34+
} from "vscode-languageclient/node";
2135

2236
let previews: { [index: string]: WebviewPanel } = {};
2337
let languageClient: LanguageClient;
2438

2539
export async function activate(context: ExtensionContext) {
26-
27-
// The server is implemented in node
28-
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
29-
// The debug options for the server
30-
let debugOptions = { execArgv: ["--nolazy", "--inspect=6010"] };
31-
32-
// If the extension is launched in debug mode then the debug server options are used
33-
// Otherwise the run options are used
34-
let serverOptions: ServerOptions = {
35-
run: { module: serverModule, transport: TransportKind.ipc },
36-
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
37-
};
38-
39-
// Options to control the language client
40-
let clientOptions: LanguageClientOptions = {
41-
// Register the server for plain text documents
42-
documentSelector: [
43-
{ scheme: 'file', language: 'yaml'},
44-
{ scheme: 'file', language: 'json'},
45-
],
46-
synchronize: {
47-
// Synchronize the setting section 'languageServerExample' to the server
48-
configurationSection: 'cfnLint',
49-
// Notify the server about file changes to '.clientrc files contain in the workspace
50-
fileEvents: [
51-
workspace.createFileSystemWatcher('**/.clientrc'),
52-
workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml'),
53-
]
54-
}
55-
};
56-
57-
// Create the language client and start the client.
58-
languageClient = new LanguageClient('cfnLint', 'CloudFormation linter Language Server', serverOptions, clientOptions);
59-
await languageClient.start();
60-
61-
languageClient.onNotification('cfn/busy', () => {
62-
window.showInformationMessage("Linter is already running. Please try again.");
63-
});
64-
languageClient.onNotification('cfn/previewIsAvailable', (uri) => {
65-
reloadSidePreview(uri, languageClient);
66-
});
67-
languageClient.onNotification('cfn/isPreviewable', (value) => {
68-
commands.executeCommand('setContext', 'isPreviewable', value);
69-
});
70-
languageClient.onNotification('cfn/fileclosed', (uri) => {
71-
// if the user closed the template itself, we close the preview
72-
if (previews[uri]) {
73-
previews[uri].dispose();
74-
}
75-
});
76-
77-
let previewDisposable = commands.registerCommand('extension.sidePreview', () => {
78-
79-
if (window.activeTextEditor.document) {
80-
let uri = Uri.file(window.activeTextEditor.document.fileName).toString();
81-
82-
languageClient.sendNotification('cfn/requestPreview', uri);
83-
}
84-
85-
});
86-
87-
context.subscriptions.push(previewDisposable);
88-
40+
// The server is implemented in node
41+
let serverModule = context.asAbsolutePath(
42+
path.join("server", "out", "server.js")
43+
);
44+
// The debug options for the server
45+
let debugOptions = { execArgv: ["--nolazy", "--inspect=6010"] };
46+
47+
// If the extension is launched in debug mode then the debug server options are used
48+
// Otherwise the run options are used
49+
let serverOptions: ServerOptions = {
50+
run: { module: serverModule, transport: TransportKind.ipc },
51+
debug: {
52+
module: serverModule,
53+
transport: TransportKind.ipc,
54+
options: debugOptions,
55+
},
56+
};
57+
58+
// Options to control the language client
59+
let clientOptions: LanguageClientOptions = {
60+
// Register the server for plain text documents
61+
documentSelector: [
62+
{ scheme: "file", language: "yaml" },
63+
{ scheme: "file", language: "json" },
64+
],
65+
synchronize: {
66+
// Synchronize the setting section 'languageServerExample' to the server
67+
configurationSection: "cfnLint",
68+
// Notify the server about file changes to '.clientrc files contain in the workspace
69+
fileEvents: [
70+
workspace.createFileSystemWatcher("**/.clientrc"),
71+
workspace.createFileSystemWatcher("**/*.?(e)y?(a)ml"),
72+
],
73+
},
74+
};
75+
76+
// Create the language client and start the client.
77+
languageClient = new LanguageClient(
78+
"cfnLint",
79+
"CloudFormation linter Language Server",
80+
serverOptions,
81+
clientOptions
82+
);
83+
await languageClient.start();
84+
85+
languageClient.onNotification("cfn/busy", () => {
86+
window.showInformationMessage(
87+
"Linter is already running. Please try again."
88+
);
89+
});
90+
languageClient.onNotification("cfn/previewIsAvailable", (uri) => {
91+
reloadSidePreview(uri, languageClient);
92+
});
93+
languageClient.onNotification("cfn/isPreviewable", (value) => {
94+
commands.executeCommand("setContext", "isPreviewable", value);
95+
});
96+
languageClient.onNotification("cfn/fileclosed", (uri) => {
97+
// if the user closed the template itself, we close the preview
98+
if (previews[uri]) {
99+
previews[uri].dispose();
100+
}
101+
});
102+
103+
let previewDisposable = commands.registerCommand(
104+
"extension.sidePreview",
105+
() => {
106+
if (window.activeTextEditor.document) {
107+
let uri = Uri.file(
108+
window.activeTextEditor.document.fileName
109+
).toString();
110+
111+
languageClient.sendNotification("cfn/requestPreview", uri);
112+
}
113+
}
114+
);
115+
116+
context.subscriptions.push(previewDisposable);
89117
}
90118

91119
function reloadSidePreview(file: string, languageClient: LanguageClient) {
92-
let uri = Uri.parse(file);
93-
let stringifiedUri = uri.toString();
94-
let dotFile = uri.fsPath + ".dot";
95-
96-
if (!fs.existsSync(dotFile)) {
97-
window.showErrorMessage("Error previewing graph. Please run `pip3 install cfn-lint pydot --upgrade`");
98-
return;
99-
}
100-
let content = fs.readFileSync(dotFile, 'utf8');
101-
102-
if (!previews[stringifiedUri]) {
103-
previews[stringifiedUri] = VsCodeWindow.createWebviewPanel(
104-
'cfnLintPreview', // Identifies the type of the webview. Used internally
105-
'Template: ' + dotFile.slice(0, -4), // Title of the panel displayed to the user
106-
ViewColumn.Two, // Editor column to show the new webview panel in.
107-
{
108-
enableScripts: true,
109-
}
110-
);
111-
previews[stringifiedUri].onDidDispose(() => {
112-
// if the user closed the preview
113-
delete previews[stringifiedUri];
114-
fs.unlinkSync(dotFile);
115-
languageClient.sendNotification('cfn/previewClosed', stringifiedUri);
116-
});
117-
}
118-
119-
const panel = previews[stringifiedUri];
120-
panel.webview.html = getPreviewContent(content);
120+
let uri = Uri.parse(file);
121+
let stringifiedUri = uri.toString();
122+
let dotFile = uri.fsPath + ".dot";
123+
124+
if (!fs.existsSync(dotFile)) {
125+
window.showErrorMessage(
126+
"Error previewing graph. Please run `pip3 install cfn-lint pydot --upgrade`"
127+
);
128+
return;
129+
}
130+
let content = fs.readFileSync(dotFile, "utf8");
131+
132+
if (!previews[stringifiedUri]) {
133+
previews[stringifiedUri] = VsCodeWindow.createWebviewPanel(
134+
"cfnLintPreview", // Identifies the type of the webview. Used internally
135+
"Template: " + dotFile.slice(0, -4), // Title of the panel displayed to the user
136+
ViewColumn.Two, // Editor column to show the new webview panel in.
137+
{
138+
enableScripts: true,
139+
}
140+
);
141+
previews[stringifiedUri].onDidDispose(() => {
142+
// if the user closed the preview
143+
delete previews[stringifiedUri];
144+
fs.unlinkSync(dotFile);
145+
languageClient.sendNotification("cfn/previewClosed", stringifiedUri);
146+
});
147+
}
148+
149+
const panel = previews[stringifiedUri];
150+
panel.webview.html = getPreviewContent(content);
121151
}
122152

123153
function getPreviewContent(content: String): string {
124-
125-
let multilineString = "`" + content + "`";
126-
// FIXME is there a better way of converting from dot to svg that is not using cdn urls?
127-
return `
154+
let multilineString = "`" + content + "`";
155+
// FIXME is there a better way of converting from dot to svg that is not using cdn urls?
156+
return `
128157
<!DOCTYPE html>
129158
<body>
130159
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3.min.js" integrity="sha256-Xb6SSzhH3wEPC4Vy3W70Lqh9Y3Du/3KxPqI2JHQSpTw=" crossorigin="anonymous"></script>
@@ -143,8 +172,8 @@ function getPreviewContent(content: String): string {
143172
}
144173

145174
export function deactivate(): Thenable<void> | undefined {
146-
if (!languageClient) {
147-
return undefined;
148-
}
149-
return languageClient.stop();
150-
}
175+
if (!languageClient) {
176+
return undefined;
177+
}
178+
return languageClient.stop();
179+
}

client/src/test/runTest.ts

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1-
import * as path from 'path';
1+
import * as path from "path";
22
import * as os from "os";
3-
import { downloadAndUnzipVSCode,
4-
runTests,
5-
} from '@vscode/test-electron';
3+
import { downloadAndUnzipVSCode, runTests } from "@vscode/test-electron";
64

75
async function main() {
8-
try {
9-
// The folder containing the Extension Manifest package.json
10-
// Passed to `--extensionDevelopmentPath`
11-
const extensionDevelopmentPath = path.resolve(__dirname, '../../../');
6+
try {
7+
// The folder containing the Extension Manifest package.json
8+
// Passed to `--extensionDevelopmentPath`
9+
const extensionDevelopmentPath = path.resolve(__dirname, "../../../");
1210

13-
// The path to the extension test runner script
14-
// Passed to --extensionTestsPath
15-
const extensionTestsPath = path.resolve(__dirname, './suite/index');
11+
// The path to the extension test runner script
12+
// Passed to --extensionTestsPath
13+
const extensionTestsPath = path.resolve(__dirname, "./suite/index");
1614

17-
const vscodeExecutablePath = await downloadAndUnzipVSCode('1.69.1');
15+
const vscodeExecutablePath = await downloadAndUnzipVSCode("1.69.1");
1816

19-
// Download VS Code, unzip it and run the integration test
20-
await runTests({
21-
vscodeExecutablePath,
22-
extensionDevelopmentPath,
23-
extensionTestsPath,
24-
launchArgs: ['--disable-extensions', '--user-data-dir', `${os.tmpdir()}`],
25-
});
26-
} catch (err) {
27-
console.error(`Failed to run tests: ${err}`);
28-
process.exit(1);
29-
}
17+
// Download VS Code, unzip it and run the integration test
18+
await runTests({
19+
vscodeExecutablePath,
20+
extensionDevelopmentPath,
21+
extensionTestsPath,
22+
launchArgs: ["--disable-extensions", "--user-data-dir", `${os.tmpdir()}`],
23+
});
24+
} catch (err) {
25+
console.error(`Failed to run tests: ${err}`);
26+
process.exit(1);
27+
}
3028
}
3129

32-
main();
30+
main();

0 commit comments

Comments
 (0)