mirror of
https://github.com/lana-k/sqliteviz.git
synced 2026-11-04 00:39:24 +08:00
#140 tests for search panel component
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
import { expect } from 'chai'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Graph from 'graphology'
|
||||
import GraphSearchPanel from '@/components/Graph/GraphSearchPanel.vue'
|
||||
import sinon from 'sinon'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
describe('GraphSearchPanel.vue', () => {
|
||||
const buildGraph = () => {
|
||||
const graph = new Graph()
|
||||
graph.addNode('node-1', { label: 'Alpha' })
|
||||
graph.addNode('node-2', { label: 'Beta' })
|
||||
graph.addNode('node-3', { label: 'Gamma' })
|
||||
graph.addNode('node-4', { label: 'Foo' })
|
||||
return graph
|
||||
}
|
||||
|
||||
it('matches labels and emits node ids for navigation', async () => {
|
||||
const clock = sinon.useFakeTimers()
|
||||
const wrapper = mount(GraphSearchPanel, {
|
||||
props: {
|
||||
graph: buildGraph(),
|
||||
nodesMatchingSearchQuery: null,
|
||||
focusedFoundNodeId: null,
|
||||
'onUpdate:nodesMatchingSearchQuery': nodes => {
|
||||
wrapper.setProps({ nodesMatchingSearchQuery: nodes })
|
||||
},
|
||||
'onUpdate:focusedFoundNodeId': nodeId => {
|
||||
wrapper.setProps({ focusedFoundNodeId: nodeId })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.find('.query-input input').setValue('a')
|
||||
clock.tick(500)
|
||||
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[0][0]).to.eql([
|
||||
'node-1',
|
||||
'node-2',
|
||||
'node-3'
|
||||
])
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[0][0]).to.equal(null)
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('3 nodes found')
|
||||
|
||||
await wrapper.find('[data-test="next-match-btn"]').trigger('click')
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[1][0]).to.equal(
|
||||
'node-1'
|
||||
)
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('1 of 3')
|
||||
|
||||
await wrapper.find('[data-test="next-match-btn"]').trigger('click')
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[2][0]).to.equal(
|
||||
'node-2'
|
||||
)
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('2 of 3')
|
||||
|
||||
await wrapper.find('[data-test="previous-match-btn"]').trigger('click')
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[3][0]).to.equal(
|
||||
'node-1'
|
||||
)
|
||||
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('1 of 3')
|
||||
|
||||
await wrapper.find('[data-test="previous-match-btn"]').trigger('click')
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[4][0]).to.equal(
|
||||
'node-3'
|
||||
)
|
||||
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('3 of 3')
|
||||
|
||||
await wrapper.find('[data-test="next-match-btn"]').trigger('click')
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[5][0]).to.equal(
|
||||
'node-1'
|
||||
)
|
||||
await nextTick()
|
||||
expect(wrapper.text()).to.contain('1 of 3')
|
||||
|
||||
await wrapper.find('.query-input input').setValue('Foo')
|
||||
clock.tick(500)
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[1][0]).to.eql([
|
||||
'node-4'
|
||||
])
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[6][0]).to.equal(null)
|
||||
|
||||
await wrapper.find('.query-input input').setValue('')
|
||||
clock.tick(500)
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[2][0]).to.eql(
|
||||
null
|
||||
)
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[7][0]).to.equal(null)
|
||||
clock.restore()
|
||||
})
|
||||
|
||||
it('matches case and uses reg exp', async () => {
|
||||
const clock = sinon.useFakeTimers()
|
||||
const wrapper = mount(GraphSearchPanel, {
|
||||
props: {
|
||||
graph: buildGraph(),
|
||||
nodesMatchingSearchQuery: null,
|
||||
focusedFoundNodeId: null,
|
||||
'onUpdate:nodesMatchingSearchQuery': nodes => {
|
||||
wrapper.setProps({ nodesMatchingSearchQuery: nodes })
|
||||
},
|
||||
'onUpdate:focusedFoundNodeId': nodeId => {
|
||||
wrapper.setProps({ focusedFoundNodeId: nodeId })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.find('.query-input input').setValue('A')
|
||||
clock.tick(500)
|
||||
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[0][0]).to.eql([
|
||||
'node-1',
|
||||
'node-2',
|
||||
'node-3'
|
||||
])
|
||||
|
||||
const matchCaseBtn = wrapper.find('[data-test="match-case-btn"]')
|
||||
const useRegExpBtn = wrapper.find('[data-test="use-reg-exp-btn"]')
|
||||
|
||||
await matchCaseBtn.trigger('click')
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[1][0]).to.eql([
|
||||
'node-1'
|
||||
])
|
||||
|
||||
await wrapper.find('.query-input input').setValue('a.+a$')
|
||||
clock.tick(500)
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[2][0]).to.eql([])
|
||||
|
||||
await useRegExpBtn.trigger('click')
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[3][0]).to.eql([
|
||||
'node-3'
|
||||
])
|
||||
|
||||
await matchCaseBtn.trigger('click')
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[4][0]).to.eql([
|
||||
'node-1',
|
||||
'node-3'
|
||||
])
|
||||
|
||||
clock.restore()
|
||||
})
|
||||
|
||||
it('shows No items found and disables navigation arrows', async () => {
|
||||
const clock = sinon.useFakeTimers()
|
||||
const wrapper = mount(GraphSearchPanel, {
|
||||
props: {
|
||||
graph: buildGraph(),
|
||||
nodesMatchingSearchQuery: null,
|
||||
focusedFoundNodeId: null,
|
||||
'onUpdate:nodesMatchingSearchQuery': nodes => {
|
||||
wrapper.setProps({ nodesMatchingSearchQuery: nodes })
|
||||
},
|
||||
'onUpdate:focusedFoundNodeId': nodeId => {
|
||||
wrapper.setProps({ focusedFoundNodeId: nodeId })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.find('.query-input input').setValue('baz')
|
||||
clock.tick(500)
|
||||
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[0][0]).to.eql([])
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId')[0][0]).to.equal(null)
|
||||
await nextTick()
|
||||
expect(wrapper.find('[data-test="no-results-text"]').isVisible()).to.be.true
|
||||
|
||||
await expect(
|
||||
wrapper.find('[data-test="next-match-btn"]').attributes('disabled')
|
||||
).to.not.equal(undefined)
|
||||
await expect(
|
||||
wrapper.find('[data-test="previous-match-btn"]').attributes('disabled')
|
||||
).to.not.equal(undefined)
|
||||
clock.restore()
|
||||
})
|
||||
|
||||
it('handles invalid regular expressions by clearing matches', async () => {
|
||||
const clock = sinon.useFakeTimers()
|
||||
const wrapper = mount(GraphSearchPanel, {
|
||||
props: {
|
||||
graph: buildGraph(),
|
||||
nodesMatchingSearchQuery: ['node-1'],
|
||||
focusedFoundNodeId: 'node-1'
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.find('.query-input input').setValue('[')
|
||||
clock.tick(500)
|
||||
|
||||
expect(wrapper.emitted('update:nodesMatchingSearchQuery')[0][0]).to.eql([])
|
||||
const useRegExpBtn = wrapper.find('[data-test="use-reg-exp-btn"]')
|
||||
|
||||
await useRegExpBtn.trigger('click')
|
||||
|
||||
expect(
|
||||
wrapper.emitted('update:nodesMatchingSearchQuery').at(-1)[0]
|
||||
).to.equal(null)
|
||||
expect(wrapper.emitted('update:focusedFoundNodeId').at(-1)[0]).to.equal(
|
||||
null
|
||||
)
|
||||
expect(wrapper.text()).to.contain('Invalid regular expression')
|
||||
|
||||
clock.restore()
|
||||
})
|
||||
|
||||
it('toggles the search panel visibility', async () => {
|
||||
const wrapper = mount(GraphSearchPanel, {
|
||||
props: {
|
||||
graph: buildGraph(),
|
||||
nodesMatchingSearchQuery: null,
|
||||
focusedFoundNodeId: null
|
||||
},
|
||||
attachTo: document.body
|
||||
})
|
||||
|
||||
const searchControls = wrapper.find('.graph-search-panel--search-controls')
|
||||
expect(searchControls.isVisible()).to.be.false
|
||||
|
||||
const toggleButton = wrapper.find(
|
||||
'[data-test="toggle-search-panel-visibility-btn"]'
|
||||
)
|
||||
await toggleButton.trigger('click')
|
||||
expect(searchControls.isVisible()).to.be.true
|
||||
|
||||
await toggleButton.trigger('click')
|
||||
expect(wrapper.vm.panelOpen).to.be.false
|
||||
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user