Skip to content

Commit

Permalink
Add additional tests and refactored query function
Browse files Browse the repository at this point in the history
  • Loading branch information
j--wong committed Jan 2, 2017
1 parent a0c5037 commit 4ec2147
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test", "--new-window" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
Expand Down
3 changes: 2 additions & 1 deletion src/jmespathMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerTextEditorCommand("jmespath.query",
(textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => {
queryJson(context);
let outputChannel = vscode.window.createOutputChannel("JMESPath Output");
queryJson(context, outputChannel);
}
)
);
Expand Down
19 changes: 10 additions & 9 deletions src/jmespathQuery.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
"use strict";

import * as vscode from "vscode";
let jmespath = require("jmespath");

let outputChannel = vscode.window.createOutputChannel("JMESPath Output");

export function queryJson(context: vscode.ExtensionContext) {
export function queryJson(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel): PromiseLike<void> {
let editor = vscode.window.activeTextEditor;

if (editor.document.languageId !== "json") {
vscode.window.showInformationMessage("Please open a JSON document.");
return;
return Promise.resolve();
}

let options: vscode.InputBoxOptions = {
prompt: "Enter JMESPath expression",
placeHolder: "JMESPath expression"
};

vscode.window.showInputBox(options).then((expression) => {
if (expression.trim().length === 0) {
return;
return vscode.window.showInputBox(options).then((expression) => {
if (expression === undefined || expression.trim().length === 0) {
vscode.window.showInformationMessage("Please enter a valid JMESPath expression.");
return Promise.resolve();
}

try {
jmespath.compile(expression);
}
catch (e) {
vscode.window.showErrorMessage(`${e.message}`);
return;
return Promise.resolve();
}

let data = vscode.window.activeTextEditor.document.getText();
Expand All @@ -39,7 +40,7 @@ export function queryJson(context: vscode.ExtensionContext) {
outputChannel.show();
} catch (e) {
vscode.window.showErrorMessage(`${e.message}`);
return;
return Promise.resolve();
}
});
}
Empty file added test/data/empty.json
Empty file.
8 changes: 8 additions & 0 deletions test/data/locations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"locations": [
{"name": "Seattle", "state": "WA"},
{"name": "New York", "state": "NY"},
{"name": "Bellevue", "state": "WA"},
{"name": "Olympia", "state": "WA"}
]
}
146 changes: 146 additions & 0 deletions test/jmespathQuery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
"use strict";

import * as vscode from "vscode";
import * as path from "path";
import * as jmespathQuery from "../src/jmespathQuery";
import * as assert from "assert";
import * as sinon from "sinon";
import chai = require("chai");

let expect = chai.expect;
let jmespath = require("jmespath");

let testDataPath = path.join(__dirname, "..", "..", "test", "data");
let testJsonFile = path.join(testDataPath, "locations.json");
let emptyJsonFile = path.join(testDataPath, "empty.json");

describe("jmespathQuery", () => {

describe("#queryJson()", () => {
let context: vscode.ExtensionContext;
let sandbox: sinon.SinonSandbox;
let showInputBox: sinon.SinonStub;
let showInformationMessage: sinon.SinonStub;
let showErrorMessage: sinon.SinonStub;
let jmespathCompile: sinon.SinonStub;

let createOutputChannel: sinon.SinonStub;
let outputChannel: vscode.OutputChannel, outputBuffer;

beforeEach(() => {
context = {
subscriptions: [],
workspaceState: null,
globalState: null,
extensionPath: null,
asAbsolutePath: sinon.stub()
};

sandbox = sinon.sandbox.create();

showInformationMessage = sandbox.stub(vscode.window, "showInformationMessage");
showErrorMessage = sandbox.stub(vscode.window, "showErrorMessage");
createOutputChannel = sandbox.stub(vscode.window, "createOutputChannel");

outputBuffer = "";
outputChannel = {
name: "TestOutputChannel",
append: (output: string) => {
outputBuffer = output;
},
appendLine: sandbox.stub(),
clear: sandbox.stub(),
show: sandbox.stub(),
hide: sandbox.stub(),
dispose: sandbox.stub()
};
createOutputChannel.withArgs(sinon.match.any).returns(outputChannel);
});

afterEach(() => {
sandbox.restore();
});

it("active document is not JSON -- display info message", () => {
return jmespathQuery.queryJson(context, outputChannel)
.then(() => {
expect(showInformationMessage.called).to.be.true;
});
});

it("empty expression entered -- display info message", () => {
jmespathCompile = sandbox.stub(jmespath, "compile");

let emptyExpression = "";
showInputBox = sandbox.stub(vscode.window, "showInputBox");
showInputBox.withArgs(sinon.match.any).returns(Promise.resolve(emptyExpression));

return vscode.workspace.openTextDocument(testJsonFile)
.then((document) => {
return vscode.window.showTextDocument(document);
})
.then((editor) => {
return jmespathQuery.queryJson(context, outputChannel);
})
.then(() => {
expect(showInformationMessage.called).to.be.true;
expect(jmespathCompile.called).to.not.be.true;
});
});

it("invalid expression entered -- display error message", () => {
let invalidExpression = "locations[?state=='WA'"; // invalid jmespath expression
showInputBox = sandbox.stub(vscode.window, "showInputBox");
showInputBox.withArgs(sinon.match.any).returns(Promise.resolve(invalidExpression));

return vscode.workspace.openTextDocument(testJsonFile)
.then((document) => {
return vscode.window.showTextDocument(document);
})
.then((editor) => {
return jmespathQuery.queryJson(context, outputChannel);
})
.then(() => {
expect(showErrorMessage.called).to.be.true;
});
});

it("valid jmespath expression -- display results in output channel", () => {
let expression = "locations[?state=='WA'].name | sort(@)";
showInputBox = sandbox.stub(vscode.window, "showInputBox");
showInputBox.withArgs(sinon.match.any).returns(Promise.resolve(expression));

let expectedOutput = JSON.stringify([ "Bellevue", "Olympia", "Seattle" ], null, " ");

return vscode.workspace.openTextDocument(testJsonFile)
.then((document) => {
return vscode.window.showTextDocument(document);
})
.then((editor) => {
return jmespathQuery.queryJson(context, outputChannel);
})
.then(() => {
expect(expectedOutput).to.equal(outputBuffer);
expect((<sinon.SinonStub>outputChannel.show).called).to.be.true;
});
});

it("empty json document -- display error message", () => {
let expression = "locations[?state=='WA'].name";
showInputBox = sandbox.stub(vscode.window, "showInputBox");
showInputBox.withArgs(sinon.match.any).returns(Promise.resolve(expression));

return vscode.workspace.openTextDocument(emptyJsonFile)
.then((document) => {
return vscode.window.showTextDocument(document);
})
.then((editor) => {
return jmespathQuery.queryJson(context, outputChannel);
})
.then(() => {
expect(showErrorMessage.called).to.be.true;
});
});
});

});

0 comments on commit 4ec2147

Please sign in to comment.