Skip to content

Commit

Permalink
feature(server) - Add support for Ref in hover and autocomplete (#248)
Browse files Browse the repository at this point in the history
* Support Ref functions for hover/autocomplete
  • Loading branch information
kddejong committed Nov 13, 2022
1 parent b393cf0 commit 277f018
Show file tree
Hide file tree
Showing 8 changed files with 537 additions and 86 deletions.
205 changes: 139 additions & 66 deletions client/src/test/suite/completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,81 @@ import * as vscode from "vscode";
import assert = require("assert");
import { getDocUri, activate } from "./helper";

suite("Should code complete", () => {
const docUri = getDocUri("completion", "completion.yaml");
const intrinsics = [
{
label: "!And",
kind: 11,
},
{
label: "!Base64",
kind: 11,
},
{
label: "!Cidr",
kind: 11,
},
{
label: "!Equals",
kind: 11,
},
{
label: "!FindInMap",
kind: 11,
},
{
label: "!GetAtt",
kind: 11,
},
{
label: "!GetAZs",
kind: 11,
},
{
label: "!If",
kind: 11,
},
{
label: "!ImportValue",
kind: 11,
},
{
label: "!Join",
kind: 11,
},
{
label: "!Not",
kind: 11,
},
{
label: "!Or",
kind: 11,
},
{
label: "!Ref",
kind: 11,
},
{
label: "!Select",
kind: 11,
},
{
label: "!Split",
kind: 11,
},
{
label: "!Sub",
kind: 11,
},
];

suite("Should code complete", () => {
test("Complete on empty template", async () => {
const docUri = getDocUri("completion", "completion.yaml");
await activate(docUri);

await testCompletion(docUri, new vscode.Position(0, 0), {
items: [
{
label: "!And",
kind: 11,
},
{
label: "!Base64",
kind: 11,
},
{
label: "!Cidr",
kind: 11,
},
{
label: "!Equals",
kind: 11,
},
{
label: "!FindInMap",
kind: 11,
},
{
label: "!GetAtt",
kind: 11,
},
{
label: "!GetAZs",
kind: 11,
},
{
label: "!If",
kind: 11,
},
{
label: "!ImportValue",
kind: 11,
},
{
label: "!Join",
kind: 11,
},
{
label: "!Not",
kind: 11,
},
{
label: "!Or",
kind: 11,
},
{
label: "!Ref",
kind: 11,
},
{
label: "!Select",
kind: 11,
},
{
label: "!Split",
kind: 11,
},
{
label: "!Sub",
kind: 11,
},
...intrinsics,
{
label: "object",
kind: 6,
Expand Down Expand Up @@ -125,6 +128,76 @@ suite("Should code complete", () => {
],
});
});

test("Complete on ref", async () => {
const docUri = getDocUri("completion", "completion2.yaml");
await activate(docUri);

const completion_intrinsics = intrinsics.filter(
(intrinsic) => intrinsic.label !== "!Ref"
);

await testCompletion(docUri, new vscode.Position(17, 19), {
items: [
...completion_intrinsics,
{
label: "Subnet1",
kind: 11,
},
{
label: "Subnet2",
kind: 11,
},
{
label: "RouteTable1",
kind: 11,
},
{
label: "Subnet1RouteTable1",
kind: 11,
},
{
label: "Vpc",
kind: 11,
},
],
});
});

test("Complete with full ref", async () => {
const docUri = getDocUri("completion", "completion2.yaml");
await activate(docUri);

const completion_intrinsics = intrinsics.filter(
(intrinsic) => intrinsic.label !== "!Ref"
);

await testCompletion(docUri, new vscode.Position(21, 22), {
items: [
...completion_intrinsics,
{
label: "!Ref Subnet1",
kind: 11,
},
{
label: "!Ref Subnet2",
kind: 11,
},
{
label: "!Ref RouteTable1",
kind: 11,
},
{
label: "!Ref Subnet1RouteTable1",
kind: 11,
},
{
label: "!Ref Vpc",
kind: 11,
},
],
});
});
});

export async function testCompletion(
Expand Down
23 changes: 23 additions & 0 deletions client/src/test/suite/fixtures/completion/completion2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

Parameters:
Vpc:
Type: AWS::EC2::VPC::Id
Resources:
Subnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
Subnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: V
RouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref V
Subnet1RouteTable1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !R
SubnetId: !Ref Subnet1
24 changes: 24 additions & 0 deletions client/src/test/suite/fixtures/hover/hover.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

Parameters:
Vpc:
Type: AWS::EC2::VPC::Id
Resources:
Subnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
Subnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: Vpc
RouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
Subnet1RouteTable1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable1
SubnetId:
Ref: Subnet1
63 changes: 63 additions & 0 deletions client/src/test/suite/hover.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as vscode from "vscode";
import assert = require("assert");
import { getDocUri, activate } from "./helper";

suite("Should hover", () => {
test("Hover on !Ref to parameter", async () => {
const docUri = getDocUri("hover", "hover.yaml");
await activate(docUri);

await testHover(
docUri,
new vscode.Position(17, 20),
"\n```\n(Parameter) Vpc: AWS::EC2::VPC::Id\n```\n"
);
});
test("Hover on !Ref to resource", async () => {
const docUri = getDocUri("hover", "hover.yaml");
await activate(docUri);

await testHover(
docUri,
new vscode.Position(21, 31),
"\n```\n(Resource) RouteTable1: AWS::EC2::RouteTable\n```\n"
);
});
test("Hover on Ref: to resource", async () => {
const docUri = getDocUri("hover", "hover.yaml");
await activate(docUri);

await testHover(
docUri,
new vscode.Position(23, 17),
"\n```\n(Resource) Subnet1: AWS::EC2::Subnet\n```\n"
);
});
test("Hover on Ref: to parameter", async () => {
const docUri = getDocUri("hover", "hover.yaml");
await activate(docUri);

await testHover(
docUri,
new vscode.Position(13, 15),
"\n```\n(Parameter) Vpc: AWS::EC2::VPC::Id\n```\n"
);
});
});

export async function testHover(
docUri: vscode.Uri,
position: vscode.Position,
expectedHover: string
): Promise<void> {
// Executing the command `vscode.executeHoverProvider` to simulate triggering hover
const actualHovers = (await vscode.commands.executeCommand(
"vscode.executeHoverProvider",
docUri,
position
)) as vscode.Hover[];

const actualHover = actualHovers[0];
const gotMessage = (<vscode.MarkdownString>actualHover.contents[0]).value;
assert.equal(expectedHover, gotMessage);
}
27 changes: 10 additions & 17 deletions server/src/cfnSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,25 @@ export class SettingsState extends YamlSettingsState {
constructor() {
super();
this.customTags = [
"!And",
"!And sequence",
"!If",
"!If sequence",
"!Not",
"!Not sequence",
"!Equals",
"!Equals sequence",
"!Or",
"!Or sequence",
"!FindInMap",
"!FindInMap sequence",
"!Base64",
"!Join",
"!Base64 scalar",
"!Join sequence",
"!Cidr",
"!Ref",
"!Sub",
"!Cidr sequence",
"!Ref scalar",
"!Sub scalar",
"!Sub sequence",
"!GetAtt",
"!GetAZs",
"!ImportValue",
"!ImportValue sequence",
"!Select",
"!GetAtt scalar",
"!GetAtt sequence",
"!GetAZs mapping",
"!GetAZs scalar",
"!ImportValue mapping",
"!ImportValue scalar",
"!Select sequence",
"!Split",
"!Split sequence",
];
this.schemaStoreEnabled = false;
Expand Down
Loading

0 comments on commit 277f018

Please sign in to comment.