1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-07 02:28:54 +08:00
This commit is contained in:
lana-k
2025-03-20 22:04:15 +01:00
parent 5e2b34a856
commit 0c1b91ab2f
146 changed files with 3317 additions and 2438 deletions

View File

@@ -48,7 +48,10 @@ describe('LoadView.vue', () => {
const inquiriesRes = new Response()
inquiriesRes.json = sinon.stub().resolves({
version: 2,
inquiries: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }]
inquiries: [
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' }
]
})
readFile.onCall(1).returns(Promise.resolve(inquiriesRes))
const db = {
@@ -71,11 +74,14 @@ describe('LoadView.vue', () => {
expect(fu.readFile.firstCall.args[0]).to.equal('https://my-url/test.db')
// Db is loaded
expect(db.loadDb.firstCall.args[0]).to.equal(await dataRes.blob.returnValues[0])
expect(db.loadDb.firstCall.args[0]).to.equal(
await dataRes.blob.returnValues[0]
)
// Inquiries file is read
expect(fu.readFile.secondCall.args[0])
.to.equal('https://my-url/test_inquiries.json')
expect(fu.readFile.secondCall.args[0]).to.equal(
'https://my-url/test_inquiries.json'
)
// Tab for inquiry is created
expect(actions.addTab.calledOnce).to.equal(true)
@@ -95,7 +101,7 @@ describe('LoadView.vue', () => {
expect($router.push.called).to.equal(true)
})
it('Doesn\'t redirect and show the button if there is an error', async () => {
it("Doesn't redirect and show the button if there is an error", async () => {
const state = {
tabs: []
}

View File

@@ -9,7 +9,6 @@ import actions from '@/store/actions'
import fu from '@/lib/utils/fileIo'
import { nextTick } from 'vue'
describe('Inquiries.vue', () => {
let clock
@@ -80,7 +79,7 @@ describe('Inquiries.vue', () => {
const store = createStore({ state, mutations, actions })
const wrapper = shallowMount(Inquiries, {
attachTo: document.body,
global: { plugins: [store] }
global: { plugins: [store] }
})
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
@@ -187,13 +186,15 @@ describe('Inquiries.vue', () => {
const store = createStore({ state, mutations, actions })
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: { plugins: [store] }
attachTo: document.body,
global: { plugins: [store] }
})
await wrapper.find('#toolbar-search input').setValue('baz')
await nextTick()
expect(wrapper.find('#inquiries-not-found').text()).to.equal('No inquiries found')
expect(wrapper.find('#inquiries-not-found').text()).to.equal(
'No inquiries found'
)
expect(wrapper.find('#start-guide').exists()).to.equal(false)
expect(wrapper.find('tbody').isVisible()).to.equal(false)
wrapper.unmount()
@@ -242,7 +243,9 @@ describe('Inquiries.vue', () => {
it('Exports one inquiry', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiry')
sinon
.stub(storedInquiries, 'serialiseInquiries')
.returns('I am a serialized inquiry')
sinon.stub(fu, 'exportToFile')
const state = {
predefinedInquiries: [],
@@ -262,8 +265,13 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper.findComponent({ name: 'ExportIcon' }).find('svg').trigger('click')
expect(fu.exportToFile.calledOnceWith('I am a serialized inquiry', 'foo.json')).to.equals(true)
await wrapper
.findComponent({ name: 'ExportIcon' })
.find('svg')
.trigger('click')
expect(
fu.exportToFile.calledOnceWith('I am a serialized inquiry', 'foo.json')
).to.equals(true)
wrapper.unmount()
})
@@ -296,9 +304,14 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper.findComponent({ name: 'CopyIcon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'CopyIcon' })
.find('svg')
.trigger('click')
expect(storedInquiries.duplicateInquiry.calledOnceWith(inquiryInStorage)).to.equals(true)
expect(
storedInquiries.duplicateInquiry.calledOnceWith(inquiryInStorage)
).to.equals(true)
const rows = wrapper.findAll('tbody tr')
expect(rows).to.have.lengthOf(2)
@@ -308,44 +321,48 @@ describe('Inquiries.vue', () => {
wrapper.unmount()
})
it('The copy of the inquiry is not selected if all inquiries were selected before duplication',
async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
const inquiryInStorage = {
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
const newInquiry = {
id: 2,
name: 'foo copy',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-03T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry)
const state = {
predefinedInquiries: [],
inquiries: [inquiryInStorage]
}
const store = createStore({ state, mutations, actions })
it('The copy of the inquiry is not selected if all inquiries were selected before duplication', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
const inquiryInStorage = {
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
const newInquiry = {
id: 2,
name: 'foo copy',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-03T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry)
const state = {
predefinedInquiries: [],
inquiries: [inquiryInStorage]
}
const store = createStore({ state, mutations, actions })
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
.trigger('click')
await wrapper.findComponent({ name: 'CopyIcon' }).find('svg').trigger('click')
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper
.findComponent({ ref: 'mainCheckBox' })
.find('.checkbox-container')
.trigger('click')
await wrapper
.findComponent({ name: 'CopyIcon' })
.find('svg')
.trigger('click')
const checkboxes = wrapper.findAllComponents('[data-test="rowCheckBox"]')
expect(checkboxes[0].vm.checked).to.equals(true)
expect(checkboxes[1].vm.checked).to.equals(false)
wrapper.unmount()
})
const checkboxes = wrapper.findAllComponents('[data-test="rowCheckBox"]')
expect(checkboxes[0].vm.checked).to.equals(true)
expect(checkboxes[1].vm.checked).to.equals(false)
wrapper.unmount()
})
it('Opens an inquiry', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
@@ -408,7 +425,9 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
expect(wrapper.findComponent({ name: 'RenameIcon' }).exists()).to.equals(false)
expect(wrapper.findComponent({ name: 'RenameIcon' }).exists()).to.equals(
false
)
wrapper.unmount()
})
@@ -432,7 +451,7 @@ describe('Inquiries.vue', () => {
const store = createStore({ state, mutations, actions })
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: {
global: {
plugins: [store],
stubs: { teleport: true, transition: false }
}
@@ -441,12 +460,16 @@ describe('Inquiries.vue', () => {
await nextTick()
// click Rename icon in the grid
await wrapper.findComponent({ name: 'RenameIcon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'RenameIcon' })
.find('svg')
.trigger('click')
// check that rename dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Rename inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Rename inquiry'
)
// check that input is filled by the current inquiry name
expect(wrapper.find('.dialog-body input').element.value).to.equals('foo')
@@ -465,14 +488,16 @@ describe('Inquiries.vue', () => {
expect(wrapper.find('tbody tr td').text()).to.equals('bar')
// check that storage is updated
expect(state.inquiries).to.eql([{
id: 1,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}])
expect(state.inquiries).to.eql([
{
id: 1,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
// check that coresponding tab also changed the name
expect(state.tabs[0].name).to.equals('bar')
@@ -513,7 +538,10 @@ describe('Inquiries.vue', () => {
await nextTick()
// click Rename icon in the grid
await wrapper.findComponent({ name: 'RenameIcon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'RenameIcon' })
.find('svg')
.trigger('click')
// change the name
await wrapper.find('.dialog-body input').setValue('')
@@ -524,8 +552,9 @@ describe('Inquiries.vue', () => {
.find(button => button.text() === 'Rename')
.trigger('click')
expect(wrapper.find('.dialog-body .text-field-error').text())
.to.equals("Inquiry name can't be empty")
expect(wrapper.find('.dialog-body .text-field-error').text()).to.equals(
"Inquiry name can't be empty"
)
// check that rename dialog is still open
await clock.tick(100)
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
@@ -604,19 +633,23 @@ describe('Inquiries.vue', () => {
await nextTick()
// click on master checkbox
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
await wrapper
.findComponent({ ref: 'mainCheckBox' })
.find('.checkbox-container')
.trigger('click')
// click Import
await wrapper.find('#toolbar-btns-import').trigger('click')
const checkboxes = wrapper.findAllComponents('[data-test="rowCheckBox"]')
expect(wrapper.findComponent({ ref: 'mainCheckBox' }).vm.checked).to.equals(false)
expect(wrapper.findComponent({ ref: 'mainCheckBox' }).vm.checked).to.equals(
false
)
expect(checkboxes[0].vm.checked).to.equals(true)
expect(checkboxes[1].vm.checked).to.equals(false)
wrapper.unmount()
})
it('Deletion is not available for predefined inquiries', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([
{
@@ -638,7 +671,9 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, { global: { plugins: [store] } })
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
expect(wrapper.findComponent({ name: 'DeleteIcon' }).exists()).to.equals(false)
expect(wrapper.findComponent({ name: 'DeleteIcon' }).exists()).to.equals(
false
)
wrapper.unmount()
})
@@ -671,20 +706,24 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: {
global: {
plugins: [store],
stubs: { teleport: true, transition: false }
}
})
})
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
// click Delete icon in the first row of the grid
await wrapper.findComponent({ name: 'DeleteIcon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'DeleteIcon' })
.find('svg')
.trigger('click')
// check that delete dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Delete inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Delete inquiry'
)
// check the message in the dialog
expect(wrapper.find('.dialog-body').text()).to.contains('"foo"?')
@@ -777,7 +816,9 @@ describe('Inquiries.vue', () => {
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([predefinedInquiry])
sinon
.stub(storedInquiries, 'readPredefinedInquiries')
.resolves([predefinedInquiry])
const inquiryInStore = {
id: 1,
name: 'foo',
@@ -787,19 +828,24 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
sinon
.stub(storedInquiries, 'serialiseInquiries')
.returns('I am a serialized inquiries')
sinon.stub(fu, 'exportToFile')
const state = {
predefinedInquiries: [],
inquiries: [inquiryInStore, {
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}]
inquiries: [
inquiryInStore,
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
]
}
const store = createStore({ state, mutations, actions })
@@ -815,12 +861,17 @@ describe('Inquiries.vue', () => {
await wrapper.find('#toolbar-btns-export').trigger('click')
expect(storedInquiries.serialiseInquiries.calledOnceWith(
sinon.match([predefinedInquiry, inquiryInStore])
)).to.equals(true)
expect(
storedInquiries.serialiseInquiries.calledOnceWith(
sinon.match([predefinedInquiry, inquiryInStore])
)
).to.equals(true)
expect(
fu.exportToFile.calledOnceWith('I am a serialized inquiries', 'My sqliteviz inquiries.json')
fu.exportToFile.calledOnceWith(
'I am a serialized inquiries',
'My sqliteviz inquiries.json'
)
).to.equals(true)
wrapper.unmount()
})
@@ -834,7 +885,9 @@ describe('Inquiries.vue', () => {
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([predefinedInquiry])
sinon
.stub(storedInquiries, 'readPredefinedInquiries')
.resolves([predefinedInquiry])
const inquiryInStore = {
id: 1,
name: 'foo',
@@ -844,7 +897,9 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
sinon
.stub(storedInquiries, 'serialiseInquiries')
.returns('I am a serialized inquiries')
sinon.stub(fu, 'exportToFile')
const state = {
@@ -857,17 +912,24 @@ describe('Inquiries.vue', () => {
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
await wrapper
.findComponent({ ref: 'mainCheckBox' })
.find('.checkbox-container')
.trigger('click')
await wrapper.find('#toolbar-btns-export').trigger('click')
expect(storedInquiries.serialiseInquiries.calledOnceWith(
sinon.match([predefinedInquiry, inquiryInStore])
)).to.equals(true)
expect(
storedInquiries.serialiseInquiries.calledOnceWith(
sinon.match([predefinedInquiry, inquiryInStore])
)
).to.equals(true)
expect(
fu.exportToFile.calledOnceWith('I am a serialized inquiries', 'My sqliteviz inquiries.json')
fu.exportToFile.calledOnceWith(
'I am a serialized inquiries',
'My sqliteviz inquiries.json'
)
).to.equals(true)
wrapper.unmount()
})
@@ -881,7 +943,9 @@ describe('Inquiries.vue', () => {
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([predefinedInquiry])
sinon
.stub(storedInquiries, 'readPredefinedInquiries')
.resolves([predefinedInquiry])
const foo = {
id: 1,
name: 'foo',
@@ -918,10 +982,10 @@ describe('Inquiries.vue', () => {
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: {
global: {
plugins: [store],
stubs: { teleport: true, transition: false }
}
}
})
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
@@ -938,8 +1002,9 @@ describe('Inquiries.vue', () => {
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
// check the message in the dialog
expect(wrapper.find('.dialog-body').text())
.to.contains('Are you sure you want to delete 2 inquiries?')
expect(wrapper.find('.dialog-body').text()).to.contains(
'Are you sure you want to delete 2 inquiries?'
)
// find Delete in the dialog and click
await wrapper
@@ -949,7 +1014,9 @@ describe('Inquiries.vue', () => {
// check the rows in the grid
expect(wrapper.findAll('tbody tr')).to.have.lengthOf(2)
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains('hello_world')
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains(
'hello_world'
)
expect(wrapper.findAll('tbody tr')[1].find('td').text()).to.equals('baz')
// check that deleted inquiry was also deleted from tabs
@@ -975,89 +1042,9 @@ describe('Inquiries.vue', () => {
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([predefinedInquiry])
const foo = {
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
const bar = {
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'updateStorage')
const state = {
tabs: [],
predefinedInquiries: [],
inquiries: [foo, bar]
}
const store = createStore({ state, mutations, actions })
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: {
plugins: [store],
stubs: { teleport: true, transition: false }
}
})
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
const rows = wrapper.findAll('tbody tr')
// Select inquiries (select also predefined inquiries)
await rows[0].find('.checkbox-container').trigger('click')
await rows[1].find('.checkbox-container').trigger('click')
await wrapper.find('#toolbar-btns-delete').trigger('click')
// check that delete dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
// check the message in the dialog
expect(wrapper.find('.dialog-body').text())
.to.contains('Are you sure you want to delete 1 inquiry?')
expect(wrapper.find('.dialog-body #note').isVisible()).to.equals(true)
// find Delete in the dialog and click
await wrapper
.findAll('.dialog-buttons-container button')
.find(button => button.text() === 'Delete')
.trigger('click')
// check the rows in the grid
expect(wrapper.findAll('tbody tr')).to.have.lengthOf(2)
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains('hello_world')
expect(wrapper.findAll('tbody tr')[1].find('td').text()).to.equals('bar')
// check that storage is updated
expect(state.inquiries).to.eql([bar])
// check that delete dialog is closed
await clock.tick(100)
expect(wrapper.find('.dialog.vfm').exists()).to.equal(false)
wrapper.unmount()
})
it('Deletes all inquiries ignoring predefined ones', async () => {
const predefinedInquiry = {
id: 0,
name: 'hello_world',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([predefinedInquiry])
sinon
.stub(storedInquiries, 'readPredefinedInquiries')
.resolves([predefinedInquiry])
const foo = {
id: 1,
name: 'foo',
@@ -1093,7 +1080,96 @@ describe('Inquiries.vue', () => {
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
const rows = wrapper.findAll('tbody tr')
// Select inquiries (select also predefined inquiries)
await rows[0].find('.checkbox-container').trigger('click')
await rows[1].find('.checkbox-container').trigger('click')
await wrapper.find('#toolbar-btns-delete').trigger('click')
// check that delete dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
// check the message in the dialog
expect(wrapper.find('.dialog-body').text()).to.contains(
'Are you sure you want to delete 1 inquiry?'
)
expect(wrapper.find('.dialog-body #note').isVisible()).to.equals(true)
// find Delete in the dialog and click
await wrapper
.findAll('.dialog-buttons-container button')
.find(button => button.text() === 'Delete')
.trigger('click')
// check the rows in the grid
expect(wrapper.findAll('tbody tr')).to.have.lengthOf(2)
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains(
'hello_world'
)
expect(wrapper.findAll('tbody tr')[1].find('td').text()).to.equals('bar')
// check that storage is updated
expect(state.inquiries).to.eql([bar])
// check that delete dialog is closed
await clock.tick(100)
expect(wrapper.find('.dialog.vfm').exists()).to.equal(false)
wrapper.unmount()
})
it('Deletes all inquiries ignoring predefined ones', async () => {
const predefinedInquiry = {
id: 0,
name: 'hello_world',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon
.stub(storedInquiries, 'readPredefinedInquiries')
.resolves([predefinedInquiry])
const foo = {
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
const bar = {
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}
sinon.stub(storedInquiries, 'updateStorage')
const state = {
tabs: [],
predefinedInquiries: [],
inquiries: [foo, bar]
}
const store = createStore({ state, mutations, actions })
const wrapper = mount(Inquiries, {
attachTo: document.body,
global: {
plugins: [store],
stubs: { teleport: true, transition: false }
}
})
await storedInquiries.readPredefinedInquiries.returnValues[0]
await nextTick()
await wrapper
.findComponent({ ref: 'mainCheckBox' })
.find('.checkbox-container')
.trigger('click')
await wrapper.find('#toolbar-btns-delete').trigger('click')
@@ -1102,8 +1178,9 @@ describe('Inquiries.vue', () => {
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
// check the message in the dialog
expect(wrapper.find('.dialog-body').text())
.to.contains('Are you sure you want to delete 2 inquiries?')
expect(wrapper.find('.dialog-body').text()).to.contains(
'Are you sure you want to delete 2 inquiries?'
)
expect(wrapper.find('.dialog-body #note').isVisible()).to.equals(true)
@@ -1115,7 +1192,9 @@ describe('Inquiries.vue', () => {
// check the rows in the grid
expect(wrapper.findAll('tbody tr')).to.have.lengthOf(1)
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains('hello_world')
expect(wrapper.findAll('tbody tr')[0].find('td').text()).to.contains(
'hello_world'
)
// check that storage is updated
expect(state.inquiries).to.eql([])

View File

@@ -150,7 +150,9 @@ describe('MainMenu.vue', () => {
await wrapper.find('#create-btn').trigger('click')
expect(actions.addTab.calledOnce).to.equal(true)
await actions.addTab.returnValues[0]
expect(mutations.setCurrentTabId.calledOnceWith(state, newInquiryId)).to.equal(true)
expect(
mutations.setCurrentTabId.calledOnceWith(state, newInquiryId)
).to.equal(true)
expect($router.push.calledOnce).to.equal(false)
})
@@ -187,106 +189,112 @@ describe('MainMenu.vue', () => {
await wrapper.find('#create-btn').trigger('click')
expect(actions.addTab.calledOnce).to.equal(true)
await actions.addTab.returnValues[0]
expect(mutations.setCurrentTabId.calledOnceWith(state, newInquiryId)).to.equal(true)
expect(
mutations.setCurrentTabId.calledOnceWith(state, newInquiryId)
).to.equal(true)
expect($router.push.calledOnce).to.equal(true)
})
it('Ctrl R calls currentTab.execute if running is enabled and route.path is "/workspace"',
async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
it('Ctrl R calls currentTab.execute if running is enabled and route.path is "/workspace"', async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
const $router = { push: sinon.stub() }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route, $router },
stubs: ['router-link'],
plugins: [store]
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
const $router = { push: sinon.stub() }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route, $router },
stubs: ['router-link'],
plugins: [store]
}
})
const ctrlR = new KeyboardEvent('keydown', { key: 'r', ctrlKey: true })
const metaR = new KeyboardEvent('keydown', { key: 'r', metaKey: true })
// Running is enabled and route path is workspace
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledOnce).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is disabled and route path is workspace
store.state.db = null
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is enabled and route path is not workspace
state.db = {}
wrapper.vm.$route.path = '/inquiries'
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
})
it('Ctrl Enter calls currentTab.execute if running is enabled and route.path is "/workspace"',
async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
const ctrlR = new KeyboardEvent('keydown', { key: 'r', ctrlKey: true })
const metaR = new KeyboardEvent('keydown', { key: 'r', metaKey: true })
// Running is enabled and route path is workspace
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledOnce).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is disabled and route path is workspace
store.state.db = null
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is enabled and route path is not workspace
state.db = {}
wrapper.vm.$route.path = '/inquiries'
document.dispatchEvent(ctrlR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaR)
expect(state.currentTab.execute.calledTwice).to.equal(true)
})
it('Ctrl Enter calls currentTab.execute if running is enabled and route.path is "/workspace"', async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
const $router = { push: sinon.stub() }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route, $router },
stubs: ['router-link'],
plugins: [store]
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
const $router = { push: sinon.stub() }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route, $router },
stubs: ['router-link'],
plugins: [store]
}
})
const ctrlEnter = new KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true })
const metaEnter = new KeyboardEvent('keydown', { key: 'Enter', metaKey: true })
// Running is enabled and route path is workspace
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledOnce).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is disabled and route path is workspace
store.state.db = null
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is enabled and route path is not workspace
store.state.db = {}
wrapper.vm.$route.path = '/inquiries'
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
})
const ctrlEnter = new KeyboardEvent('keydown', {
key: 'Enter',
ctrlKey: true
})
const metaEnter = new KeyboardEvent('keydown', {
key: 'Enter',
metaKey: true
})
// Running is enabled and route path is workspace
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledOnce).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is disabled and route path is workspace
store.state.db = null
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
// Running is enabled and route path is not workspace
store.state.db = {}
wrapper.vm.$route.path = '/inquiries'
document.dispatchEvent(ctrlEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
document.dispatchEvent(metaEnter)
expect(state.currentTab.execute.calledTwice).to.equal(true)
})
it('Ctrl B calls createNewInquiry', async () => {
const tab = {
query: 'SELECT * FROM foo',
@@ -324,124 +332,130 @@ describe('MainMenu.vue', () => {
expect(wrapper.vm.createNewInquiry.callCount).to.equal(4)
})
it('Ctrl S calls checkInquiryBeforeSave if the tab is unsaved and route path is /workspace',
async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
it('Ctrl S calls checkInquiryBeforeSave if the tab is unsaved and route path is /workspace', async () => {
const tab = {
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route },
stubs: ['router-link'],
plugins: [store]
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const store = createStore({ state })
const $route = { path: '/workspace' }
wrapper = shallowMount(MainMenu, {
global: {
mocks: { $route },
stubs: ['router-link'],
plugins: [store]
}
})
sinon.stub(wrapper.vm, 'checkInquiryBeforeSave')
const ctrlS = new KeyboardEvent('keydown', { key: 's', ctrlKey: true })
const metaS = new KeyboardEvent('keydown', { key: 's', metaKey: true })
// tab is unsaved and route is /workspace
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledOnce).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
// tab is saved and route is /workspace
store.state.tabs[0].isSaved = true
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
// tab is unsaved and route is not /workspace
wrapper.vm.$route.path = '/inquiries'
store.state.tabs[0].isSaved = false
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
})
sinon.stub(wrapper.vm, 'checkInquiryBeforeSave')
it('Saves the inquiry when no need the new name',
async () => {
const tab = {
id: 1,
const ctrlS = new KeyboardEvent('keydown', { key: 's', ctrlKey: true })
const metaS = new KeyboardEvent('keydown', { key: 's', metaKey: true })
// tab is unsaved and route is /workspace
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledOnce).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
// tab is saved and route is /workspace
store.state.tabs[0].isSaved = true
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
// tab is unsaved and route is not /workspace
wrapper.vm.$route.path = '/inquiries'
store.state.tabs[0].isSaved = false
document.dispatchEvent(ctrlS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
document.dispatchEvent(metaS)
expect(wrapper.vm.checkInquiryBeforeSave.calledTwice).to.equal(true)
})
it('Saves the inquiry when no need the new name', async () => {
const tab = {
id: 1,
name: 'foo',
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const mutations = {
updateTab: sinon.stub()
}
const actions = {
saveInquiry: sinon.stub().returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
execute: sinon.stub(),
isSaved: false
}
const state = {
currentTab: tab,
tabs: [tab],
db: {}
}
const mutations = {
updateTab: sinon.stub()
}
const actions = {
saveInquiry: sinon.stub().returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
}
const store = createStore({ state, mutations, actions })
const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(false)
wrapper = mount(MainMenu, {
attachTo: document.body,
global: {
mocks: { $route },
stubs: {
'router-link': true, 'app-diagnostic-info': true,
teleport: true, transition: false
},
plugins: [store]
}
viewType: 'chart',
viewOptions: []
})
}
const store = createStore({ state, mutations, actions })
const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(false)
await wrapper.find('#save-btn').trigger('click')
// check that the dialog is closed
expect(wrapper.find('.dialog.vfm').exists()).to.equal(false)
// check that the inquiry was saved via saveInquiry (newName='')
expect(actions.saveInquiry.calledOnce).to.equal(true)
expect(actions.saveInquiry.args[0][1]).to.eql({
inquiryTab: state.currentTab, newName: ''
})
// check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({
tab,
newValues: {
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
}))).to.equal(true)
// check that 'inquirySaved' event was triggered on eventBus
expect(eventBus.$emit.calledOnceWith('inquirySaved')).to.equal(true)
wrapper = mount(MainMenu, {
attachTo: document.body,
global: {
mocks: { $route },
stubs: {
'router-link': true,
'app-diagnostic-info': true,
teleport: true,
transition: false
},
plugins: [store]
}
})
await wrapper.find('#save-btn').trigger('click')
// check that the dialog is closed
expect(wrapper.find('.dialog.vfm').exists()).to.equal(false)
// check that the inquiry was saved via saveInquiry (newName='')
expect(actions.saveInquiry.calledOnce).to.equal(true)
expect(actions.saveInquiry.args[0][1]).to.eql({
inquiryTab: state.currentTab,
newName: ''
})
// check that the tab was updated
expect(
mutations.updateTab.calledOnceWith(
state,
sinon.match({
tab,
newValues: {
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
})
)
).to.equal(true)
// check that 'inquirySaved' event was triggered on eventBus
expect(eventBus.$emit.calledOnceWith('inquirySaved')).to.equal(true)
})
it('Shows en error when the new name is needed but not specifyied', async () => {
const tab = {
id: 1,
@@ -477,8 +491,10 @@ describe('MainMenu.vue', () => {
global: {
mocks: { $route },
stubs: {
'router-link': true, 'app-diagnostic-info': true,
teleport: true, transition: false
'router-link': true,
'app-diagnostic-info': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -488,8 +504,9 @@ describe('MainMenu.vue', () => {
// check that the dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Save inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Save inquiry'
)
// find Save in the dialog and click
await wrapper
@@ -498,7 +515,9 @@ describe('MainMenu.vue', () => {
.trigger('click')
// check that we have an error message and dialog is still open
expect(wrapper.find('.text-field-error').text()).to.equal('Inquiry name can\'t be empty')
expect(wrapper.find('.text-field-error').text()).to.equal(
"Inquiry name can't be empty"
)
await clock.tick(100)
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
})
@@ -538,8 +557,10 @@ describe('MainMenu.vue', () => {
global: {
mocks: { $route },
stubs: {
'router-link': true, 'app-diagnostic-info': true,
teleport: true, transition: false
'router-link': true,
'app-diagnostic-info': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -549,8 +570,9 @@ describe('MainMenu.vue', () => {
// check that the dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Save inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Save inquiry'
)
// enter the new name
await wrapper.find('.dialog-body input').setValue('foo')
@@ -575,17 +597,22 @@ describe('MainMenu.vue', () => {
})
// check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({
tab,
newValues: {
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
}))).to.equal(true)
expect(
mutations.updateTab.calledOnceWith(
state,
sinon.match({
tab,
newValues: {
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
})
)
).to.equal(true)
// check that 'inquirySaved' event was triggered on eventBus
expect(eventBus.$emit.calledOnceWith('inquirySaved')).to.equal(true)
@@ -635,8 +662,10 @@ describe('MainMenu.vue', () => {
global: {
mocks: { $route },
stubs: {
'router-link': true, 'app-diagnostic-info': true,
teleport: true, transition: false
'router-link': true,
'app-diagnostic-info': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -646,8 +675,9 @@ describe('MainMenu.vue', () => {
// check that the dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Save inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Save inquiry'
)
// check that save-note is visible (save-note is an explanation why do we need a new name)
expect(wrapper.find('#save-note').isVisible()).to.equal(true)
@@ -675,17 +705,22 @@ describe('MainMenu.vue', () => {
})
// check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({
tab,
newValues: {
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
}))).to.equal(true)
expect(
mutations.updateTab.calledOnceWith(
state,
sinon.match({
tab,
newValues: {
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: [],
isSaved: true
}
})
)
).to.equal(true)
// check that 'inquirySaved' event was triggered on eventBus
expect(eventBus.$emit.calledOnceWith('inquirySaved')).to.equal(true)
@@ -738,8 +773,10 @@ describe('MainMenu.vue', () => {
global: {
mocks: { $route },
stubs: {
'router-link': true, 'app-diagnostic-info': true,
teleport: true, transition: false
'router-link': true,
'app-diagnostic-info': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -749,8 +786,9 @@ describe('MainMenu.vue', () => {
// check that the dialog is open
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Save inquiry')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Save inquiry'
)
// find Cancel in the dialog and click
await wrapper

View File

@@ -11,7 +11,6 @@ import fIo from '@/lib/utils/fileIo'
import csv from '@/lib/csv'
import { nextTick } from 'vue'
describe('Schema.vue', () => {
let clock
@@ -145,7 +144,10 @@ describe('Schema.vue', () => {
}
})
await wrapper.findComponent({ name: 'export-icon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'export-icon' })
.find('svg')
.trigger('click')
expect(state.db.export.calledOnceWith('fooDB'))
wrapper.unmount()
})
@@ -188,14 +190,18 @@ describe('Schema.vue', () => {
sinon.spy(wrapper.vm, 'addCsvJson')
sinon.spy(wrapper.vm.$refs.addCsvJson, 'loadToDb')
await wrapper.findComponent({ name: 'add-table-icon' }).find('svg').trigger('click')
await wrapper
.findComponent({ name: 'add-table-icon' })
.find('svg')
.trigger('click')
await wrapper.vm.$refs.addCsvJson.preview.returnValues[0]
await wrapper.vm.addCsvJson.returnValues[0]
await nextTick()
await nextTick()
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('CSV import')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'CSV import'
)
await wrapper.find('#import-start').trigger('click')
await wrapper.vm.$refs.addCsvJson.loadToDb.returnValues[0]
await wrapper.find('#import-finish').trigger('click')
@@ -205,7 +211,13 @@ describe('Schema.vue', () => {
expect(wrapper.vm.$store.state.db.schema).to.eql([
{ name: 'foo', columns: [{ name: 'id', type: 'N/A' }] },
{ name: 'test', columns: [{ name: 'col1', type: 'REAL' }, { name: 'col2', type: 'TEXT' }] }
{
name: 'test',
columns: [
{ name: 'col1', type: 'REAL' },
{ name: 'col2', type: 'TEXT' }
]
}
])
const res = await wrapper.vm.$store.state.db.execute('select * from test')

View File

@@ -36,7 +36,11 @@ describe('TableDescription.vue', () => {
expect(wrapper.find('.columns').isVisible()).to.equal(true)
expect(wrapper.findAll('.column').length).to.equal(2)
expect(wrapper.findAll('.column')[0].text()).to.include('id').and.include('number')
expect(wrapper.findAll('.column')[1].text()).to.include('title').and.include('nvarchar(24)')
expect(wrapper.findAll('.column')[0].text())
.to.include('id')
.and.include('number')
expect(wrapper.findAll('.column')[1].text())
.to.include('title')
.and.include('nvarchar(24)')
})
})

View File

@@ -12,9 +12,9 @@ describe('DataView.vue', () => {
})
it('emits update on mode changing', async () => {
const wrapper = mount(DataView, {
const wrapper = mount(DataView, {
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -26,24 +26,32 @@ describe('DataView.vue', () => {
})
it('method getOptionsForSave calls the same method of the current view component', async () => {
const wrapper = mount(DataView, {
const wrapper = mount(DataView, {
global: {
mocks: { $store }
}
})
const chart = wrapper.findComponent({ name: 'Chart' }).vm
sinon.stub(chart, 'getOptionsForSave').returns({ here_are: 'chart_settings' })
sinon
.stub(chart, 'getOptionsForSave')
.returns({ here_are: 'chart_settings' })
expect(wrapper.vm.getOptionsForSave()).to.eql({ here_are: 'chart_settings' })
expect(wrapper.vm.getOptionsForSave()).to.eql({
here_are: 'chart_settings'
})
const pivotBtn = wrapper.findComponent({ ref: 'pivotBtn' })
await pivotBtn.trigger('click')
const pivot = wrapper.findComponent({ name: 'pivot' }).vm
sinon.stub(pivot, 'getOptionsForSave').returns({ here_are: 'pivot_settings' })
sinon
.stub(pivot, 'getOptionsForSave')
.returns({ here_are: 'pivot_settings' })
expect(wrapper.vm.getOptionsForSave()).to.eql({ here_are: 'pivot_settings' })
expect(wrapper.vm.getOptionsForSave()).to.eql({
here_are: 'pivot_settings'
})
wrapper.unmount()
})
@@ -117,7 +125,7 @@ describe('DataView.vue', () => {
sinon.spy(window, 'alert')
const wrapper = mount(DataView, {
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -127,8 +135,8 @@ describe('DataView.vue', () => {
expect(
window.alert.calledOnceWith(
"Your browser doesn't support copying images into the clipboard. " +
'If you use Firefox you can enable it ' +
'by setting dom.events.asyncClipboard.clipboardItem to true.'
'If you use Firefox you can enable it ' +
'by setting dom.events.asyncClipboard.clipboardItem to true.'
)
).to.equal(true)
@@ -146,9 +154,11 @@ describe('DataView.vue', () => {
mocks: { $store }
}
})
sinon.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy').callsFake(async () => {
await clock.tick(5000)
})
sinon
.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy')
.callsFake(async () => {
await clock.tick(5000)
})
// Click copy to clipboard
const copyBtn = wrapper.findComponent({ ref: 'copyToClipboardBtn' })
@@ -156,11 +166,14 @@ describe('DataView.vue', () => {
// The dialog is shown...
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Copy to clipboard')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Copy to clipboard'
)
// ... with Rendering message...
expect(wrapper.find('.dialog-body').text()).to.equal('Rendering the visualisation...')
expect(wrapper.find('.dialog-body').text()).to.equal(
'Rendering the visualisation...'
)
// Switch to microtasks (let prepareCopy run)
await clock.tick(0)
@@ -177,7 +190,9 @@ describe('DataView.vue', () => {
expect(wrapper.find('.dialog-body').text()).to.equal('Image is ready')
// Click copy
await wrapper.find('.dialog-buttons-container button.primary').trigger('click')
await wrapper
.find('.dialog-buttons-container button.primary')
.trigger('click')
// The dialog is not shown...
await clock.tick(100)
@@ -196,9 +211,11 @@ describe('DataView.vue', () => {
}
})
sinon.spy(wrapper.vm, 'copyToClipboard')
sinon.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy').callsFake(async () => {
await clock.tick(500)
})
sinon
.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy')
.callsFake(async () => {
await clock.tick(500)
})
// Click copy to clipboard
const copyBtn = wrapper.findComponent({ ref: 'copyToClipboardBtn' })
@@ -229,9 +246,11 @@ describe('DataView.vue', () => {
}
})
sinon.spy(wrapper.vm, 'copyToClipboard')
sinon.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy').callsFake(async () => {
await clock.tick(5000)
})
sinon
.stub(wrapper.vm.$refs.viewComponent, 'prepareCopy')
.callsFake(async () => {
await clock.tick(5000)
})
// Click copy to clipboard
const copyBtn = wrapper.findComponent({ ref: 'copyToClipboardBtn' })
@@ -245,7 +264,9 @@ describe('DataView.vue', () => {
await nextTick()
// Click cancel
await wrapper.find('.dialog-buttons-container button.secondary').trigger('click')
await wrapper
.find('.dialog-buttons-container button.secondary')
.trigger('click')
// The dialog is not shown...
await clock.tick(100)

View File

@@ -39,7 +39,7 @@ describe('Pivot.vue', () => {
}
},
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
const colLabels = wrapper.findAll('.pivot-output thead th.pvtColLabel')
@@ -77,7 +77,7 @@ describe('Pivot.vue', () => {
}
},
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -144,7 +144,11 @@ describe('Pivot.vue', () => {
rendererName: 'Table',
vals: []
})
sinon.stub(wrapper.findComponent({ref: "customChart"}).vm, 'getOptionsForSave')
sinon
.stub(
wrapper.findComponent({ ref: 'customChart' }).vm,
'getOptionsForSave'
)
.returns({ here_are: 'custom chart settings' })
let optionsForSave = wrapper.vm.getOptionsForSave()
@@ -208,7 +212,8 @@ describe('Pivot.vue', () => {
expect(await wrapper.vm.prepareCopy()).to.be.instanceof(HTMLCanvasElement)
sinon.stub(wrapper.findComponent({ref: "customChart"}).vm, 'prepareCopy')
sinon
.stub(wrapper.findComponent({ ref: 'customChart' }).vm, 'prepareCopy')
.returns(URL.createObjectURL(new Blob()))
await wrapper.findComponent({ name: 'pivotUi' }).setValue({
@@ -271,7 +276,7 @@ describe('Pivot.vue', () => {
}
})
const chartComponent = wrapper.findComponent({ref: "customChart"}).vm
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
sinon.stub(chartComponent, 'saveAsSvg')
await wrapper.vm.saveAsSvg()
@@ -309,7 +314,7 @@ describe('Pivot.vue', () => {
}
})
const chartComponent = wrapper.findComponent({ref: "customChart"}).vm
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
sinon.stub(chartComponent, 'saveAsHtml')
await wrapper.vm.saveAsHtml()
@@ -347,7 +352,7 @@ describe('Pivot.vue', () => {
}
})
const chartComponent = wrapper.findComponent({ref: "customChart"}).vm
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
sinon.stub(chartComponent, 'saveAsPng')
await wrapper.vm.saveAsPng()
@@ -376,7 +381,7 @@ describe('Pivot.vue', () => {
},
attachTo: container,
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -407,7 +412,7 @@ describe('Pivot.vue', () => {
},
attachTo: container,
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -440,14 +445,16 @@ describe('Pivot.vue', () => {
},
attachTo: container,
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
await wrapper.vm.saveAsHtml()
expect(pivotHelper.getPivotHtml.calledOnce).to.equal(true)
const html = pivotHelper.getPivotHtml.returnValues[0]
expect(fIo.exportToFile.calledOnceWith(html, 'pivot.html', 'text/html')).to.equal(true)
expect(
fIo.exportToFile.calledOnceWith(html, 'pivot.html', 'text/html')
).to.equal(true)
})
it('saveAsPng - standart chart', async () => {
@@ -473,7 +480,7 @@ describe('Pivot.vue', () => {
},
attachTo: container,
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -481,12 +488,18 @@ describe('Pivot.vue', () => {
expect(chartHelper.getImageDataUrl.calledOnce).to.equal(true)
await chartHelper.getImageDataUrl.returnValues[0]
expect(wrapper.emitted().loadingImageCompleted.length).to.equal(1)
expect(fIo.downloadFromUrl.calledOnceWith('standat chart data url', 'pivot')).to.equal(true)
expect(
fIo.downloadFromUrl.calledOnceWith('standat chart data url', 'pivot')
).to.equal(true)
})
it('saveAsPng - table', async () => {
sinon.stub(pivotHelper, 'getPivotCanvas').returns(document.createElement('canvas'))
sinon.stub(HTMLCanvasElement.prototype, 'toDataURL').returns('canvas data url')
sinon
.stub(pivotHelper, 'getPivotCanvas')
.returns(document.createElement('canvas'))
sinon
.stub(HTMLCanvasElement.prototype, 'toDataURL')
.returns('canvas data url')
sinon.stub(fIo, 'downloadFromUrl')
const wrapper = mount(Pivot, {
@@ -508,7 +521,7 @@ describe('Pivot.vue', () => {
},
attachTo: container,
global: {
stubs: { 'chart': true }
stubs: { chart: true }
}
})
@@ -516,6 +529,8 @@ describe('Pivot.vue', () => {
expect(HTMLCanvasElement.prototype.toDataURL.calledOnce).to.equal(true)
await HTMLCanvasElement.prototype.toDataURL.returnValues[0]
expect(wrapper.emitted().loadingImageCompleted.length).to.equal(1)
expect(fIo.downloadFromUrl.calledOnceWith('canvas data url', 'pivot')).to.equal(true)
expect(
fIo.downloadFromUrl.calledOnceWith('canvas data url', 'pivot')
).to.equal(true)
})
})

View File

@@ -4,10 +4,10 @@ import PivotSortBtn from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi
describe('PivotSortBtn.vue', () => {
it('switches order', async () => {
const wrapper = shallowMount(PivotSortBtn, {
const wrapper = shallowMount(PivotSortBtn, {
props: {
modelValue: 'key_a_to_z',
'onUpdate:modelValue': (e) => wrapper.setProps({ modelValue: e })
'onUpdate:modelValue': e => wrapper.setProps({ modelValue: e })
}
})

View File

@@ -7,16 +7,17 @@ describe('PivotUi.vue', () => {
const wrapper = mount(PivotUi, {
props: {
keyNames: ['foo', 'bar'],
'onUpdate:modelValue': (e) => wrapper.setProps({ modelValue: e })
'onUpdate:modelValue': e => wrapper.setProps({ modelValue: e })
}
})
// choose columns
await wrapper.findAll('.sqliteviz-select.cols .multiselect__element > span')[0]
await wrapper
.findAll('.sqliteviz-select.cols .multiselect__element > span')[0]
.trigger('click')
expect(wrapper.emitted().update.length).to.equal(1)
let value = wrapper.props('modelValue')
expect(value.rows).to.eql([])
expect(value.cols).to.eql(['foo'])
@@ -28,7 +29,8 @@ describe('PivotUi.vue', () => {
expect(value.vals).to.eql([])
// choose rows
await wrapper.findAll('.sqliteviz-select.rows .multiselect__element > span')[0]
await wrapper
.findAll('.sqliteviz-select.rows .multiselect__element > span')[0]
.trigger('click')
expect(wrapper.emitted().update.length).to.equal(2)
@@ -71,7 +73,8 @@ describe('PivotUi.vue', () => {
expect(value.vals).to.eql([])
// change aggregator
await wrapper.findAll('.sqliteviz-select.aggregator .multiselect__element > span')[12]
await wrapper
.findAll('.sqliteviz-select.aggregator .multiselect__element > span')[12]
.trigger('click')
expect(wrapper.emitted().update.length).to.equal(5)
@@ -120,7 +123,8 @@ describe('PivotUi.vue', () => {
expect(value.vals).to.eql(['foo', 'bar'])
// change renderer
await wrapper.findAll('.sqliteviz-select.renderer .multiselect__element > span')[13]
await wrapper
.findAll('.sqliteviz-select.renderer .multiselect__element > span')[13]
.trigger('click')
expect(wrapper.emitted().update.length).to.equal(8)
@@ -134,7 +138,8 @@ describe('PivotUi.vue', () => {
expect(value.vals).to.eql(['foo', 'bar'])
// change aggregator again
await wrapper.findAll('.sqliteviz-select.aggregator .multiselect__element > span')[3]
await wrapper
.findAll('.sqliteviz-select.aggregator .multiselect__element > span')[3]
.trigger('click')
expect(wrapper.emitted().update.length).to.equal(9)

View File

@@ -1,6 +1,9 @@
import { expect } from 'chai'
import { _getDataSources, getPivotCanvas, getPivotHtml }
from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
import {
_getDataSources,
getPivotCanvas,
getPivotHtml
} from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
describe('pivotHelper.js', () => {
it('_getDataSources returns data sources', () => {
@@ -22,10 +25,10 @@ describe('pivotHelper.js', () => {
const pivotData = {
rowAttrs: ['y'],
colAttrs: ['x', 'z'],
getRowKeys () {
getRowKeys() {
return [[3], [6], [9]]
},
getColKeys () {
getColKeys() {
return [
[5, 2],
[5, 3],
@@ -33,9 +36,9 @@ describe('pivotHelper.js', () => {
[10, 6]
]
},
getAggregator (row, col) {
getAggregator(row, col) {
return {
value () {
value() {
return +row + +col[1]
}
}
@@ -61,7 +64,9 @@ describe('pivotHelper.js', () => {
child.classList.add('pvtTable')
pivotOutput.append(child)
expect(await getPivotCanvas(pivotOutput)).to.be.instanceof(HTMLCanvasElement)
expect(await getPivotCanvas(pivotOutput)).to.be.instanceof(
HTMLCanvasElement
)
})
it('getPivotHtml returns html with styles', async () => {

View File

@@ -25,8 +25,9 @@ describe('Record.vue', () => {
expect(rows[1].findAll('th')[0].text()).to.equals('name')
expect(rows[1].findAll('td')[0].text()).to.equals('bar')
const selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
const selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('bar')
})
@@ -49,8 +50,9 @@ describe('Record.vue', () => {
expect(rows).to.have.lengthOf(2)
expect(rows[0].findAll('td')[0].text()).to.equals('1')
expect(rows[1].findAll('td')[0].text()).to.equals('foo')
let selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
let selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('1')
await wrapper.find('.next').trigger('click')
@@ -58,8 +60,9 @@ describe('Record.vue', () => {
rows = wrapper.findAll('tbody tr')
expect(rows[0].findAll('td')[0].text()).to.equals('2')
expect(rows[1].findAll('td')[0].text()).to.equals('bar')
selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('2')
await wrapper.find('.prev').trigger('click')
@@ -67,8 +70,9 @@ describe('Record.vue', () => {
rows = wrapper.findAll('tbody tr')
expect(rows[0].findAll('td')[0].text()).to.equals('1')
expect(rows[1].findAll('td')[0].text()).to.equals('foo')
selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('1')
await wrapper.find('.last').trigger('click')
@@ -76,8 +80,9 @@ describe('Record.vue', () => {
rows = wrapper.findAll('tbody tr')
expect(rows[0].findAll('td')[0].text()).to.equals('3')
expect(rows[1].findAll('td')[0].text()).to.equals('baz')
selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('3')
await wrapper.find('.first').trigger('click')
@@ -85,8 +90,9 @@ describe('Record.vue', () => {
rows = wrapper.findAll('tbody tr')
expect(rows[0].findAll('td')[0].text()).to.equals('1')
expect(rows[1].findAll('td')[0].text()).to.equals('foo')
selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('1')
})
@@ -105,12 +111,14 @@ describe('Record.vue', () => {
}
})
const selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
const selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
await selectedCell.trigger('click')
const selectedCellAfterClick = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
const selectedCellAfterClick = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCellAfterClick.exists()).to.equals(false)
})
})

View File

@@ -39,8 +39,8 @@ describe('RunResult.vue', () => {
expect(
window.alert.calledOnceWith(
"Your browser doesn't support copying into the clipboard. " +
'If you use Firefox you can enable it ' +
'by setting dom.events.asyncClipboard.clipboardItem to true.'
'If you use Firefox you can enable it ' +
'by setting dom.events.asyncClipboard.clipboardItem to true.'
)
).to.equal(true)
@@ -79,8 +79,9 @@ describe('RunResult.vue', () => {
// The dialog is shown...
expect(wrapper.find('.dialog.vfm').exists()).to.equal(true)
expect(wrapper.find('.dialog.vfm .dialog-header').text())
.to.contain('Copy to clipboard')
expect(wrapper.find('.dialog.vfm .dialog-header').text()).to.contain(
'Copy to clipboard'
)
// ... with Building message...
expect(wrapper.find('.dialog-body').text()).to.equal('Building CSV...')
@@ -96,7 +97,9 @@ describe('RunResult.vue', () => {
expect(wrapper.find('.dialog-body').text()).to.equal('CSV is ready')
// Click copy
await wrapper.find('.dialog-buttons-container button.primary').trigger('click')
await wrapper
.find('.dialog-buttons-container button.primary')
.trigger('click')
await window.navigator.clipboard.writeText.returnValues[0]
// The dialog is not shown...
@@ -180,7 +183,9 @@ describe('RunResult.vue', () => {
await nextTick()
// Click cancel
await wrapper.find('.dialog-buttons-container button.secondary').trigger('click')
await wrapper
.find('.dialog-buttons-container button.secondary')
.trigger('click')
// The dialog is not shown...
await clock.tick(100)
expect(wrapper.find('.dialog.vfm').exists()).to.equal(false)
@@ -246,8 +251,9 @@ describe('RunResult.vue', () => {
// Click on 'bar' cell again
await rows[1].findAll('td')[1].trigger('click')
expect(wrapper.find('.value-viewer-container .table-preview').text())
.to.equals('No cell selected to view')
expect(
wrapper.find('.value-viewer-container .table-preview').text()
).to.equals('No cell selected to view')
wrapper.unmount()
})
@@ -318,8 +324,9 @@ describe('RunResult.vue', () => {
// Click on 'foo' cell again
await rows[1].find('td').trigger('click')
expect(wrapper.find('.value-viewer-container .table-preview').text())
.to.equals('No cell selected to view')
expect(
wrapper.find('.value-viewer-container .table-preview').text()
).to.equals('No cell selected to view')
wrapper.unmount()
})
@@ -357,8 +364,9 @@ describe('RunResult.vue', () => {
// 'name-1' is selected
expect(wrapper.find('.value-body').text()).to.equals('name-1')
let selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
let selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('name-1')
// Go to last record
@@ -375,8 +383,9 @@ describe('RunResult.vue', () => {
// '29' is selected
expect(wrapper.find('.value-body').text()).to.equals('29')
selectedCell = wrapper
.find('.sqliteviz-table tbody td[aria-selected="true"]')
selectedCell = wrapper.find(
'.sqliteviz-table tbody td[aria-selected="true"]'
)
expect(selectedCell.text()).to.equals('29')
wrapper.unmount()
})

View File

@@ -25,7 +25,7 @@ describe('ValueViewer.vue', () => {
}
})
await wrapper.find('button.json').trigger('click')
expect(wrapper.find('.value-body').text()).to.equals('Can\'t parse JSON.')
expect(wrapper.find('.value-body').text()).to.equals("Can't parse JSON.")
})
it('copy to clipboard', async () => {
@@ -38,7 +38,8 @@ describe('ValueViewer.vue', () => {
await wrapper.find('button.copy').trigger('click')
expect(window.navigator.clipboard.writeText.calledOnceWith('foo'))
.to.equal(true)
expect(window.navigator.clipboard.writeText.calledOnceWith('foo')).to.equal(
true
)
})
})

View File

@@ -18,8 +18,12 @@ describe('SqlEditor.vue', () => {
plugins: [store]
}
})
await wrapper.findComponent({ ref: 'cm' }).setValue('SELECT * FROM foo', 'value')
expect(wrapper.emitted()['update:modelValue'][0]).to.eql(['SELECT * FROM foo'])
await wrapper
.findComponent({ ref: 'cm' })
.setValue('SELECT * FROM foo', 'value')
expect(wrapper.emitted()['update:modelValue'][0]).to.eql([
'SELECT * FROM foo'
])
})
it('Run is disabled if there is no db or no query or is getting result set', async () => {
@@ -28,11 +32,13 @@ describe('SqlEditor.vue', () => {
}
const store = createStore({ state })
const wrapper = mount(SqlEditor, {
const wrapper = mount(SqlEditor, {
global: { plugins: [store] },
props: { isGettingResults: false }
})
await wrapper.findComponent({ ref: 'cm' }).setValue('SELECT * FROM foo', 'value')
await wrapper
.findComponent({ ref: 'cm' })
.setValue('SELECT * FROM foo', 'value')
const runButton = wrapper.findComponent({ ref: 'runBtn' })
expect(runButton.props('disabled')).to.equal(true)
@@ -44,7 +50,9 @@ describe('SqlEditor.vue', () => {
await wrapper.findComponent({ ref: 'cm' }).setValue('', 'value')
expect(runButton.props('disabled')).to.equal(true)
await wrapper.findComponent({ ref: 'cm' }).setValue('SELECT * FROM foo', 'value')
await wrapper
.findComponent({ ref: 'cm' })
.setValue('SELECT * FROM foo', 'value')
expect(runButton.props('disabled')).to.equal(false)
await wrapper.setProps({ isGettingResults: true })

View File

@@ -1,7 +1,9 @@
import { expect } from 'chai'
import sinon from 'sinon'
import state from '@/store/state'
import showHint, { getHints } from '@/views/Main/Workspace/Tabs/Tab/SqlEditor/hint'
import showHint, {
getHints
} from '@/views/Main/Workspace/Tabs/Tab/SqlEditor/hint'
import CM from 'codemirror'
describe('hint.js', () => {
@@ -22,9 +24,7 @@ describe('hint.js', () => {
},
{
name: 'bar',
columns: [
{ name: 'barId', type: 'INTEGER' }
]
columns: [{ name: 'barId', type: 'INTEGER' }]
}
]
}
@@ -33,7 +33,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: 'SELECT',
type: 'keyword'
@@ -70,7 +70,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: 'SELECT',
type: 'keyword'
@@ -87,7 +87,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: 'foo',
type: 'string'
@@ -104,7 +104,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: ' ',
type: null
@@ -121,7 +121,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: ';',
type: 'punctuation'
@@ -134,30 +134,27 @@ describe('hint.js', () => {
expect(CM.showHint.called).to.equal(false)
})
it(
'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' }],
from: null, // from/to doesn't metter because getRange is mocked
to: null
})
it('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' }],
from: null, // from/to doesn't metter because getRange is mocked
to: null
})
const editor = {
getRange () {
return 'select'
}
const editor = {
getRange() {
return 'select'
}
const hints = getHints(editor, {})
expect(hints.list).to.eql([])
}
)
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',
'is completed with this option',
() => {
// mock CM.hint.sql and editor
sinon.stub(CM.hint, 'sql').returns({
@@ -166,7 +163,7 @@ describe('hint.js', () => {
to: null
})
const editor = {
getRange () {
getRange() {
return 'house.name'
}
}
@@ -178,13 +175,10 @@ describe('hint.js', () => {
it('getHints returns hints as is when there are more than one option', () => {
// mock CM.hint.sql and editor
const list = [
{ text: 'SELECT' },
{ text: 'ST' }
]
const list = [{ text: 'SELECT' }, { text: 'ST' }]
sinon.stub(CM.hint, 'sql').returns({ list, from: null, to: null })
const editor = {
getRange () {
getRange() {
return 'se'
}
}
@@ -195,22 +189,19 @@ describe('hint.js', () => {
sinon.restore()
})
it(
'getHints returns hints as is when there only one option but the token is not completed',
() => {
// mock CM.hint.sql and editor
const list = [{ text: 'SELECT' }]
sinon.stub(CM.hint, 'sql').returns({ list, from: null, to: null })
const editor = {
getRange () {
return 'sele'
}
it('getHints returns hints as is when there only one option but the token is not completed', () => {
// mock CM.hint.sql and editor
const list = [{ text: 'SELECT' }]
sinon.stub(CM.hint, 'sql').returns({ list, from: null, to: null })
const editor = {
getRange() {
return 'sele'
}
const hints = getHints(editor, {})
expect(hints.list).to.eql(list)
}
)
const hints = getHints(editor, {})
expect(hints.list).to.eql(list)
})
it('tables is empty object when schema is null', () => {
// mock store state
@@ -219,7 +210,7 @@ describe('hint.js', () => {
// mock showHint and editor
sinon.stub(CM, 'showHint')
const editor = {
getTokenAt () {
getTokenAt() {
return {
string: 'SELECT',
type: 'keyword'

View File

@@ -31,7 +31,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true, 'icon-button': true },
stubs: { chart: true, 'icon-button': true },
plugins: [store]
},
props: {
@@ -56,10 +56,15 @@ describe('Tab.vue', () => {
})
await nextTick()
expect(wrapper.find('.tab-content-container').isVisible()).to.equal(true)
expect(wrapper.find('.bottomPane .run-result-panel').exists()).to.equal(true)
expect(wrapper.find('.run-result-panel .result-before').isVisible()).to.equal(true)
expect(wrapper.find('.above .sql-editor-panel .codemirror-container').text())
.to.contain('SELECT * FROM foo')
expect(wrapper.find('.bottomPane .run-result-panel').exists()).to.equal(
true
)
expect(
wrapper.find('.run-result-panel .result-before').isVisible()
).to.equal(true)
expect(
wrapper.find('.above .sql-editor-panel .codemirror-container').text()
).to.contain('SELECT * FROM foo')
})
it("Doesn't render tab when it's not active", async () => {
@@ -74,7 +79,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -114,7 +119,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -174,7 +179,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -219,7 +224,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -263,7 +268,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true, 'icon-button': true },
stubs: { chart: true, 'icon-button': true },
plugins: [store]
},
props: {
@@ -274,7 +279,9 @@ describe('Tab.vue', () => {
store.state.tabs[0].isGettingResults = true
await nextTick()
expect(wrapper.find('.run-result-panel .result-in-progress').exists()).to.equal(true)
expect(
wrapper.find('.run-result-panel .result-in-progress').exists()
).to.equal(true)
})
it('Shows error when executing query ends with error', async () => {
@@ -310,7 +317,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true, 'icon-button': true, },
stubs: { chart: true, 'icon-button': true },
plugins: [store]
},
props: {
@@ -323,10 +330,16 @@ describe('Tab.vue', () => {
message: 'There is no table foo'
}
await nextTick()
expect(wrapper.find('.run-result-panel .result-before').isVisible()).to.equal(false)
expect(wrapper.find('.run-result-panel .result-in-progress').exists()).to.equal(false)
expect(
wrapper.find('.run-result-panel .result-before').isVisible()
).to.equal(false)
expect(
wrapper.find('.run-result-panel .result-in-progress').exists()
).to.equal(false)
expect(wrapper.findComponent({ name: 'logs' }).isVisible()).to.equal(true)
expect(wrapper.findComponent({ name: 'logs' }).text()).to.include('There is no table foo')
expect(wrapper.findComponent({ name: 'logs' }).text()).to.include(
'There is no table foo'
)
})
it('Passes result to sql-table component', async () => {
@@ -368,7 +381,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -378,10 +391,16 @@ describe('Tab.vue', () => {
await nextTick()
store.state.tabs[0].result = result
await nextTick()
expect(wrapper.find('.run-result-panel .result-before').isVisible()).to.equal(false)
expect(wrapper.find('.run-result-panel .result-in-progress').exists()).to.equal(false)
expect(
wrapper.find('.run-result-panel .result-before').isVisible()
).to.equal(false)
expect(
wrapper.find('.run-result-panel .result-in-progress').exists()
).to.equal(false)
expect(wrapper.findComponent({ name: 'logs' }).exists()).to.equal(false)
expect(wrapper.findComponent({ name: 'SqlTable' }).vm.dataSet).to.eql(result)
expect(wrapper.findComponent({ name: 'SqlTable' }).vm.dataSet).to.eql(
result
)
})
it('Switches views', async () => {
@@ -414,7 +433,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -422,33 +441,43 @@ describe('Tab.vue', () => {
}
})
let tableBtn = wrapper.find('.above .side-tool-bar')
let tableBtn = wrapper
.find('.above .side-tool-bar')
.findComponent({ ref: 'tableBtn' })
await tableBtn.vm.$emit('click')
expect(wrapper.find('.bottomPane .sql-editor-panel').exists()).to.equal(true)
expect(wrapper.find('.bottomPane .sql-editor-panel').exists()).to.equal(
true
)
expect(wrapper.find('.above .run-result-panel').exists()).to.equal(true)
const dataViewBtn = wrapper.find('.above .side-tool-bar')
const dataViewBtn = wrapper
.find('.above .side-tool-bar')
.findComponent({ ref: 'dataViewBtn' })
await dataViewBtn.vm.$emit('click')
expect(wrapper.find('.bottomPane .sql-editor-panel').exists()).to.equal(true)
expect(wrapper.find('.bottomPane .sql-editor-panel').exists()).to.equal(
true
)
expect(wrapper.find('.above .data-view-panel').exists()).to.equal(true)
const sqlEditorBtn = wrapper.find('.above .side-tool-bar')
const sqlEditorBtn = wrapper
.find('.above .side-tool-bar')
.findComponent({ ref: 'sqlEditorBtn' })
await sqlEditorBtn.vm.$emit('click')
expect(wrapper.find('.above .sql-editor-panel').exists()).to.equal(true)
expect(wrapper.find('.bottomPane .data-view-panel').exists()).to.equal(true)
tableBtn = wrapper.find('.bottomPane .side-tool-bar')
tableBtn = wrapper
.find('.bottomPane .side-tool-bar')
.findComponent({ ref: 'tableBtn' })
await tableBtn.vm.$emit('click')
expect(wrapper.find('.above .sql-editor-panel').exists()).to.equal(true)
expect(wrapper.find('.bottomPane .run-result-panel').exists()).to.equal(true)
expect(wrapper.find('.bottomPane .run-result-panel').exists()).to.equal(
true
)
})
it('Maximize top panel if maximized panel is above', async () => {
@@ -480,7 +509,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -489,8 +518,9 @@ describe('Tab.vue', () => {
})
await nextTick()
expect(wrapper.find('.above').element.parentElement.style.height)
.to.equal('100%')
expect(wrapper.find('.above').element.parentElement.style.height).to.equal(
'100%'
)
})
it('Maximize bottom panel if maximized panel is below', async () => {
@@ -522,7 +552,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -530,8 +560,9 @@ describe('Tab.vue', () => {
}
})
await nextTick()
expect(wrapper.find('.bottomPane').element.parentElement.style.height)
.to.equal('100%')
expect(
wrapper.find('.bottomPane').element.parentElement.style.height
).to.equal('100%')
})
it('Panel size is 50 if nothing to maximize', async () => {
@@ -562,7 +593,7 @@ describe('Tab.vue', () => {
const wrapper = mount(Tab, {
attachTo: place,
global: {
stubs: { 'chart': true },
stubs: { chart: true },
plugins: [store]
},
props: {
@@ -571,9 +602,11 @@ describe('Tab.vue', () => {
})
await nextTick()
expect(wrapper.find('.above').element.parentElement.style.height)
.to.equal('50%')
expect(wrapper.find('.bottomPane').element.parentElement.style.height)
.to.equal('50%')
expect(wrapper.find('.above').element.parentElement.style.height).to.equal(
'50%'
)
expect(
wrapper.find('.bottomPane').element.parentElement.style.height
).to.equal('50%')
})
})

View File

@@ -6,10 +6,9 @@ import { createStore } from 'vuex'
import Tabs from '@/views/Main/Workspace/Tabs'
import eventBus from '@/lib/eventBus'
describe('Tabs.vue', () => {
let clock
beforeEach(() => {
clock = sinon.useFakeTimers()
sinon.spy(eventBus, '$emit')
@@ -43,8 +42,21 @@ describe('Tabs.vue', () => {
// mock store state
const state = {
tabs: [
{ id: 1, name: 'foo', query: 'select * from foo', chart: [], isSaved: true },
{ id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isSaved: false }
{
id: 1,
name: 'foo',
query: 'select * from foo',
chart: [],
isSaved: true
},
{
id: 2,
name: null,
tempName: 'Untitled',
query: '',
chart: [],
isSaved: false
}
],
currentTabId: 2
}
@@ -81,8 +93,21 @@ describe('Tabs.vue', () => {
// mock store state
const state = {
tabs: [
{ id: 1, name: 'foo', query: 'select * from foo', chart: [], isSaved: true },
{ id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isSaved: false }
{
id: 1,
name: 'foo',
query: 'select * from foo',
chart: [],
isSaved: true
},
{
id: 2,
name: null,
tempName: 'Untitled',
query: '',
chart: [],
isSaved: false
}
],
currentTabId: 2
}
@@ -210,7 +235,9 @@ describe('Tabs.vue', () => {
attachTo: document.body,
global: {
stubs: {
'router-link': true, teleport: true, transition: false
'router-link': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -284,7 +311,9 @@ describe('Tabs.vue', () => {
attachTo: document.body,
global: {
stubs: {
'router-link': true, teleport: true, transition: false
'router-link': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -360,7 +389,9 @@ describe('Tabs.vue', () => {
attachTo: document.body,
global: {
stubs: {
'router-link': true, teleport: true, transition: false
'router-link': true,
teleport: true,
transition: false
},
plugins: [store]
}
@@ -401,8 +432,21 @@ describe('Tabs.vue', () => {
// mock store state
const state = {
tabs: [
{ id: 1, name: 'foo', query: 'select * from foo', chart: [], isSaved: true },
{ id: 2, name: null, tempName: 'Untitled', query: '', chart: [], isSaved: false }
{
id: 1,
name: 'foo',
query: 'select * from foo',
chart: [],
isSaved: true
},
{
id: 2,
name: null,
tempName: 'Untitled',
query: '',
chart: [],
isSaved: false
}
],
currentTabId: 2
}
@@ -429,7 +473,13 @@ describe('Tabs.vue', () => {
// mock store state
const state = {
tabs: [
{ id: 1, name: 'foo', query: 'select * from foo', chart: [], isSaved: true }
{
id: 1,
name: 'foo',
query: 'select * from foo',
chart: [],
isSaved: true
}
],
currentTabId: 1
}