From 53e51942954cae0eae10b54eeaa260427e53e290 Mon Sep 17 00:00:00 2001 From: lana-k Date: Mon, 16 Sep 2024 23:49:02 +0200 Subject: [PATCH] #116 update tests --- src/components/SqlTable/index.vue | 2 +- tests/components/CsvImport/CsvImport.spec.js | 527 +++++++++++++++++- tests/components/DbUploader.spec.js | 80 ++- tests/lib/csv.spec.js | 21 +- tests/lib/utils/fileIo.spec.js | 58 ++ .../Main/Workspace/Schema/Schema.spec.js | 2 +- 6 files changed, 677 insertions(+), 13 deletions(-) diff --git a/src/components/SqlTable/index.vue b/src/components/SqlTable/index.vue index 2bd60b0..8b22018 100644 --- a/src/components/SqlTable/index.vue +++ b/src/components/SqlTable/index.vue @@ -75,7 +75,7 @@ export default { components: { Pager }, props: { dataSet: Object, - time: String, + time: [String, Number], pageSize: { type: Number, default: 20 diff --git a/tests/components/CsvImport/CsvImport.spec.js b/tests/components/CsvImport/CsvImport.spec.js index c231769..6868718 100644 --- a/tests/components/CsvImport/CsvImport.spec.js +++ b/tests/components/CsvImport/CsvImport.spec.js @@ -13,7 +13,7 @@ describe('CsvJsonImport.vue', () => { let clock let wrapper const newTabId = 1 - const file = { name: 'my data.csv' } + const file = new File([], 'my data.csv') beforeEach(() => { clock = sinon.useFakeTimers() @@ -78,6 +78,7 @@ describe('CsvJsonImport.vue', () => { await wrapper.vm.open() await wrapper.vm.$nextTick() expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true) + expect(wrapper.find('.dialog-header').text()).to.equal('CSV import') expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data') expect(wrapper.findComponent({ name: 'delimiter-selector' }).vm.value).to.equal('|') expect(wrapper.find('#quote-char input').element.value).to.equal('"') @@ -95,6 +96,34 @@ describe('CsvJsonImport.vue', () => { .to.include('Preview parsing is completed in') expect(wrapper.find('#import-finish').isVisible()).to.equal(false) expect(wrapper.find('#import-start').isVisible()).to.equal(true) + expect(wrapper.find('#import-start').attributes().disabled).to.equal(undefined) + }) + + it('disables import if no rows found', async () => { + sinon.stub(csv, 'parse').resolves({ + delimiter: '|', + data: { + columns: ['col2', 'col1'], + values: { + col1: [], + col2: [] + } + }, + rowCount: 0, + messages: [] + }) + + await wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + const rows = wrapper.findAll('tbody tr') + expect(rows).to.have.lengthOf(0) + expect(wrapper.findComponent({ name: 'logs' }).text()) + .to.include('No rows to import.') + expect(wrapper.find('.no-data').isVisible()).to.equal(true) + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + expect(wrapper.find('#import-start').attributes().disabled).to.equal('disabled') }) it('reparses when parameters changes', async () => { @@ -231,7 +260,8 @@ describe('CsvJsonImport.vue', () => { col2: ['foo'] } }, - rowCount: 1 + rowCount: 1, + messages: [] }) wrapper.vm.preview() @@ -240,7 +270,18 @@ describe('CsvJsonImport.vue', () => { let resolveParsing parse.onCall(1).returns(new Promise(resolve => { - resolveParsing = resolve + resolveParsing = () => resolve({ + delimiter: '|', + data: { + columns: ['col1', 'col2'], + values: { + col1: [1], + col2: ['foo'] + } + }, + rowCount: 1, + messages: [] + }) })) await wrapper.find('#csv-json-table-name input').setValue('foo') @@ -715,7 +756,11 @@ describe('CsvJsonImport.vue', () => { }) it('checks table name', async () => { - sinon.stub(csv, 'parse').resolves() + sinon.stub(csv, 'parse').resolves({ + data: {}, + hasErrors: false, + messages: [] + }) await wrapper.vm.preview() await wrapper.vm.open() await wrapper.vm.$nextTick() @@ -743,3 +788,477 @@ describe('CsvJsonImport.vue', () => { expect(wrapper.vm.db.addTableFromCsv.called).to.equal(false) }) }) + +describe('CsvJsonImport.vue - json', () => { + let state = {} + let actions = {} + let mutations = {} + let store = {} + let clock + let wrapper + const newTabId = 1 + const file = new File( + [new Blob( + [JSON.stringify({ foo: [1, 2, 3] }, null, 2)], + { type: 'application/json' } + )], + 'my data.json', + { type: 'application/json' }) + + beforeEach(() => { + clock = sinon.useFakeTimers() + + // mock store state and mutations + state = {} + mutations = { + setDb: sinon.stub(), + setCurrentTabId: sinon.stub() + } + actions = { + addTab: sinon.stub().resolves(newTabId) + } + store = new Vuex.Store({ state, mutations, actions }) + + const db = { + sanitizeTableName: sinon.stub().returns('my_data'), + addTableFromCsv: sinon.stub().resolves(), + createProgressCounter: sinon.stub().returns(1), + deleteProgressCounter: sinon.stub(), + validateTableName: sinon.stub().resolves(), + execute: sinon.stub().resolves(), + refreshSchema: sinon.stub().resolves() + } + + // mount the component + wrapper = mount(CsvJsonImport, { + store, + propsData: { + file, + dialogName: 'addCsvJson', + db + } + }) + }) + + afterEach(() => { + sinon.restore() + }) + + it('previews', async () => { + await wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true) + expect(wrapper.find('.dialog-header').text()).to.equal('JSON import') + expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data') + expect(wrapper.findComponent({ name: 'delimiter-selector' }).exists()).to.equal(false) + expect(wrapper.find('#quote-char input').exists()).to.equal(false) + expect(wrapper.find('#escape-char input').exists()).to.equal(false) + expect(wrapper.findComponent({ name: 'check-box' }).exists()).to.equal(false) + const rows = wrapper.findAll('tbody tr') + expect(rows).to.have.lengthOf(1) + expect(rows.at(0).findAll('td').at(0).text()).to.equal([ + '{', + ' "foo": [', + ' 1,', + ' 2,', + ' 3', + ' ]', + '}' + ].join('\n') + ) + expect(wrapper.findComponent({ name: 'logs' }).text()) + .to.include('Preview parsing is completed in') + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + }) + + it('has proper state before parsing is complete', async () => { + const getJsonParseResult = sinon.stub(wrapper.vm, 'getJsonParseResult') + getJsonParseResult.onCall(0).returns({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + hasErrors: false, + messages: [] + }) + + let resolveParsing + getJsonParseResult.onCall(1).returns(new Promise(resolve => { + resolveParsing = () => resolve({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + hasErrors: false, + messages: [] + }) + })) + + await wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await wrapper.vm.$nextTick() + + // "Parsing JSON..." in the logs + expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(1).text()) + .to.equal('Parsing JSON...') + + // After 1 second - loading indicator is shown + await clock.tick(1000) + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(true) + + // All the dialog controls are disabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(true) + expect(wrapper.find('#import-finish').element.disabled).to.equal(true) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true) + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + await resolveParsing() + await getJsonParseResult.returnValues[1] + + // Loading indicator is not shown when parsing is compete + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(false) + }) + + it('has proper state before import is completed', async () => { + const getJsonParseResult = sinon.spy(wrapper.vm, 'getJsonParseResult') + + let resolveImport = sinon.stub() + wrapper.vm.db.addTableFromCsv = sinon.stub() + .resolves(new Promise(resolve => { resolveImport = resolve })) + + await wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await getJsonParseResult.returnValues[1] + await wrapper.vm.$nextTick() + + // Parsing success in the logs + expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(2).text()) + .to.equal('Importing JSON into a SQLite database...') + + // After 1 second - loading indicator is shown + await clock.tick(1000) + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(true) + + // All the dialog controls are disabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(true) + expect(wrapper.find('#import-finish').element.disabled).to.equal(true) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true) + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + expect(wrapper.vm.db.addTableFromCsv.getCall(0).args[0]).to.equal('foo') // table name + + // After resolving - loading indicator is not shown + await resolveImport() + await wrapper.vm.db.addTableFromCsv.returnValues[0] + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(false) + }) + + it('import success', async () => { + const getJsonParseResult = sinon.spy(wrapper.vm, 'getJsonParseResult') + + await wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await getJsonParseResult.returnValues[1] + await wrapper.vm.$nextTick() + + // Import success in the logs + const logs = wrapper.findComponent({ name: 'logs' }).findAll('.msg') + expect(logs).to.have.lengthOf(3) + expect(logs.at(2).text()).to.contain('Importing JSON into a SQLite database is completed in') + + // All the dialog controls are enabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(false) + expect(wrapper.find('#import-finish').element.disabled).to.equal(false) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(false) + expect(wrapper.find('#import-finish').isVisible()).to.equal(true) + }) +}) + +describe('CsvJsonImport.vue - ndjson', () => { + let state = {} + let actions = {} + let mutations = {} + let store = {} + let clock + let wrapper + const newTabId = 1 + const file = new File([], 'my data.ndjson') + + beforeEach(() => { + clock = sinon.useFakeTimers() + + // mock store state and mutations + state = {} + mutations = { + setDb: sinon.stub(), + setCurrentTabId: sinon.stub() + } + actions = { + addTab: sinon.stub().resolves(newTabId) + } + store = new Vuex.Store({ state, mutations, actions }) + + const db = { + sanitizeTableName: sinon.stub().returns('my_data'), + addTableFromCsv: sinon.stub().resolves(), + createProgressCounter: sinon.stub().returns(1), + deleteProgressCounter: sinon.stub(), + validateTableName: sinon.stub().resolves(), + execute: sinon.stub().resolves(), + refreshSchema: sinon.stub().resolves() + } + + // mount the component + wrapper = mount(CsvJsonImport, { + store, + propsData: { + file, + dialogName: 'addCsvJson', + db + } + }) + }) + + afterEach(() => { + sinon.restore() + }) + + it('previews', async () => { + sinon.stub(csv, 'parse').resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + messages: [] + }) + + wrapper.vm.preview() + await wrapper.vm.open() + await wrapper.vm.$nextTick() + expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true) + expect(wrapper.find('.dialog-header').text()).to.equal('JSON import') + expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data') + expect(wrapper.findComponent({ name: 'delimiter-selector' }).exists()).to.equal(false) + expect(wrapper.find('#quote-char input').exists()).to.equal(false) + expect(wrapper.find('#escape-char input').exists()).to.equal(false) + expect(wrapper.findComponent({ name: 'check-box' }).exists()).to.equal(false) + const rows = wrapper.findAll('tbody tr') + expect(rows).to.have.lengthOf(1) + expect(rows.at(0).findAll('td').at(0).text()).to.equal('{ "foo": [ 1, 2, 3 ] }') + expect(wrapper.findComponent({ name: 'logs' }).text()) + .to.include('Preview parsing is completed in') + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + }) + + it('has proper state before parsing is complete', async () => { + const parse = sinon.stub(csv, 'parse') + parse.onCall(0).resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1 + }) + + wrapper.vm.preview() + wrapper.vm.open() + await wrapper.vm.$nextTick() + + let resolveParsing + parse.onCall(1).returns(new Promise(resolve => { + resolveParsing = () => resolve({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + messages: [] + }) + })) + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await wrapper.vm.$nextTick() + + // "Parsing JSON..." in the logs + expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(1).text()) + .to.equal('Parsing JSON...') + + // After 1 second - loading indicator is shown + await clock.tick(1000) + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(true) + + // All the dialog controls are disabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(true) + expect(wrapper.find('#import-finish').element.disabled).to.equal(true) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true) + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + await resolveParsing() + await parse.returnValues[1] + + // Loading indicator is not shown when parsing is compete + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(false) + }) + + it('has proper state before import is completed', async () => { + const parse = sinon.stub(csv, 'parse') + parse.onCall(0).resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + hasErrors: false, + messages: [] + }) + + parse.onCall(1).resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + hasErrors: false, + messages: [] + }) + + let resolveImport = sinon.stub() + wrapper.vm.db.addTableFromCsv = sinon.stub() + .resolves(new Promise(resolve => { resolveImport = resolve })) + + wrapper.vm.preview() + wrapper.vm.open() + await wrapper.vm.$nextTick() + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await csv.parse.returnValues[1] + await wrapper.vm.$nextTick() + + // Parsing success in the logs + expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(2).text()) + .to.equal('Importing JSON into a SQLite database...') + + // After 1 second - loading indicator is shown + await clock.tick(1000) + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(true) + + // All the dialog controls are disabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(true) + expect(wrapper.find('#import-finish').element.disabled).to.equal(true) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true) + expect(wrapper.find('#import-finish').isVisible()).to.equal(false) + expect(wrapper.find('#import-start').isVisible()).to.equal(true) + expect(wrapper.vm.db.addTableFromCsv.getCall(0).args[0]).to.equal('foo') // table name + + // After resolving - loading indicator is not shown + await resolveImport() + await wrapper.vm.db.addTableFromCsv.returnValues[0] + expect( + wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists() + ).to.equal(false) + }) + + it('import success', async () => { + const parse = sinon.stub(csv, 'parse') + parse.onCall(0).resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 1, + hasErrors: false, + messages: [] + }) + // we need to separate calles because messages will mutate + parse.onCall(1).resolves({ + delimiter: '|', + data: { + columns: ['doc'], + values: { + doc: ['{ "foo": [ 1, 2, 3 ] }'] + } + }, + rowCount: 2, + hasErrors: false, + messages: [] + }) + + wrapper.vm.preview() + wrapper.vm.open() + await wrapper.vm.$nextTick() + + await wrapper.find('#csv-json-table-name input').setValue('foo') + await wrapper.find('#import-start').trigger('click') + await csv.parse.returnValues[1] + await wrapper.vm.$nextTick() + + // Import success in the logs + const logs = wrapper.findComponent({ name: 'logs' }).findAll('.msg') + expect(logs).to.have.lengthOf(3) + expect(logs.at(2).text()).to.contain('Importing JSON into a SQLite database is completed in') + + // All the dialog controls are enabled + expect(wrapper.find('#import-cancel').element.disabled).to.equal(false) + expect(wrapper.find('#import-finish').element.disabled).to.equal(false) + expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(false) + expect(wrapper.find('#import-finish').isVisible()).to.equal(true) + }) +}) diff --git a/tests/components/DbUploader.spec.js b/tests/components/DbUploader.spec.js index 0fafe67..d25c23e 100644 --- a/tests/components/DbUploader.spec.js +++ b/tests/components/DbUploader.spec.js @@ -31,7 +31,7 @@ describe('DbUploader.vue', () => { it('loads db on click and redirects to /workspace', async () => { // mock getting a file from user - const file = { name: 'test.db' } + const file = new File([], 'test.db') sinon.stub(fu, 'getFileFromUser').resolves(file) // mock db loading @@ -85,7 +85,7 @@ describe('DbUploader.vue', () => { }) // mock a file dropped by a user - const file = { name: 'test.db' } + const file = new File([], 'test.db') const dropData = { dataTransfer: new DataTransfer() } Object.defineProperty(dropData.dataTransfer, 'files', { value: [file], @@ -103,7 +103,7 @@ describe('DbUploader.vue', () => { it("doesn't redirect if already on /workspace", async () => { // mock getting a file from user - const file = { name: 'test.db' } + const file = new File([], 'test.db') sinon.stub(fu, 'getFileFromUser').resolves(file) // mock db loading @@ -136,7 +136,7 @@ describe('DbUploader.vue', () => { it('shows parse dialog if gets csv file', async () => { // mock getting a file from user - const file = { name: 'test.csv' } + const file = new File([], 'test.csv') sinon.stub(fu, 'getFileFromUser').resolves(file) // mock router @@ -168,9 +168,77 @@ describe('DbUploader.vue', () => { wrapper.destroy() }) - it('deletes temporary db if CSV import is canceled', async () => { + it('shows parse dialog if gets json file', async () => { // mock getting a file from user - const file = { name: 'test.csv' } + const file = new File([], 'test.json', { type: 'application/json' }) + sinon.stub(fu, 'getFileFromUser').resolves(file) + + // mock router + const $router = { push: sinon.stub() } + const $route = { path: '/workspace' } + + // mount the component + const wrapper = mount(DbUploader, { + attachTo: place, + store, + mocks: { $router, $route }, + propsData: { + type: 'illustrated' + } + }) + + const JsonImport = wrapper.vm.$refs.addCsvJson + sinon.stub(JsonImport, 'reset') + sinon.stub(JsonImport, 'preview').resolves() + sinon.stub(JsonImport, 'open') + + await wrapper.find('.drop-area').trigger('click') + await wrapper.vm.$nextTick() + expect(JsonImport.reset.calledOnce).to.equal(true) + await wrapper.vm.animationPromise + expect(JsonImport.preview.calledOnce).to.equal(true) + await wrapper.vm.$nextTick() + expect(JsonImport.open.calledOnce).to.equal(true) + wrapper.destroy() + }) + + it('shows parse dialog if gets ndjson file', async () => { + // mock getting a file from user + const file = new File([], 'test.ndjson') + sinon.stub(fu, 'getFileFromUser').resolves(file) + + // mock router + const $router = { push: sinon.stub() } + const $route = { path: '/workspace' } + + // mount the component + const wrapper = mount(DbUploader, { + attachTo: place, + store, + mocks: { $router, $route }, + propsData: { + type: 'illustrated' + } + }) + + const JsonImport = wrapper.vm.$refs.addCsvJson + sinon.stub(JsonImport, 'reset') + sinon.stub(JsonImport, 'preview').resolves() + sinon.stub(JsonImport, 'open') + + await wrapper.find('.drop-area').trigger('click') + await wrapper.vm.$nextTick() + expect(JsonImport.reset.calledOnce).to.equal(true) + await wrapper.vm.animationPromise + expect(JsonImport.preview.calledOnce).to.equal(true) + await wrapper.vm.$nextTick() + expect(JsonImport.open.calledOnce).to.equal(true) + wrapper.destroy() + }) + + it('deletes temporary db if import is canceled', async () => { + // mock getting a file from user + const file = new File([], 'test.csv') sinon.stub(fu, 'getFileFromUser').resolves(file) // mock router diff --git a/tests/lib/csv.spec.js b/tests/lib/csv.spec.js index a8ac5e2..55257fc 100644 --- a/tests/lib/csv.spec.js +++ b/tests/lib/csv.spec.js @@ -28,7 +28,26 @@ describe('csv.js', () => { }) }) - it('getResult without fields', () => { + it('getResult without fields but with columns', () => { + const source = { + data: [ + [1, 'foo', new Date('2021-06-30T14:10:24.717Z')], + [2, 'bar', new Date('2021-07-30T14:10:15.717Z')] + ], + meta: {} + } + const columns = ['id', 'name', 'date'] + expect(csv.getResult(source, columns)).to.eql({ + columns: ['id', 'name', 'date'], + values: { + id: [1, 2], + name: ['foo', 'bar'], + date: ['2021-06-30T14:10:24.717Z', '2021-07-30T14:10:15.717Z'] + } + }) + }) + + it('getResult without fields and columns', () => { const source = { data: [ [1, 'foo', new Date('2021-06-30T14:10:24.717Z')], diff --git a/tests/lib/utils/fileIo.spec.js b/tests/lib/utils/fileIo.spec.js index 2e12b8f..b61a9c6 100644 --- a/tests/lib/utils/fileIo.spec.js +++ b/tests/lib/utils/fileIo.spec.js @@ -106,10 +106,65 @@ describe('fileIo.js', () => { await expect(fIo.readAsArrayBuffer(blob)).to.be.rejectedWith('Problem parsing input file.') }) + it('isJSON', () => { + let file = { type: 'application/json' } + expect(fIo.isJSON(file)).to.equal(true) + + file = { type: 'application/x-sqlite3' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: '', name: 'test.db' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: '', name: 'test.sqlite' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: '', name: 'test.sqlite3' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: '', name: 'test.csv' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: '', name: 'test.ndjson' } + expect(fIo.isJSON(file)).to.equal(false) + + file = { type: 'text', name: 'test.db' } + expect(fIo.isJSON(file)).to.equal(false) + }) + + it('isNDJSON', () => { + let file = { type: 'application/json', name: 'test.json' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: 'application/x-sqlite3', name: 'test.sqlite3' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: '', name: 'test.db' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: '', name: 'test.sqlite' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: '', name: 'test.sqlite3' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: '', name: 'test.csv' } + expect(fIo.isNDJSON(file)).to.equal(false) + + file = { type: '', name: 'test.ndjson' } + expect(fIo.isNDJSON(file)).to.equal(true) + + file = { type: 'text', name: 'test.db' } + expect(fIo.isNDJSON(file)).to.equal(false) + }) + it('isDatabase', () => { let file = { type: 'application/vnd.sqlite3' } expect(fIo.isDatabase(file)).to.equal(true) + file = { type: 'application/json' } + expect(fIo.isDatabase(file)).to.equal(false) + file = { type: 'application/x-sqlite3' } expect(fIo.isDatabase(file)).to.equal(true) @@ -125,6 +180,9 @@ describe('fileIo.js', () => { file = { type: '', name: 'test.csv' } expect(fIo.isDatabase(file)).to.equal(false) + file = { type: '', name: 'test.ndjson' } + expect(fIo.isDatabase(file)).to.equal(false) + file = { type: 'text', name: 'test.db' } expect(fIo.isDatabase(file)).to.equal(false) }) diff --git a/tests/views/Main/Workspace/Schema/Schema.spec.js b/tests/views/Main/Workspace/Schema/Schema.spec.js index 4fb7734..ee8b1e4 100644 --- a/tests/views/Main/Workspace/Schema/Schema.spec.js +++ b/tests/views/Main/Workspace/Schema/Schema.spec.js @@ -125,7 +125,7 @@ describe('Schema.vue', () => { }) it('adds table', async () => { - const file = { name: 'test.csv' } + const file = new File([], 'test.csv') sinon.stub(fIo, 'getFileFromUser').resolves(file) sinon.stub(csv, 'parse').resolves({