diff --git a/backend/package.json b/backend/package.json index 4dffae4c..b22f3499 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,7 +5,7 @@ "license": "Apache 2.0", "description": "Provide rich user experience for Yeoman generators using VSCode extension or the browser", "repository": "https://github.com/SAP/yeoman-ui", - "version": "0.0.30", + "version": "0.0.31", "engines": { "vscode": "^1.39.2" }, diff --git a/backend/src/yeomanui.ts b/backend/src/yeomanui.ts index 3a5f4f4a..588dafa4 100644 --- a/backend/src/yeomanui.ts +++ b/backend/src/yeomanui.ts @@ -68,6 +68,7 @@ export class YeomanUI { this.rpc.registerMethod({ func: this.evaluateMethod, thisArg: this }); this.rpc.registerMethod({ func: this.toggleLog, thisArg: this }); this.rpc.registerMethod({ func: this.logMessage, thisArg: this }); + this.youiAdapter = new YouiAdapter(logger); this.youiAdapter.setYeomanUI(this); this.promptCount = 0; @@ -175,10 +176,7 @@ export class YeomanUI { this.doGeneratorDone(true, message, destinationRoot); }); } catch (error) { - const errorMessage = this.getErrorInfo(error); - console.error(errorMessage); - this.logMessage(errorMessage); - this.toggleLog(); + this.handleError(error); } } @@ -194,6 +192,13 @@ export class YeomanUI { return `name: ${name}\n message: ${message}\n stack: ${stack}\n string: ${string}\n`; } + handleError(error: any) { + const errorMessage = `Error info ---->\n ${this.getErrorInfo(error)}`; + console.error(errorMessage); + this.logMessage(errorMessage); + this.toggleLog(); + } + public doGeneratorDone(success: boolean, message: string, targetPath = ""): Promise { return this.rpc.invoke("generatorDone", [true, message, targetPath]); } @@ -208,14 +213,18 @@ export class YeomanUI { * @param method */ public evaluateMethod(params: any[], questionName: string, methodName: string): any { - if (this.currentQuestions) { - const relevantQuestion: any = _.find(this.currentQuestions, question => { - return (_.get(question, "name") === questionName); - }); - if (relevantQuestion) { - return relevantQuestion[methodName].apply(this.gen, params); + try { + if (this.currentQuestions) { + const relevantQuestion: any = _.find(this.currentQuestions, question => { + return (_.get(question, "name") === questionName); + }); + if (relevantQuestion) { + return relevantQuestion[methodName].apply(this.gen, params); + } } - } + } catch (error) { + this.handleError(error); + } } public async receiveIsWebviewReady() { diff --git a/frontend/src/App.vue b/frontend/src/App.vue index f914d29d..7c7fa5f1 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -249,20 +249,8 @@ export default { this.rpc.invoke("toggleLog", [{}]); } }, - getErrorMessageOnException(question, error) { - let errorInfo; - if (_.isString(error)) { - errorInfo = error; - } else { - const name = _.get(error, "name", ""); - const message = _.get(error, "message", ""); - const stack = _.get(error, "stack", ""); - const string = error.toString(); - - errorInfo = `name: ${name}\n message: ${message}\n stack: ${stack}\n string: ${string}\n`; - } - - return `Could not update the '${question.name}' question in generator '${this.generatorName}'.\nError info ---->\n ${errorInfo}`; + getErrorMessageOnException(question) { + return `Could not update the '${question.name}' question in generator '${this.generatorName}`; }, next() { if (this.resolve) { diff --git a/frontend/src/components/QuestionTypes/QuestionEditor.vue b/frontend/src/components/QuestionTypes/QuestionEditor.vue index 88d9db9e..af435228 100644 --- a/frontend/src/components/QuestionTypes/QuestionEditor.vue +++ b/frontend/src/components/QuestionTypes/QuestionEditor.vue @@ -5,6 +5,8 @@ solo rows=7 v-model="text" + @blur="onChange" + @keyup.enter="onChange" :placeholder="currentQuestion.default" class="yeoman-form-control" aria-describedby="validation-message" @@ -28,11 +30,12 @@ export default { text: undefined } }, - watch: { - text: { - handler(val) { - this.currentQuestion.answer = _.size(val) === 0 ? _.get(this.currentQuestion, "default") : val - this.updateQuestionsFromIndex(this.questionIndex) + methods: { + onChange() { + const currentValue = _.isEmpty(this.text) ? _.get(this.currentQuestion, "default") : this.text; + if (this.currentQuestion.answer !== currentValue) { + this.currentQuestion.answer = currentValue; + this.updateQuestionsFromIndex(this.questionIndex); } } } diff --git a/frontend/tests/components/QuestionTypes/QuestionEditor.spec.js b/frontend/tests/components/QuestionTypes/QuestionEditor.spec.js index a47b182f..421cc775 100644 --- a/frontend/tests/components/QuestionTypes/QuestionEditor.spec.js +++ b/frontend/tests/components/QuestionTypes/QuestionEditor.spec.js @@ -9,31 +9,46 @@ describe('QuestionEditor.vue', () => { destroy(wrapper) }) - describe('text - watcher', () => { + describe('onChange - method', () => { test('text size is 0', async () => { wrapper = initComponent(QuestionEditor, { currentQuestion: { - default: 'testDefault', answer: 'testAnswer' + type: 'time', default: 'testDefault', answer: 'testAnswer' }, updateQuestionsFromIndex: () => {} }) wrapper.vm.$data.text = '' - await wrapper.vm.$nextTick() + wrapper.vm.onChange() expect(wrapper.vm.currentQuestion.answer).toBe('testDefault') }) test('text size is not 0', async () => { wrapper = initComponent(QuestionEditor, { currentQuestion: { - default: 'testDefault', answer: 'testAnswer' + type: 'time', default: 'testDefault', answer: 'testAnswer' }, updateQuestionsFromIndex: () => {} }) wrapper.vm.$data.text = 'test_value' - await wrapper.vm.$nextTick() + wrapper.vm.onChange() expect(wrapper.vm.currentQuestion.answer).toBe('test_value') }) + + test('text size is equal to previous answer', async () => { + wrapper = initComponent(QuestionEditor, { + currentQuestion: { + type: 'time', default: 'testDefault', answer: 'testAnswer' + }, + updateQuestionsFromIndex: jest.fn() + }) + + const spyUpdateQuestionsFromIndex = jest.spyOn(wrapper.vm, 'updateQuestionsFromIndex') + wrapper.vm.$data.text = 'testAnswer' + wrapper.vm.onChange() + expect(spyUpdateQuestionsFromIndex).not.toHaveBeenCalled() + spyUpdateQuestionsFromIndex.mockRestore() + }) }) }) diff --git a/frontend/tests/components/QuestionTypes/QuestionInput.spec.js b/frontend/tests/components/QuestionTypes/QuestionInput.spec.js index d03520aa..220e1e95 100644 --- a/frontend/tests/components/QuestionTypes/QuestionInput.spec.js +++ b/frontend/tests/components/QuestionTypes/QuestionInput.spec.js @@ -35,7 +35,7 @@ describe('QuestionInput.vue', () => { }) }) - describe('text - method', () => { + describe('onChange - method', () => { test('text size is 0', async () => { wrapper = initComponent(QuestionInput, { currentQuestion: {