mirror of
https://github.com/lana-k/sqliteviz.git
synced 2026-02-04 15:38:55 +08:00
634 lines
18 KiB
JavaScript
634 lines
18 KiB
JavaScript
import { expect } from 'chai'
|
|
import { mount, flushPromises } from '@vue/test-utils'
|
|
import Pivot from '@/components/Pivot/index.vue'
|
|
import chartHelper from '@/lib/chartHelper'
|
|
import fIo from '@/lib/utils/fileIo'
|
|
import $ from 'jquery'
|
|
import sinon from 'sinon'
|
|
import pivotHelper from '@/components/Pivot/pivotHelper'
|
|
|
|
describe('Pivot.vue', () => {
|
|
let container
|
|
const $store = { state: { isWorkspaceVisible: true } }
|
|
|
|
beforeEach(() => {
|
|
container = document.createElement('div')
|
|
document.body.appendChild(container)
|
|
})
|
|
|
|
afterEach(() => {
|
|
container.remove()
|
|
sinon.restore()
|
|
})
|
|
|
|
it('renders pivot table', () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
const colLabels = wrapper.findAll('.pivot-output thead th.pvtColLabel')
|
|
expect(colLabels[0].text()).to.equal('2020')
|
|
expect(colLabels[1].text()).to.equal('2021')
|
|
const rows = wrapper.findAll('.pivot-output tbody tr')
|
|
// row0: bar - 2 - 1
|
|
expect(rows[0].find('th').text()).to.equal('bar')
|
|
expect(rows[0].find('td.col0').text()).to.equal('2')
|
|
expect(rows[0].find('td.col1').text()).to.equal('1')
|
|
expect(rows[0].find('td.rowTotal').text()).to.equal('3')
|
|
|
|
// row1: foo - - 2
|
|
expect(rows[1].find('th').text()).to.equal('foo')
|
|
expect(rows[1].find('td.col0').text()).to.equal('')
|
|
expect(rows[1].find('td.col1').text()).to.equal('1')
|
|
expect(rows[1].find('td.rowTotal').text()).to.equal('1')
|
|
})
|
|
|
|
it('updates when dataSource changes', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
|
|
await wrapper.setProps({
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar', 'foo', 'baz'],
|
|
year: [2021, 2021, 2020, 2020, 2021, 2020]
|
|
}
|
|
})
|
|
|
|
const colLabels = wrapper.findAll('.pivot-output thead th.pvtColLabel')
|
|
expect(colLabels[0].text()).to.equal('2020')
|
|
expect(colLabels[1].text()).to.equal('2021')
|
|
const rows = wrapper.findAll('.pivot-output tbody tr')
|
|
// row0: bar - 2 - 1
|
|
expect(rows[0].find('th').text()).to.equal('bar')
|
|
expect(rows[0].find('td.col0').text()).to.equal('2')
|
|
expect(rows[0].find('td.col1').text()).to.equal('1')
|
|
expect(rows[0].find('td.rowTotal').text()).to.equal('3')
|
|
|
|
// row1: baz - 1 -
|
|
expect(rows[1].find('th').text()).to.equal('baz')
|
|
expect(rows[1].find('td.col0').text()).to.equal('1')
|
|
expect(rows[1].find('td.col1').text()).to.equal('')
|
|
expect(rows[1].find('td.rowTotal').text()).to.equal('1')
|
|
|
|
// row2: foo - - 2
|
|
expect(rows[2].find('th').text()).to.equal('foo')
|
|
expect(rows[2].find('td.col0').text()).to.equal('')
|
|
expect(rows[2].find('td.col1').text()).to.equal('2')
|
|
expect(rows[2].find('td.rowTotal').text()).to.equal('2')
|
|
})
|
|
|
|
it('returns options for save', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
global: {
|
|
mocks: { $store }
|
|
}
|
|
})
|
|
|
|
await wrapper.findComponent({ name: 'pivotUi' }).setValue({
|
|
rows: ['year'],
|
|
cols: ['item'],
|
|
colOrder: 'value_a_to_z',
|
|
rowOrder: 'value_z_to_a',
|
|
aggregator: $.pivotUtilities.aggregators.Count(),
|
|
aggregatorName: 'Count',
|
|
renderer: $.pivotUtilities.renderers.Table,
|
|
rendererName: 'Table',
|
|
vals: []
|
|
})
|
|
sinon
|
|
.stub(
|
|
wrapper.findComponent({ ref: 'customChart' }).vm,
|
|
'getOptionsForSave'
|
|
)
|
|
.returns({ here_are: 'custom chart settings' })
|
|
|
|
let optionsForSave = wrapper.vm.getOptionsForSave()
|
|
|
|
expect(optionsForSave.rows).to.eql(['year'])
|
|
expect(optionsForSave.cols).to.eql(['item'])
|
|
expect(optionsForSave.colOrder).to.equal('value_a_to_z')
|
|
expect(optionsForSave.rowOrder).to.equal('value_z_to_a')
|
|
expect(optionsForSave.aggregatorName).to.equal('Count')
|
|
expect(optionsForSave.rendererName).to.equal('Table')
|
|
expect(optionsForSave.rendererOptions).to.equal(undefined)
|
|
expect(optionsForSave.vals).to.eql([])
|
|
|
|
await wrapper.findComponent({ name: 'pivotUi' }).setValue({
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'value_a_to_z',
|
|
rowOrder: 'value_z_to_a',
|
|
aggregator: $.pivotUtilities.aggregators.Count(),
|
|
aggregatorName: 'Count',
|
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
|
rendererName: 'Custom chart',
|
|
vals: []
|
|
})
|
|
|
|
optionsForSave = wrapper.vm.getOptionsForSave()
|
|
expect(optionsForSave.rows).to.eql(['item'])
|
|
expect(optionsForSave.cols).to.eql(['year'])
|
|
expect(optionsForSave.colOrder).to.equal('value_a_to_z')
|
|
expect(optionsForSave.rowOrder).to.equal('value_z_to_a')
|
|
expect(optionsForSave.aggregatorName).to.equal('Count')
|
|
expect(optionsForSave.rendererName).to.equal('Custom chart')
|
|
expect(optionsForSave.rendererOptions).to.eql({
|
|
customChartOptions: { here_are: 'custom chart settings' }
|
|
})
|
|
expect(optionsForSave.vals).to.eql([])
|
|
})
|
|
|
|
it('prepareCopy returns canvas for tables and url for plotly charts', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
mocks: { $store }
|
|
}
|
|
})
|
|
|
|
expect(await wrapper.vm.prepareCopy()).to.be.instanceof(HTMLCanvasElement)
|
|
|
|
sinon
|
|
.stub(wrapper.findComponent({ ref: 'customChart' }).vm, 'prepareCopy')
|
|
.returns(URL.createObjectURL(new Blob()))
|
|
|
|
await wrapper.findComponent({ name: 'pivotUi' }).setValue({
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'value_a_to_z',
|
|
rowOrder: 'value_z_to_a',
|
|
aggregator: $.pivotUtilities.aggregators.Count(),
|
|
aggregatorName: 'Count',
|
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
|
rendererName: 'Custom chart',
|
|
vals: []
|
|
})
|
|
|
|
expect(await wrapper.vm.prepareCopy()).to.be.a('string')
|
|
|
|
await wrapper.findComponent({ name: 'pivotUi' }).setValue({
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'value_a_to_z',
|
|
rowOrder: 'value_z_to_a',
|
|
aggregator: $.pivotUtilities.aggregators.Count(),
|
|
aggregatorName: 'Count',
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart',
|
|
vals: []
|
|
})
|
|
|
|
expect(await wrapper.vm.prepareCopy()).to.be.a('string')
|
|
})
|
|
|
|
it('saveAsSvg calls chart method if renderer is Custom Chart', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
|
rendererName: 'Custom chart',
|
|
rendererOptions: {
|
|
customChartOptions: {
|
|
data: [],
|
|
layout: {},
|
|
frames: []
|
|
}
|
|
}
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
mocks: { $store }
|
|
}
|
|
})
|
|
|
|
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
|
|
sinon.stub(chartComponent, 'saveAsSvg')
|
|
|
|
await wrapper.vm.saveAsSvg()
|
|
expect(chartComponent.saveAsSvg.called).to.equal(true)
|
|
})
|
|
|
|
it('saveAsHtml calls chart method if renderer is Custom Chart', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
|
rendererName: 'Custom chart',
|
|
rendererOptions: {
|
|
customChartOptions: {
|
|
data: [],
|
|
layout: {},
|
|
frames: []
|
|
}
|
|
}
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
mocks: { $store }
|
|
}
|
|
})
|
|
|
|
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
|
|
sinon.stub(chartComponent, 'saveAsHtml')
|
|
|
|
await wrapper.vm.saveAsHtml()
|
|
expect(chartComponent.saveAsHtml.called).to.equal(true)
|
|
})
|
|
|
|
it('saveAsPng calls chart method if renderer is Custom Chart', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Custom chart'],
|
|
rendererName: 'Custom chart',
|
|
rendererOptions: {
|
|
customChartOptions: {
|
|
data: [],
|
|
layout: {},
|
|
frames: []
|
|
}
|
|
}
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
mocks: { $store }
|
|
}
|
|
})
|
|
|
|
const chartComponent = wrapper.findComponent({ ref: 'customChart' }).vm
|
|
sinon.stub(chartComponent, 'saveAsPng')
|
|
|
|
await wrapper.vm.saveAsPng()
|
|
expect(chartComponent.saveAsPng.called).to.equal(true)
|
|
})
|
|
|
|
it('saveAsSvg - standart chart', async () => {
|
|
sinon.spy(chartHelper, 'getImageDataUrl')
|
|
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.saveAsSvg()
|
|
expect(chartHelper.getImageDataUrl.calledOnce).to.equal(true)
|
|
})
|
|
|
|
it('saveAsHtml - standart chart', async () => {
|
|
sinon.spy(chartHelper, 'getChartData')
|
|
sinon.spy(chartHelper, 'getHtml')
|
|
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.saveAsHtml()
|
|
expect(chartHelper.getChartData.calledOnce).to.equal(true)
|
|
const chartData = await chartHelper.getChartData.returnValues[0]
|
|
expect(chartHelper.getHtml.calledOnceWith(chartData)).to.equal(true)
|
|
})
|
|
|
|
it('saveAsHtml - table', async () => {
|
|
sinon.stub(pivotHelper, 'getPivotHtml')
|
|
sinon.stub(fIo, 'exportToFile')
|
|
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers.Table,
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
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)
|
|
})
|
|
|
|
it('saveAsPng - standart chart', async () => {
|
|
sinon.stub(chartHelper, 'getImageDataUrl').returns('standat chart data url')
|
|
sinon.stub(fIo, 'downloadFromUrl')
|
|
|
|
const wrapper = mount(Pivot, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.saveAsPng()
|
|
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)
|
|
})
|
|
|
|
it('saveAsPng - table', async () => {
|
|
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, {
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers.Table,
|
|
rendererName: 'Table'
|
|
}
|
|
},
|
|
attachTo: container,
|
|
global: {
|
|
stubs: { chart: true }
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.saveAsPng()
|
|
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)
|
|
})
|
|
|
|
it('resizes standart chart', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
global: {
|
|
mocks: { $store: { state: { isWorkspaceVisible: true } } }
|
|
},
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart'
|
|
}
|
|
},
|
|
attachTo: container
|
|
})
|
|
|
|
await flushPromises()
|
|
|
|
const plotContainer = wrapper.find('.pivot-output').wrapperElement
|
|
const plot = wrapper.find('.svg-container').wrapperElement
|
|
|
|
const initialContainerWidth = plotContainer.scrollWidth
|
|
const initialContainerHeight = plotContainer.scrollHeight
|
|
|
|
const initialPlotWidth = plot.scrollWidth
|
|
const initialPlotHeight = plot.scrollHeight
|
|
|
|
const newContainerWidth = initialContainerWidth * 2 || 1000
|
|
const newContainerHeight = initialContainerHeight * 2 || 2000
|
|
|
|
plotContainer.style.width = `${newContainerWidth}px`
|
|
plotContainer.style.height = `${newContainerHeight}px`
|
|
|
|
await flushPromises()
|
|
|
|
const plotAfterResize = wrapper.find('.svg-container').wrapperElement
|
|
expect(plotAfterResize.scrollWidth).not.to.equal(initialPlotWidth)
|
|
|
|
expect(plotAfterResize.scrollWidth.scrollHeight).not.to.equal(
|
|
initialPlotHeight
|
|
)
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('hides or shows controlls depending on showViewSettings and resizes standart chart', async () => {
|
|
const wrapper = mount(Pivot, {
|
|
global: {
|
|
mocks: { $store: { state: { isWorkspaceVisible: true } } }
|
|
},
|
|
props: {
|
|
dataSources: {
|
|
item: ['foo', 'bar', 'bar', 'bar'],
|
|
year: [2021, 2021, 2020, 2020]
|
|
},
|
|
initOptions: {
|
|
rows: ['item'],
|
|
cols: ['year'],
|
|
colOrder: 'key_a_to_z',
|
|
rowOrder: 'key_a_to_z',
|
|
aggregatorName: 'Count',
|
|
vals: [],
|
|
renderer: $.pivotUtilities.renderers['Bar Chart'],
|
|
rendererName: 'Bar Chart'
|
|
}
|
|
},
|
|
attachTo: container
|
|
})
|
|
|
|
expect(wrapper.find('.pivot-ui').isVisible()).to.equal(false)
|
|
|
|
await flushPromises()
|
|
|
|
const plot = wrapper.find('.svg-container').wrapperElement
|
|
const initialPlotHeight = plot.scrollHeight
|
|
|
|
await wrapper.setProps({ showViewSettings: true })
|
|
expect(wrapper.find('.pivot-ui').isVisible()).to.equal(true)
|
|
|
|
await flushPromises()
|
|
const plotAfterResize = wrapper.find('.svg-container').wrapperElement
|
|
|
|
expect(plotAfterResize.scrollWidth.scrollHeight).not.to.equal(
|
|
initialPlotHeight
|
|
)
|
|
|
|
wrapper.unmount()
|
|
})
|
|
})
|