From 3c456ef135358d7dc2204e811b9c16d958856603 Mon Sep 17 00:00:00 2001 From: lana-k Date: Fri, 29 Jul 2022 15:27:01 +0200 Subject: [PATCH] fix sql hint: read properties of undefined #99 --- package.json | 2 +- .../Main/Workspace/Tabs/Tab/SqlEditor/hint.js | 12 +++- .../Workspace/Tabs/Tab/SqlEditor/hint.spec.js | 62 ++++++++++++------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 14f9163..c9e76c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqliteviz", - "version": "0.21.0", + "version": "0.21.1", "license": "Apache-2.0", "private": true, "scripts": { diff --git a/src/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.js b/src/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.js index bbe974d..55221b1 100644 --- a/src/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.js +++ b/src/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.js @@ -3,14 +3,20 @@ import 'codemirror/addon/hint/show-hint.js' import 'codemirror/addon/hint/sql-hint.js' import store from '@/store' +function _getHintText (hint) { + return typeof hint === 'string' ? hint : hint.text +} export function getHints (cm, options) { - const token = cm.getTokenAt(cm.getCursor()).string.toUpperCase() const result = CM.hint.sql(cm, options) + // Don't show the hint if there is only one option - // and the token is already completed with this option - if (result.list.length === 1 && result.list[0].text.toUpperCase() === token) { + // and the replacingText is already equals to this option + const replacedText = cm.getRange(result.from, result.to).toUpperCase() + if (result.list.length === 1 && + _getHintText(result.list[0]).toUpperCase() === replacedText) { result.list = [] } + return result } diff --git a/tests/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.spec.js b/tests/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.spec.js index 378ab07..4a9355d 100644 --- a/tests/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.spec.js +++ b/tests/views/Main/Workspace/Tabs/Tab/SqlEditor/hint.spec.js @@ -138,15 +138,37 @@ describe('hint.js', () => { 'getHints returns [ ] if there is only one option and token is completed with this option', () => { // mock CM.hint.sql and editor - sinon.stub(CM.hint, 'sql').returns({ list: [{ text: 'SELECT' }] }) + sinon.stub(CM.hint, 'sql').returns({ + list: [{ text: 'SELECT' }], + from: null, // from/to doesn't metter because getRange is mocked + to: null + }) + const editor = { - getTokenAt () { - return { - string: 'select', - type: 'keyword' - } - }, - getCursor: sinon.stub() + getRange () { + return 'select' + } + } + + const hints = getHints(editor, {}) + expect(hints.list).to.eql([]) + } + ) + + it( + 'getHints returns [ ] if there is only one string option and token ' + + 'is completed with this option', + () => { + // mock CM.hint.sql and editor + sinon.stub(CM.hint, 'sql').returns({ + list: ['house.name'], + from: null, // from/to doesn't metter because getRange is mocked + to: null + }) + const editor = { + getRange () { + return 'house.name' + } } const hints = getHints(editor, {}) @@ -160,15 +182,11 @@ describe('hint.js', () => { { text: 'SELECT' }, { text: 'ST' } ] - sinon.stub(CM.hint, 'sql').returns({ list }) + sinon.stub(CM.hint, 'sql').returns({ list, from: null, to: null }) const editor = { - getTokenAt () { - return { - string: 'se', - type: 'keyword' - } - }, - getCursor: sinon.stub() + getRange () { + return 'se' + } } const hints = getHints(editor, {}) @@ -182,15 +200,11 @@ describe('hint.js', () => { () => { // mock CM.hint.sql and editor const list = [{ text: 'SELECT' }] - sinon.stub(CM.hint, 'sql').returns({ list }) + sinon.stub(CM.hint, 'sql').returns({ list, from: null, to: null }) const editor = { - getTokenAt () { - return { - string: 'sele', - type: 'keyword' - } - }, - getCursor: sinon.stub() + getRange () { + return 'sele' + } } const hints = getHints(editor, {})