mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-07 02:28:54 +08:00
Create an empty database #44
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="db-uploader-container" :style="{ width }">
|
<div class="db-uploader-container" :style="{ width }">
|
||||||
<change-db-icon v-if="type === 'small'" @click.native="browse"/>
|
<change-db-icon v-if="type === 'small'" @click.native="browse"/>
|
||||||
<div v-if="['regular', 'illustrated'].includes(type)" class="drop-area-container">
|
<div v-if="type === 'illustrated'" class="drop-area-container">
|
||||||
<div
|
<div
|
||||||
class="drop-area"
|
class="drop-area"
|
||||||
@dragover.prevent="state = 'dragover'"
|
@dragover.prevent="state = 'dragover'"
|
||||||
@@ -154,9 +154,9 @@ export default {
|
|||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'regular',
|
default: 'small',
|
||||||
validator: (value) => {
|
validator: (value) => {
|
||||||
return ['regular', 'illustrated', 'small'].includes(value)
|
return ['illustrated', 'small'].includes(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
width: {
|
width: {
|
||||||
@@ -227,11 +227,20 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async finish () {
|
async finish () {
|
||||||
|
console.log('finish')
|
||||||
this.$store.commit('setDb', this.newDb)
|
this.$store.commit('setDb', this.newDb)
|
||||||
this.$store.commit('saveSchema', this.schema)
|
this.$store.commit('saveSchema', this.schema)
|
||||||
|
console.log('after saveSchema')
|
||||||
if (this.importCsvCompleted) {
|
if (this.importCsvCompleted) {
|
||||||
this.$modal.hide('parse')
|
this.$modal.hide('parse')
|
||||||
const tabId = await this.$store.dispatch('addTab', { query: 'select * from csv_import' })
|
const stmt = [
|
||||||
|
'/*',
|
||||||
|
' * Your CSV file has been imported into csv_import table.',
|
||||||
|
' * You can run this SQL query to make all CSV records available for charting.',
|
||||||
|
' */',
|
||||||
|
'SELECT * FROM csv_import'
|
||||||
|
].join('\n')
|
||||||
|
const tabId = await this.$store.dispatch('addTab', { query: stmt })
|
||||||
this.$store.commit('setCurrentTabId', tabId)
|
this.$store.commit('setCurrentTabId', tabId)
|
||||||
this.importCsvCompleted = false
|
this.importCsvCompleted = false
|
||||||
}
|
}
|
||||||
@@ -341,7 +350,7 @@ export default {
|
|||||||
// Create db with csv table and get schema
|
// Create db with csv table and get schema
|
||||||
const name = file.name.replace(/\.[^.]+$/, '')
|
const name = file.name.replace(/\.[^.]+$/, '')
|
||||||
start = new Date()
|
start = new Date()
|
||||||
this.schema = await this.newDb.createDb(name, parseResult.data, progressCounterId)
|
this.schema = await this.newDb.importDb(name, parseResult.data, progressCounterId)
|
||||||
end = new Date()
|
end = new Date()
|
||||||
|
|
||||||
// Inform about import success
|
// Inform about import success
|
||||||
@@ -389,6 +398,7 @@ export default {
|
|||||||
this.delimiter = ''
|
this.delimiter = ''
|
||||||
return Promise.all([this.previewCSV(), this.animationPromise])
|
return Promise.all([this.previewCSV(), this.animationPromise])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
console.log('show')
|
||||||
this.$modal.show('parse')
|
this.$modal.show('parse')
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -432,6 +442,7 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#img-container {
|
#img-container {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="icon-tooltip" :style="tooltipStyle">
|
<span class="icon-tooltip" :style="tooltipStyle">
|
||||||
Change database
|
Load another database or CSV
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class Database {
|
|||||||
delete this.importProgresses[id]
|
delete this.importProgresses[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
async createDb (name, data, progressCounterId) {
|
async importDb (name, data, progressCounterId) {
|
||||||
const result = await this.pw.postMessage({
|
const result = await this.pw.postMessage({
|
||||||
action: 'import',
|
action: 'import',
|
||||||
columns: data.columns,
|
columns: data.columns,
|
||||||
@@ -66,14 +66,15 @@ class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadDb (file) {
|
async loadDb (file) {
|
||||||
const fileContent = await fu.readAsArrayBuffer(file)
|
const fileContent = file ? await fu.readAsArrayBuffer(file) : null
|
||||||
const res = await this.pw.postMessage({ action: 'open', buffer: fileContent })
|
const res = await this.pw.postMessage({ action: 'open', buffer: fileContent })
|
||||||
|
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
throw new Error(res.error)
|
throw new Error(res.error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getSchema(file.name.replace(/\.[^.]+$/, ''))
|
const dbName = file ? file.name.replace(/\.[^.]+$/, '') : 'database'
|
||||||
|
return this.getSchema(dbName)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSchema (name) {
|
async getSchema (name) {
|
||||||
@@ -85,12 +86,14 @@ class Database {
|
|||||||
const result = await this.execute(getSchemaSql)
|
const result = await this.execute(getSchemaSql)
|
||||||
// Parse DDL statements to get column names and types
|
// Parse DDL statements to get column names and types
|
||||||
const parsedSchema = []
|
const parsedSchema = []
|
||||||
|
if (result && result.values) {
|
||||||
result.values.forEach(item => {
|
result.values.forEach(item => {
|
||||||
parsedSchema.push({
|
parsedSchema.push({
|
||||||
name: item[0],
|
name: item[0],
|
||||||
columns: getColumns(item[1])
|
columns: getColumns(item[1])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Return db name and schema
|
// Return db name and schema
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="db">
|
<div id="db">
|
||||||
<div @click="schemaVisible = !schemaVisible" class="db-name">
|
<div @click="schemaVisible = !schemaVisible" class="db-name">
|
||||||
<tree-chevron :expanded="schemaVisible"/>
|
<tree-chevron v-show="schema.length > 0" :expanded="schemaVisible"/>
|
||||||
{{ dbName }}
|
{{ dbName }}
|
||||||
</div>
|
</div>
|
||||||
<db-uploader id="db-edit" type="small" />
|
<db-uploader id="db-edit" type="small" />
|
||||||
|
|||||||
@@ -6,13 +6,7 @@
|
|||||||
:after="{ size: 80, max: 100 }"
|
:after="{ size: 80, max: 100 }"
|
||||||
>
|
>
|
||||||
<template #left-pane>
|
<template #left-pane>
|
||||||
<schema v-if="$store.state.schema"/>
|
<schema/>
|
||||||
<div v-else id="empty-schema-container">
|
|
||||||
<div class="warning">
|
|
||||||
Database is not loaded. Queries can’t be run without database.
|
|
||||||
</div>
|
|
||||||
<db-uploader id="db-uploader" width="100%"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<template #right-pane>
|
<template #right-pane>
|
||||||
<tabs />
|
<tabs />
|
||||||
@@ -25,15 +19,43 @@
|
|||||||
import Splitpanes from '@/components/Splitpanes'
|
import Splitpanes from '@/components/Splitpanes'
|
||||||
import Schema from './Schema'
|
import Schema from './Schema'
|
||||||
import Tabs from './Tabs'
|
import Tabs from './Tabs'
|
||||||
import DbUploader from '@/components/DbUploader'
|
import database from '@/lib/database'
|
||||||
|
import store from '@/store'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Editor',
|
name: 'Editor',
|
||||||
components: {
|
components: {
|
||||||
Schema,
|
Schema,
|
||||||
Splitpanes,
|
Splitpanes,
|
||||||
Tabs,
|
Tabs
|
||||||
DbUploader
|
},
|
||||||
|
async beforeRouteEnter (to, from, next) {
|
||||||
|
if (!store.state.schema) {
|
||||||
|
const newDb = database.getNewDatabase()
|
||||||
|
const newSchema = await newDb.loadDb()
|
||||||
|
store.commit('setDb', newDb)
|
||||||
|
store.commit('saveSchema', newSchema)
|
||||||
|
const stmt = [
|
||||||
|
'/*',
|
||||||
|
' * Your database is empty. In order to start building charts',
|
||||||
|
' * you should create a table and insert data into it.',
|
||||||
|
' */',
|
||||||
|
'CREATE TABLE house',
|
||||||
|
'(',
|
||||||
|
' name TEXT,',
|
||||||
|
' points INTEGER',
|
||||||
|
');',
|
||||||
|
'INSERT INTO house VALUES',
|
||||||
|
"('Gryffindor', 100),",
|
||||||
|
"('Hufflepuff', 90),",
|
||||||
|
"('Ravenclaw', 95),",
|
||||||
|
"('Slytherin', 80);"
|
||||||
|
].join('\n')
|
||||||
|
|
||||||
|
const tabId = await store.dispatch('addTab', { query: stmt })
|
||||||
|
store.commit('setCurrentTabId', tabId)
|
||||||
|
}
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -43,32 +65,4 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--color-white);
|
background-color: var(--color-white);
|
||||||
}
|
}
|
||||||
#empty-schema-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 200px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#db-uploader {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: 24px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning {
|
|
||||||
padding: 12px 24px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
>>>.drop-area {
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
>>>.drop-area .text {
|
|
||||||
max-width: 200px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<div id="note">
|
<div id="note">
|
||||||
Sqliteviz is fully client-side. Your database never leaves your computer.
|
Sqliteviz is fully client-side. Your database never leaves your computer.
|
||||||
</div>
|
</div>
|
||||||
<button id ="skip" class="secondary" @click="$router.push('/editor')">
|
<button id="skip" class="secondary" @click="$router.push('/editor')">
|
||||||
Skip database loading
|
Create empty database
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ describe('DbUploader.vue', () => {
|
|||||||
let state = {}
|
let state = {}
|
||||||
let mutations = {}
|
let mutations = {}
|
||||||
let store = {}
|
let store = {}
|
||||||
|
let place
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// mock store state and mutations
|
// mock store state and mutations
|
||||||
@@ -20,10 +21,14 @@ describe('DbUploader.vue', () => {
|
|||||||
setDb: sinon.stub()
|
setDb: sinon.stub()
|
||||||
}
|
}
|
||||||
store = new Vuex.Store({ state, mutations })
|
store = new Vuex.Store({ state, mutations })
|
||||||
|
|
||||||
|
place = document.createElement('div')
|
||||||
|
document.body.appendChild(place)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sinon.restore()
|
sinon.restore()
|
||||||
|
place.remove()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('loads db on click and redirects to /editor', async () => {
|
it('loads db on click and redirects to /editor', async () => {
|
||||||
@@ -44,15 +49,22 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
// mount the component
|
// mount the component
|
||||||
const wrapper = shallowMount(DbUploader, {
|
const wrapper = shallowMount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
store,
|
store,
|
||||||
mocks: { $router, $route }
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await wrapper.find('.drop-area').trigger('click')
|
await wrapper.find('.drop-area').trigger('click')
|
||||||
expect(db.loadDb.calledOnceWith(file)).to.equal(true)
|
expect(db.loadDb.calledOnceWith(file)).to.equal(true)
|
||||||
await db.loadDb.returnValues[0]
|
await db.loadDb.returnValues[0]
|
||||||
|
await wrapper.vm.animationPromise
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
expect(mutations.saveSchema.calledOnceWith(state, schema)).to.equal(true)
|
expect(mutations.saveSchema.calledOnceWith(state, schema)).to.equal(true)
|
||||||
expect($router.push.calledOnceWith('/editor')).to.equal(true)
|
expect($router.push.calledOnceWith('/editor')).to.equal(true)
|
||||||
|
wrapper.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('loads db on drop and redirects to /editor', async () => {
|
it('loads db on drop and redirects to /editor', async () => {
|
||||||
@@ -69,8 +81,12 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
// mount the component
|
// mount the component
|
||||||
const wrapper = shallowMount(DbUploader, {
|
const wrapper = shallowMount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
store,
|
store,
|
||||||
mocks: { $router, $route }
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// mock a file dropped by a user
|
// mock a file dropped by a user
|
||||||
@@ -84,8 +100,11 @@ describe('DbUploader.vue', () => {
|
|||||||
await wrapper.find('.drop-area').trigger('drop', dropData)
|
await wrapper.find('.drop-area').trigger('drop', dropData)
|
||||||
expect(db.loadDb.calledOnceWith(file)).to.equal(true)
|
expect(db.loadDb.calledOnceWith(file)).to.equal(true)
|
||||||
await db.loadDb.returnValues[0]
|
await db.loadDb.returnValues[0]
|
||||||
|
await wrapper.vm.animationPromise
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
expect(mutations.saveSchema.calledOnceWith(state, schema)).to.equal(true)
|
expect(mutations.saveSchema.calledOnceWith(state, schema)).to.equal(true)
|
||||||
expect($router.push.calledOnceWith('/editor')).to.equal(true)
|
expect($router.push.calledOnceWith('/editor')).to.equal(true)
|
||||||
|
wrapper.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("doesn't redirect if already on /editor", async () => {
|
it("doesn't redirect if already on /editor", async () => {
|
||||||
@@ -106,13 +125,20 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
// mount the component
|
// mount the component
|
||||||
const wrapper = shallowMount(DbUploader, {
|
const wrapper = shallowMount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
store,
|
store,
|
||||||
mocks: { $router, $route }
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await wrapper.find('.drop-area').trigger('click')
|
await wrapper.find('.drop-area').trigger('click')
|
||||||
await db.loadDb.returnValues[0]
|
await db.loadDb.returnValues[0]
|
||||||
|
await wrapper.vm.animationPromise
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
expect($router.push.called).to.equal(false)
|
expect($router.push.called).to.equal(false)
|
||||||
|
wrapper.destroy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -122,6 +148,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
let actions = {}
|
let actions = {}
|
||||||
const newTabId = 1
|
const newTabId = 1
|
||||||
let store = {}
|
let store = {}
|
||||||
|
let place
|
||||||
|
|
||||||
// mock router
|
// mock router
|
||||||
const $router = { }
|
const $router = { }
|
||||||
@@ -150,15 +177,24 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
|
|
||||||
$router.push = sinon.stub()
|
$router.push = sinon.stub()
|
||||||
|
|
||||||
|
place = document.createElement('div')
|
||||||
|
document.body.appendChild(place)
|
||||||
|
|
||||||
// mount the component
|
// mount the component
|
||||||
wrapper = mount(DbUploader, {
|
wrapper = mount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
store,
|
store,
|
||||||
mocks: { $router, $route }
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sinon.restore()
|
sinon.restore()
|
||||||
|
wrapper.destroy()
|
||||||
|
place.remove()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shows parse dialog if gets csv file', async () => {
|
it('shows parse dialog if gets csv file', async () => {
|
||||||
@@ -184,6 +220,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.find('[data-modal="parse"]').exists()).to.equal(true)
|
expect(wrapper.find('[data-modal="parse"]').exists()).to.equal(true)
|
||||||
expect(wrapper.findComponent({ name: 'delimiter-selector' }).vm.value).to.equal('|')
|
expect(wrapper.findComponent({ name: 'delimiter-selector' }).vm.value).to.equal('|')
|
||||||
expect(wrapper.find('#quote-char input').element.value).to.equal('"')
|
expect(wrapper.find('#quote-char input').element.value).to.equal('"')
|
||||||
@@ -219,6 +256,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
parse.onCall(1).resolves({
|
parse.onCall(1).resolves({
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
@@ -328,6 +366,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
let resolveParsing
|
let resolveParsing
|
||||||
parse.onCall(1).returns(new Promise(resolve => {
|
parse.onCall(1).returns(new Promise(resolve => {
|
||||||
@@ -395,6 +434,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -452,6 +492,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -511,6 +552,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -563,7 +605,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
|
|
||||||
let resolveImport = sinon.stub()
|
let resolveImport = sinon.stub()
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().resolves(new Promise(resolve => { resolveImport = resolve })),
|
importDb: sinon.stub().resolves(new Promise(resolve => { resolveImport = resolve })),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub()
|
deleteProgressCounter: sinon.stub()
|
||||||
}
|
}
|
||||||
@@ -573,6 +615,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -598,11 +641,11 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
||||||
expect(wrapper.find('#csv-finish').isVisible()).to.equal(false)
|
expect(wrapper.find('#csv-finish').isVisible()).to.equal(false)
|
||||||
expect(wrapper.find('#csv-import').isVisible()).to.equal(true)
|
expect(wrapper.find('#csv-import').isVisible()).to.equal(true)
|
||||||
expect(newDb.createDb.getCall(0).args[0]).to.equal('foo') // file name
|
expect(newDb.importDb.getCall(0).args[0]).to.equal('foo') // file name
|
||||||
|
|
||||||
// After resolving - loading indicator is not shown
|
// After resolving - loading indicator is not shown
|
||||||
await resolveImport()
|
await resolveImport()
|
||||||
await newDb.createDb.returnValues[0]
|
await newDb.importDb.returnValues[0]
|
||||||
expect(
|
expect(
|
||||||
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
).to.equal(false)
|
).to.equal(false)
|
||||||
@@ -621,7 +664,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
hasErrors: false,
|
hasErrors: false,
|
||||||
messages: []
|
messages: []
|
||||||
})
|
})
|
||||||
|
// we need to separate calles because messages will mutate
|
||||||
parse.onCall(1).resolves({
|
parse.onCall(1).resolves({
|
||||||
delimiter: '|',
|
delimiter: '|',
|
||||||
data: {
|
data: {
|
||||||
@@ -637,7 +680,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
|
|
||||||
const schema = {}
|
const schema = {}
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().resolves(schema),
|
importDb: sinon.stub().resolves(schema),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub()
|
deleteProgressCounter: sinon.stub()
|
||||||
}
|
}
|
||||||
@@ -647,6 +690,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -681,7 +725,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
hasErrors: false,
|
hasErrors: false,
|
||||||
messages: []
|
messages: []
|
||||||
})
|
})
|
||||||
|
// we need to separate calles because messages will mutate
|
||||||
parse.onCall(1).resolves({
|
parse.onCall(1).resolves({
|
||||||
delimiter: '|',
|
delimiter: '|',
|
||||||
data: {
|
data: {
|
||||||
@@ -696,7 +740,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().rejects(new Error('fail')),
|
importDb: sinon.stub().rejects(new Error('fail')),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub()
|
deleteProgressCounter: sinon.stub()
|
||||||
}
|
}
|
||||||
@@ -706,6 +750,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -729,8 +774,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('import final', async () => {
|
it('import final', async () => {
|
||||||
const parse = sinon.stub(csv, 'parse')
|
sinon.stub(csv, 'parse').resolves({
|
||||||
parse.onCall(0).resolves({
|
|
||||||
delimiter: '|',
|
delimiter: '|',
|
||||||
data: {
|
data: {
|
||||||
columns: ['col1', 'col2'],
|
columns: ['col1', 'col2'],
|
||||||
@@ -742,22 +786,9 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
messages: []
|
messages: []
|
||||||
})
|
})
|
||||||
|
|
||||||
parse.onCall(1).resolves({
|
|
||||||
delimiter: '|',
|
|
||||||
data: {
|
|
||||||
columns: ['col1', 'col2'],
|
|
||||||
values: [
|
|
||||||
[1, 'foo'],
|
|
||||||
[2, 'bar']
|
|
||||||
]
|
|
||||||
},
|
|
||||||
hasErrors: false,
|
|
||||||
messages: []
|
|
||||||
})
|
|
||||||
|
|
||||||
const schema = {}
|
const schema = {}
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().resolves(schema),
|
importDb: sinon.stub().resolves(schema),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub()
|
deleteProgressCounter: sinon.stub()
|
||||||
}
|
}
|
||||||
@@ -767,6 +798,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -784,8 +816,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('import cancel', async () => {
|
it('import cancel', async () => {
|
||||||
const parse = sinon.stub(csv, 'parse')
|
sinon.stub(csv, 'parse').resolves({
|
||||||
parse.onCall(0).resolves({
|
|
||||||
delimiter: '|',
|
delimiter: '|',
|
||||||
data: {
|
data: {
|
||||||
columns: ['col1', 'col2'],
|
columns: ['col1', 'col2'],
|
||||||
@@ -797,22 +828,9 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
messages: []
|
messages: []
|
||||||
})
|
})
|
||||||
|
|
||||||
parse.onCall(1).resolves({
|
|
||||||
delimiter: '|',
|
|
||||||
data: {
|
|
||||||
columns: ['col1', 'col2'],
|
|
||||||
values: [
|
|
||||||
[1, 'foo'],
|
|
||||||
[2, 'bar']
|
|
||||||
]
|
|
||||||
},
|
|
||||||
hasErrors: false,
|
|
||||||
messages: []
|
|
||||||
})
|
|
||||||
|
|
||||||
const schema = {}
|
const schema = {}
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().resolves(schema),
|
importDb: sinon.stub().resolves(schema),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub(),
|
deleteProgressCounter: sinon.stub(),
|
||||||
shutDown: sinon.stub()
|
shutDown: sinon.stub()
|
||||||
@@ -823,6 +841,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
@@ -856,7 +875,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
|
|
||||||
const schema = {}
|
const schema = {}
|
||||||
const newDb = {
|
const newDb = {
|
||||||
createDb: sinon.stub().resolves(schema),
|
importDb: sinon.stub().resolves(schema),
|
||||||
createProgressCounter: sinon.stub().returns(1),
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
deleteProgressCounter: sinon.stub(),
|
deleteProgressCounter: sinon.stub(),
|
||||||
loadDb: sinon.stub().resolves()
|
loadDb: sinon.stub().resolves()
|
||||||
@@ -867,6 +886,7 @@ describe('DbUploader.vue import CSV', () => {
|
|||||||
await csv.parse.returnValues[0]
|
await csv.parse.returnValues[0]
|
||||||
await wrapper.vm.animationPromise
|
await wrapper.vm.animationPromise
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
await wrapper.find('#csv-import').trigger('click')
|
await wrapper.find('#csv-import').trigger('click')
|
||||||
await csv.parse.returnValues[1]
|
await csv.parse.returnValues[1]
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ describe('database.js', () => {
|
|||||||
}
|
}
|
||||||
const progressHandler = sinon.spy()
|
const progressHandler = sinon.spy()
|
||||||
const progressCounterId = db.createProgressCounter(progressHandler)
|
const progressCounterId = db.createProgressCounter(progressHandler)
|
||||||
const { dbName, schema } = await db.createDb('foo', data, progressCounterId)
|
const { dbName, schema } = await db.importDb('foo', data, progressCounterId)
|
||||||
expect(dbName).to.equal('foo')
|
expect(dbName).to.equal('foo')
|
||||||
expect(schema).to.have.lengthOf(1)
|
expect(schema).to.have.lengthOf(1)
|
||||||
expect(schema[0].name).to.equal('csv_import')
|
expect(schema[0].name).to.equal('csv_import')
|
||||||
@@ -164,7 +164,7 @@ describe('database.js', () => {
|
|||||||
expect(progressHandler.secondCall.calledWith(100)).to.equal(true)
|
expect(progressHandler.secondCall.calledWith(100)).to.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('createDb throws errors', async () => {
|
it('importDb throws errors', async () => {
|
||||||
const data = {
|
const data = {
|
||||||
columns: ['id', 'name'],
|
columns: ['id', 'name'],
|
||||||
values: [
|
values: [
|
||||||
@@ -174,7 +174,7 @@ describe('database.js', () => {
|
|||||||
}
|
}
|
||||||
const progressHandler = sinon.stub()
|
const progressHandler = sinon.stub()
|
||||||
const progressCounterId = db.createProgressCounter(progressHandler)
|
const progressCounterId = db.createProgressCounter(progressHandler)
|
||||||
await expect(db.createDb('foo', data, progressCounterId))
|
await expect(db.importDb('foo', data, progressCounterId))
|
||||||
.to.be.rejectedWith('column index out of range')
|
.to.be.rejectedWith('column index out of range')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user