Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Commit

Permalink
adding diagnostic command to check command Ids and fixing typo in tes… (
Browse files Browse the repository at this point in the history
#121)

* adding diagnostic command to check command Ids and fixing typo in test name
* removing extra paren in output message
* updating validation to provide better feedback
* adding ellipsis to the starting line to hint at an ongoing process
* removing generic group name in favor of a didact specific one
* revamping validation for easier testing and addressing PR feedback
* massaging the tests and adding new negative test

Signed-off-by: bfitzpat@redhat.com <bfitzpat@redhat.com>
  • Loading branch information
bfitzpat authored May 14, 2020
1 parent 568c5af commit 1d2f8fb
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 24 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ All notable changes to the "vscode-didact" extension will be documented in this

## 0.1.15

- TBD
- Adding "Validate Didact File" command to provide diagnostic validation
- Adding title-level context menu item to Markdown and AsciiDoc editors to call validation

## 0.1.14

Expand Down
11 changes: 11 additions & 0 deletions demos/markdown/validation-test.didact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Didact Command Validation

Though a command ID referenced in one VS Code environment may be valid, it may not exist in another. We now have a validation step that ensures that all command IDs found in Didact links are valid.

## Valid

Open the Command Palette now, using `Ctrl+Shift+P` on your keyboard. Or [click here](didact://?commandId=workbench.action.showCommands)

## Invalid

This command does not exist. [Click here](didact://?commandId=invalid.command.specified)
17 changes: 15 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@
"dark": "resources/dark/refresh.svg",
"light": "resources/light/refresh.svg"
}
},
{
"command": "vscode.didact.verifyCommands",
"title": "Validate Didact File",
"when": "resourceFilename =~ /[.](didact)[.](md|adoc)$/"
}
],
"keybindings": [
Expand All @@ -112,12 +117,12 @@
{
"command": "vscode.didact.startDidact",
"when": "resourceFilename =~ /[.](didact)[.](md|adoc)$/",
"group": "vscode.didact.group"
"group": "vscode.didact.group@1"
},
{
"command": "vscode.didact.scaffoldProject",
"when": "resourceExtname =~ /\\.json$/",
"group": "vscode.didact.group"
"group": "vscode.didact.group@2"
}
],
"view/item/context": [
Expand All @@ -138,6 +143,14 @@
"when": "view == didact.tutorials",
"group": "navigation"
}
],
"editor/title": [
{
"when": "resourceFilename =~ /[.](didact)[.](md|adoc)$/",
"command": "vscode.didact.verifyCommands",
"alt": "vscode.didact.verifyCommands",
"group": "didact.editor"
}
]
},
"snippets": [
Expand Down
1 change: 1 addition & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand(commandConstants.SEND_TERMINAL_KEY_SEQUENCE, extensionFunctions.sendTerminalCtrlC));
context.subscriptions.push(vscode.commands.registerCommand(commandConstants.CLOSE_TERMINAL, extensionFunctions.closeTerminal));
context.subscriptions.push(vscode.commands.registerCommand(commandConstants.CLI_SUCCESS_COMMAND, extensionFunctions.cliExecutionCheck));
context.subscriptions.push(vscode.commands.registerCommand(commandConstants.VALIDATE_COMMAND_IDS, extensionFunctions.validateCommandIDsInSelectedFile));

// set up the vscode URI handler
vscode.window.registerUriHandler({
Expand Down
65 changes: 65 additions & 0 deletions src/extensionFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {parseADtoHTML} from './asciidocUtils';
import * as scaffoldUtils from './scaffoldUtils';
import { TreeNode } from './nodeProvider';
import { handleExtFilePath } from './commandHandler';
import * as url from 'url';

let didactOutputChannel: vscode.OutputChannel | undefined = undefined;

Expand All @@ -53,6 +54,7 @@ export const REFRESH_DIDACT_VIEW = 'vscode.didact.view.refresh';
export const SEND_TERMINAL_KEY_SEQUENCE = 'vscode.didact.sendNamedTerminalCtrlC';
export const CLOSE_TERMINAL = 'vscode.didact.closeNamedTerminal';
export const CLI_SUCCESS_COMMAND = 'vscode.didact.cliCommandSuccessful';
export const VALIDATE_COMMAND_IDS = 'vscode.didact.verifyCommands';

export const DIDACT_OUTPUT_CHANNEL = 'Didact Activity';

Expand Down Expand Up @@ -599,4 +601,67 @@ export namespace extensionFunctions {
console.log('[' + msg + ']');
}
}

// exported for testing
export async function validateDidactCommands(commands : any[]) : Promise<boolean> {
let allOk = true;
if (commands && commands.length > 0) {
sendTextToOutputChannel(`Starting validation...`);
const vsCommands : string[] = await vscode.commands.getCommands(true);
for(let command of commands) {
// validate all commands we found
const parsedUrl = url.parse(command, true);
const query = parsedUrl.query;
if (query.commandId) {
const commandId = utils.getValue(query.commandId);
if (commandId) {
let foundCommand = validateCommand(commandId, vsCommands);
if (foundCommand) {
// expected result - we found the command in the vscode command list
} else {
// unexpected result - let the user know
sendTextToOutputChannel(`--Missing Command ID ${commandId}.`);
allOk = false;
}
}
}
}
}
return allOk;
}

// exported for testing
export function validateCommand(commandId:string, vsCommands:string[]) : boolean {
if (commandId) {
var filteredList : string[] = vsCommands.filter( function (command) {
return command === commandId;
});
if (filteredList.length >= 1) {
return true;
}
}
return false;
}

export async function validateCommandIDsInSelectedFile(didactUri: vscode.Uri) : Promise<void> {
if (didactUri) {
await vscode.commands.executeCommand(START_DIDACT_COMMAND, didactUri);
}
if (DidactWebviewPanel.currentPanel) {
const commands : any[] = extensionFunctions.gatherAllCommandsLinks();
let allOk = false;
if (commands && commands.length > 0) {
allOk = await validateDidactCommands(commands);
if (allOk) {
sendTextToOutputChannel(`--Command IDs: OK`);
sendTextToOutputChannel(`Validation Result: SUCCESS`);
} else {
sendTextToOutputChannel(`Validation Result: FAILURE`);
sendTextToOutputChannel(`-- Note that command IDs not found may be due to a missing extension or simply an invalid ID.`);
}
} else {
sendTextToOutputChannel(`Validation Result: FAILURE - No command IDs found in current Didact file`);
}
}
}
}
44 changes: 24 additions & 20 deletions src/test/suite/didact.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as commandHandler from '../../commandHandler';

const testMD = vscode.Uri.parse('vscode://redhat.vscode-didact?extension=demos/markdown/didact-demo.didact.md');
const testMD2 = vscode.Uri.parse('vscode://redhat.vscode-didact?extension=demos/markdown/simple-example.didact.md');
const testMD3 = vscode.Uri.parse('vscode://redhat.vscode-didact?extension=demos/markdown/validation-test.didact.md');
const testExt = 'didact://?commandId=vscode.didact.extensionRequirementCheck&text=some-field-to-update$$redhat.vscode-didact';
const testReq = 'didact://?commandId=vscode.didact.requirementCheck&text=os-requirements-status$$uname$$Linux&completion=Didact%20is%20running%20on%20a%20Linux%20machine.';
const testReqCli = 'didact://?commandId=vscode.didact.cliCommandSuccessful&text=maven-cli-return-status$$uname&completion=Didact%20is%20running%20on%20a%20Linux%20machine.';
Expand Down Expand Up @@ -174,32 +175,35 @@ suite('Didact test suite', () => {
await vscode.commands.executeCommand(START_DIDACT_COMMAND, testMD).then( async () => {
if (DidactWebviewPanel.currentPanel) {
const commands : any[] = extensionFunctions.gatherAllCommandsLinks();
assert.equal(commands && commands.length > 0, true);
if (commands && commands.length > 0) {
for(let command of commands) {
// validate all commands
const parsedUrl = url.parse(command, true);
const query = parsedUrl.query;
assert.notEqual(query.commandId, undefined);
if (query.commandId) {
const commandId = getValue(query.commandId);
if (commandId) {
console.log('Looking for ' + commandId);
const vsCommands : string[] = await vscode.commands.getCommands(true);
var filteredList : string[] = vsCommands.filter( function (command) {
return command === commandId;
});
assert.equal(filteredList.length, 1, `Found command ${commandId} in Didact file but command is not found`);
}
assert.strictEqual(commands && commands.length > 0, true);
const isOk = await extensionFunctions.validateDidactCommands(commands);

// if we failed the above, we can do a deeper dive to figure out what command is missing
if (!isOk) {
const vsCommands : string[] = await vscode.commands.getCommands(true);
for (let command of commands) {
let commandOk = extensionFunctions.validateCommand(command, vsCommands);
if (!commandOk) {
console.log(`--Missing Command ID ${command}`);
}
}
} else {
assert.fail('No commands found in VS Code environment.');
}
}
assert.strictEqual(isOk, true, `Missing commands in test file.`);
}
});
});

test('Verify that validation fails when given a negative case', async () => {
await vscode.commands.executeCommand(START_DIDACT_COMMAND, testMD3).then( async () => {
if (DidactWebviewPanel.currentPanel) {
const commands : any[] = extensionFunctions.gatherAllCommandsLinks();
assert.strictEqual(commands && commands.length > 0, true);
const isOk = await extensionFunctions.validateDidactCommands(commands);
assert.strictEqual(isOk, false, `Invalid file should not have passed validation test`);
}
});
});

test('Walk through the demo didact file to ensure that we get all the requirements commands successfully', async () => {
await vscode.commands.executeCommand(START_DIDACT_COMMAND, testMD).then( async () => {
if (DidactWebviewPanel.currentPanel) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/suite/extensionFunctions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ suite('Extension Functions Test Suite', () => {
});
});

test('try executing an ivalid command', async function() {
test('try executing an invalid command', async function() {
await extensionFunctions.cliExecutionCheck('test-bogus','doesnotexist').then( (returnBool) => {
assert.equal(returnBool, false);
});
Expand Down

0 comments on commit 1d2f8fb

Please sign in to comment.