Skip to content

Commit

Permalink
Show progress notification with possibility to open Output while wait…
Browse files Browse the repository at this point in the history
…ing. (#378)
  • Loading branch information
ira-gordin-sap authored Oct 5, 2020
1 parent 4b846cc commit 6595387
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 14 deletions.
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yeoman-ui",
"version": "1.1.27",
"version": "1.1.28",
"displayName": "Application Wizard",
"publisher": "SAPOS",
"author": {
Expand Down
8 changes: 7 additions & 1 deletion backend/src/logUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Output } from "./output";
import { YeomanUI } from "./yeomanui";


module.exports = (output: Output, yeomanUi: YeomanUI) => {
module.exports = ( output: Output, yeomanUi: YeomanUI) => {
function getMessage(args: any) {
const message = stripAnsi(_.get(args, "[0]", ""));
return `${message}`;
Expand Down Expand Up @@ -41,6 +41,12 @@ module.exports = (output: Output, yeomanUi: YeomanUI) => {
return log;
}

log.showProgress = function() {
const message = getMessage(arguments);
yeomanUi.showProgress(message);
return log;
}

log.force = function() {
showMessage(arguments);
return log;
Expand Down
4 changes: 3 additions & 1 deletion backend/src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ export default {
channel_name: "Generators",
select_generator_description: `${selectGeneratorQuestionHint}.\n${selectTargetFolderQuestionHint}.`,
artifact_generated: `The project has been generated.`,
artifact_with_name_generated: (artifactName: string) => `The '${artifactName}' project has been generated.`
artifact_with_name_generated: (artifactName: string) => `The '${artifactName}' project has been generated.`,
show_progress_button: "Check progress",
show_progress_message: "Generating..."
};
6 changes: 3 additions & 3 deletions backend/src/panels/AbstractWebviewPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path';
import * as _ from 'lodash';
import * as fsextra from 'fs-extra';
import { IChildLogger } from '@vscode-logging/logger';
import { getLogger } from '../logger/logger-wrapper';
import { getClassLogger } from '../logger/logger-wrapper';
import Environment = require('yeoman-environment');


Expand All @@ -18,7 +18,7 @@ export abstract class AbstractWebviewPanel {
protected state: any;
protected context: vscode.ExtensionContext;

protected logger: IChildLogger;
protected readonly logger: IChildLogger;
protected disposables: vscode.Disposable[];
protected isInBAS: boolean;

Expand All @@ -35,7 +35,7 @@ export abstract class AbstractWebviewPanel {
this.extensionPath = context.extensionPath;
this.mediaPath = path.join(context.extensionPath, "dist", "media");
this.htmlFileName = "index.html";
this.logger = getLogger();
this.logger = getClassLogger("AbstractWebviewPanel");
this.disposables = [];
this.context = context;
this.isInBAS = !_.isEmpty(_.get(process, "env.WS_BASE_URL"));
Expand Down
2 changes: 1 addition & 1 deletion backend/src/panels/YeomanUIPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export class YeomanUIPanel extends AbstractWebviewPanel {
const filter = GeneratorFilter.create(_.get(uiOptions, "filter"));

const rpc = new RpcExtension(this.webViewPanel.webview);
const vscodeYouiEvents: YouiEvents = new VSCodeYouiEvents(rpc, this.webViewPanel, filter, this.messages);
this.output.setChannelName(`${YeomanUIPanel.YEOMAN_UI}.${this.messages.channel_name}`);
const vscodeYouiEvents: YouiEvents = new VSCodeYouiEvents(rpc, this.webViewPanel, filter, this.messages, this.output);

const outputPath = this.isInBAS ? undefined: _.get(vscode, "workspace.workspaceFolders[0].uri.fsPath");
this.yeomanui = new YeomanUI(rpc,
Expand Down
36 changes: 35 additions & 1 deletion backend/src/vscode-youi-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,29 @@ import { YouiEvents } from "./youi-events";
import { IRpc } from "@sap-devx/webview-rpc/out.ext/rpc-common";
import { GeneratorFilter, GeneratorType } from './filter';
import { relative, isAbsolute } from 'path';
import { GeneratorOutput } from './vscode-output';
import { IChildLogger } from '@vscode-logging/logger';
import { getClassLogger } from './logger/logger-wrapper';

export class VSCodeYouiEvents implements YouiEvents {
private webviewPanel: vscode.WebviewPanel;
private readonly genFilter: GeneratorFilter;
private readonly messages: any;
private resolveFunc: any;
private output: GeneratorOutput;
private readonly logger: IChildLogger;

constructor(rpc: IRpc, webviewPanel: vscode.WebviewPanel, genFilter: GeneratorFilter, messages: any) {
constructor(
rpc: IRpc,
webviewPanel: vscode.WebviewPanel,
genFilter: GeneratorFilter,
messages: any,
output: GeneratorOutput) {
this.webviewPanel = webviewPanel;
this.genFilter = genFilter;
this.messages = messages;
this.output = output;
this.logger = getClassLogger("VSCodeYouiEvents");
}

public doGeneratorDone(success: boolean, message: string, targetFolderPath?: string): void {
Expand All @@ -27,6 +39,28 @@ export class VSCodeYouiEvents implements YouiEvents {
this.showInstallMessage();
}

public showProgress(message?: string): void {
const openOutput: any = this.messages.show_progress_button;
const buttons: string[] = [];
buttons.push(openOutput);
if (_.isEmpty(message)) {
message = this.messages.show_progress_message;
}
this.logger.debug("Showing Progress.", {
notificationMessage: message,
});
vscode.window.showInformationMessage(message, ...buttons).then(selection => {
if (selection === openOutput) {
return this.toggleOutput();
}
});
}

private toggleOutput() {
this.output.show();
this.logger.trace("Output was shown.");
}

private doClose(): void {
if (this.webviewPanel) {
this.webviewPanel.dispose();
Expand Down
4 changes: 4 additions & 0 deletions backend/src/webSocketServer/server-youi-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ export class ServerYouiEvents implements YouiEvents {
public doGeneratorInstall(): void {
this.rpc.invoke("generatorInstall");
}

public showProgress(message?: string): void {
this.rpc.invoke("showProgress");
}
}
5 changes: 5 additions & 0 deletions backend/src/yeomanui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ export class YeomanUI {
entry.set(methodName, handler);
}

public async showProgress(message?: string) {
this.youiEvents.showProgress(message);
}


private async logError(error: any, prefixMessage?: string) {
const errorObj: any = this.getErrorInfo(error);
if (prefixMessage) {
Expand Down
1 change: 1 addition & 0 deletions backend/src/youi-events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface YouiEvents {
doGeneratorDone(success: boolean, message: string, targetFolderPath?: string): void;
doGeneratorInstall(): void;
showProgress(message?: string): void;
}
3 changes: 2 additions & 1 deletion backend/tests/extension.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ describe('extension unit test', () => {
describe('activate', () => {
it("commands registration", async () => {
loggerWrapperMock.expects("createExtensionLoggerAndSubscribeToLogSettingsChanges");
loggerWrapperMock.expects("getLogger").thrice();
loggerWrapperMock.expects("getLogger");
loggerWrapperMock.expects("getClassLogger").twice();
swaTrackerWrapperMock.expects("createSWATracker");
await extension.activate(testContext);
expect( _.get(oRegisteredCommands, "loadYeomanUI")).to.be.not.undefined;
Expand Down
49 changes: 46 additions & 3 deletions backend/tests/vscode-youi-events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import * as _ from "lodash";
import * as vscode from "vscode";
import { GeneratorFilter } from '../src/filter';
import * as messages from '../src/messages';

import * as loggerWrapper from "../src/logger/logger-wrapper";
import { GeneratorOutput } from '../src/vscode-output';
import { VSCodeYouiEvents } from "../src/vscode-youi-events";

describe('vscode-youi-events unit test', () => {
Expand All @@ -15,6 +16,13 @@ describe('vscode-youi-events unit test', () => {
let commandsMock: any;
let workspaceMock: any;
let eventsMock: any;
let loggerWrapperMock: any;
let generatorOutputMock: any;

const testLogger = {debug: () => true, error: () => true,
fatal: () => true, warn: () => true, info: () => true, trace: () => true, getChildLogger: () => {return testLogger;}};

let loggerMock: any;

before(() => {
sandbox = sinon.createSandbox();
Expand All @@ -37,18 +45,26 @@ describe('vscode-youi-events unit test', () => {

beforeEach(() => {
const webViewPanel: any = {dispose: () => true};
events = new VSCodeYouiEvents(undefined, webViewPanel, GeneratorFilter.create(), messages.default);
loggerWrapperMock = sandbox.mock(loggerWrapper);
loggerWrapperMock.expects("getClassLogger").returns(testLogger);
const generatorOutput = new GeneratorOutput();
events = new VSCodeYouiEvents(undefined, webViewPanel, GeneratorFilter.create(), messages.default, generatorOutput);
windowMock = sandbox.mock(vscode.window);
commandsMock = sandbox.mock(vscode.commands);
workspaceMock = sandbox.mock(vscode.workspace);
eventsMock = sandbox.mock(events);
generatorOutputMock = sandbox.mock(generatorOutput);
loggerMock = sandbox.mock(testLogger);
});

afterEach(() => {
windowMock.verify();
eventsMock.verify();
commandsMock.verify();
workspaceMock.verify();
loggerWrapperMock.verify();
generatorOutputMock.verify();
loggerMock.verify();
});

it("doGeneratorInstall", () => {
Expand All @@ -72,6 +88,32 @@ describe('vscode-youi-events unit test', () => {
expect(events["isPredecessorOf"]('C:\\Foo', 'D:\\Foo\\Bar')).to.be.false;
});

describe("showProgress", () => {
it("no message received ---> show default Information message with Progress button", async () => {
loggerMock.expects("debug");
windowMock.expects("showInformationMessage").
withExactArgs(messages.default.show_progress_message, messages.default.show_progress_button).resolves();
await events.showProgress();
});

it("message received ---> show Information message with received message and Progress button", async () => {
const message: string = "Generating generator";
loggerMock.expects("debug");
windowMock.expects("showInformationMessage").
withExactArgs(message, messages.default.show_progress_button).resolves();
await events.showProgress(message);
});

it("Progress button pressed ---> show Output", async () => {
loggerMock.expects("debug");
loggerMock.expects("trace");
windowMock.expects("showInformationMessage").
withExactArgs(messages.default.show_progress_message, messages.default.show_progress_button).resolves(messages.default.show_progress_button);
generatorOutputMock.expects("show");
await events.showProgress();
});
});

describe("doGeneratorDone", () => {
it("on success, add to workspace button and open in new workspace button are visible", () => {
eventsMock.expects("doClose");
Expand Down Expand Up @@ -180,7 +222,8 @@ describe('vscode-youi-events unit test', () => {

it("generator filter type is module", () => {
const genFilter = GeneratorFilter.create({type: ["module"]});
const testEvents = new VSCodeYouiEvents(undefined, undefined, genFilter, messages.default);
loggerWrapperMock.expects("getClassLogger");
const testEvents = new VSCodeYouiEvents(undefined, undefined, genFilter, messages.default, undefined);
eventsMock = sandbox.mock(testEvents);
eventsMock.expects("doClose");
windowMock.expects("showInformationMessage").withExactArgs(messages.default.artifact_generated).resolves();
Expand Down
19 changes: 18 additions & 1 deletion backend/tests/yeomanui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ describe('yeomanui unit test', () => {
public doGeneratorInstall(): void {
return;
}
public showProgress(message?: string): void {
return;
}
}
class TestRpc implements IRpc {
public timeout: number;
Expand Down Expand Up @@ -76,7 +79,7 @@ describe('yeomanui unit test', () => {
}

const testLogger = {debug: () => true, error: () => true,
fatal: () => true, warn: () => true, info: () => true, trace: () => true, getChildLogger: () => (null as IChildLogger)};
fatal: () => true, warn: () => true, info: () => true, trace: () => true, getChildLogger: () => {return testLogger;}};

const rpc = new TestRpc();
const outputChannel: any = {
Expand Down Expand Up @@ -138,6 +141,20 @@ describe('yeomanui unit test', () => {
});
});

describe("showProgress", () => {
it("called with message parameter ---> call showProgress event with the parameter", async () => {
const message: string = "Project Test is generating"
youiEventsMock.expects("showProgress").withExactArgs(message);
await yeomanUi.showProgress(message);
});

it("called without message parameter ---> call showProgress event with no parameter", async () => {
const message: string = "Project Test is generating"
youiEventsMock.expects("showProgress").withExactArgs(undefined);
await yeomanUi.showProgress();
});
});

describe("getGenerators", () => {
let envMock: any;

Expand Down
3 changes: 2 additions & 1 deletion generator-foodq/generators/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module.exports = class extends Generator {
hint: "Our recommendation is green"
},
when: (response) => {
this.log(response.hungry);
this.log(response.hungry);
return response.hungry;
},
validate: (value, answers) => {
Expand Down Expand Up @@ -348,6 +348,7 @@ module.exports = class extends Generator {
}

writing() {
this.log.showProgress("FoodQ is generating.");
this.log('in writing');
this.fs.copyTpl(this.templatePath('index.html'),
this.destinationPath('public/index.html'), {
Expand Down

0 comments on commit 6595387

Please sign in to comment.