1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-07 02:28:54 +08:00

5 Commits

Author SHA1 Message Date
lana-k
db3dbdf993 Merge branch 'master' of github.com:lana-k/sqliteviz 2023-05-17 21:41:17 +02:00
lana-k
4e13a16e33 No blocking while loading predifined #107 2023-05-17 21:37:41 +02:00
saaj
9c0103fd05 SQLite 3.41.0 and pearson correlation extension function (#106)
* Build SQLite 3.41.0

* Update pivot_vtab

* Add Pearson correlation coefficient function extension, build

* Add an easy way to running test locally without Nodejs

* Use RSS sum to pick top2 processes for the report

* Try previous Ubuntu LTS as a workaround for Firefox worker not starting
2023-03-04 22:51:25 +01:00
saaj
e4b117ffb9 Sqljs upgrade and benchmark improvements (#103)
* Update to sql.js 1.7.0

* Update to emsdk 3.0.1, replace/remove deprecated/irrelevant settings

- Renamed .bc extension to .o
- Remove deprecated INLINING_LIMIT setting
- Remove SINGLE_FILE

* Update SQLite to 3.39.3

* Collect and plot CPU and RSS charts from the benchmark containers

* Move procpath commands to a playbook, plot only top 2 RSS & CPU usage

* Optimise for size, put -flto for both compile and link
2023-03-04 17:00:46 +01:00
lana-k
6320f818cb fix undefined in tests and chart metrics 2022-07-30 16:42:30 +02:00
22 changed files with 504 additions and 305 deletions

View File

@@ -11,7 +11,7 @@ on:
jobs:
test:
name: Run tests
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Use Node.js

24
Dockerfile.test Normal file
View File

@@ -0,0 +1,24 @@
# An easy way to run tests locally without Nodejs installed:
#
# docker build -t sqliteviz/test -f Dockerfile.test .
#
FROM node:12
RUN set -ex; \
apt update; \
apt install -y chromium firefox-esr; \
npm install -g npm@7
WORKDIR /tmp/build
COPY package.json package-lock.json ./
COPY lib lib
RUN npm install
COPY . .
RUN set -ex; \
sed -i 's/browsers: \[.*\],/browsers: ['"'FirefoxHeadlessTouch'"'],/' karma.conf.js
RUN npm run lint -- --no-fix && npm run test

View File

@@ -1,4 +1,4 @@
FROM emscripten/emsdk:2.0.24
FROM emscripten/emsdk:3.0.1
WORKDIR /tmp/build

View File

@@ -43,6 +43,8 @@ SQLite [miscellaneous extensions][3] included:
SQLite 3rd party extensions included:
1. [pivot_vtab][5] -- a pivot virtual table
2. `pearson` correlation coefficient function extension from [sqlean][21]
(which is part of [squib][20])
To ease the step to have working clone locally, the build is committed into
the repository.
@@ -99,3 +101,5 @@ described in [this message from SQLite Forum][12]:
[17]: https://sqlite.org/contrib/
[18]: https://sqlite.org/contrib//download/extension-functions.c?get=25
[19]: https://github.com/lana-k/sqliteviz/blob/master/tests/lib/database/sqliteExtensions.spec.js
[20]: https://github.com/mrwilson/squib/blob/master/pearson.c
[21]: https://github.com/nalgeon/sqlean/blob/incubator/src/pearson.c

View File

@@ -1,14 +1,25 @@
# SQLite WebAssembly build micro-benchmark
This directory contains a micro-benchmark for evaluating SQLite
WebAssembly builds performance on typical SQL queries, run from
`make.sh` script. It can also serve as a smoke test.
This directory contains a micro-benchmark for evaluating SQLite WebAssembly
builds performance on read and write SQL queries, run from `make.sh` script. If
the script has permission to `nice` processes and [Procpath][1] is installed,
e.g. it is run with `sudo -E env PATH=$PATH ./make.sh`, it'll `renice` all
processes running inside the benchmark containers. It can also serve as a smoke
test (e.g. for memory leaks).
The benchmark operates on a set of SQLite WebAssembly builds expected
in `lib/build-$NAME` directories each containing `sql-wasm.js` and
`sql-wasm.wasm`. Then it creates a Docker image for each, and runs
the benchmark in Firefox and Chromium using Karma in the container.
The benchmark operates on a set of SQLite WebAssembly builds expected in
`lib/build-$NAME` directories each containing `sql-wasm.js` and
`sql-wasm.wasm`. Then it creates a Docker image for each, and runs the
benchmark in Firefox and Chromium using Karma in the container.
After successful run, the benchmark result of each build is contained
in `build-$NAME-result.json`. The JSON result files can be analysed
using `result-analysis.ipynb` Jupyter notebook.
After successful run, the benchmark produces the following per each build:
- `build-$NAME-result.json`
- `build-$NAME.sqlite` (if Procpath is installed)
- `build-$NAME.svg` (if Procpath is installed)
These files can be analysed using `result-analysis.ipynb` Jupyter notebook.
The SVG is a chart with CPU and RSS usage of each test container (i.e. Chromium
run, then Firefox run per container).
[1]: https://pypi.org/project/Procpath/

View File

@@ -1,7 +1,8 @@
#!/bin/bash -e
cleanup () {
rm -rf lib/dist $flag_file
rm -rf lib/dist "$renice_flag_file"
docker rm -f sqljs-benchmark-run 2> /dev/null || true
}
trap cleanup EXIT
@@ -11,34 +12,36 @@ if [ ! -f sample.csv ]; then
| gunzip -c > sample.csv
fi
PLAYBOOK=procpath/karma_docker.procpath
# for renice to work run like "sudo -E env PATH=$PATH ./make.sh"
test_ni=$(nice -n -1 nice)
if [ $test_ni == -1 ]; then
flag_file=$(mktemp)
test_ni=$(nice -n -5 nice)
if [ $test_ni == -5 ]; then
renice_flag_file=$(mktemp)
fi
(
while [ -f $flag_file ]; do
root_pid=$(
docker ps -f status=running -f name='^sqljs-benchmark-' -q \
| xargs -r -I{} -- docker inspect -f '{{.State.Pid}}' {}
)
if [ ! -z $root_pid ]; then
procpath query -d $'\n' "$..children[?(@.stat.pid == $root_pid)]..pid" \
| xargs -I{} -- renice -n -1 -p {} > /dev/null
fi
sleep 1
done &
)
{
while [ -f $renice_flag_file ]; do
procpath --logging-level ERROR play -f $PLAYBOOK renice:watch
done
} &
shopt -s nullglob
for d in lib/build-* ; do
rm -rf lib/dist
cp -r $d lib/dist
sample_name=$(basename $d)
name=$(basename $d)
docker build -t sqliteviz/sqljs-benchmark:$name .
docker rm sqljs-benchmark-$name 2> /dev/null || true
docker run -it --cpus 2 --name sqljs-benchmark-$name sqliteviz/sqljs-benchmark:$name
docker cp sqljs-benchmark-$name:/tmp/build/suite-result.json ${name}-result.json
docker rm sqljs-benchmark-$name
docker build -t sqliteviz/sqljs-benchmark .
docker rm sqljs-benchmark-run 2> /dev/null || true
docker run -d -it --cpus 2 --name sqljs-benchmark-run sqliteviz/sqljs-benchmark
{
rm -f ${sample_name}.sqlite
procpath play -f $PLAYBOOK -o database_file=${sample_name}.sqlite track:record
procpath play -f $PLAYBOOK -o database_file=${sample_name}.sqlite \
-o plot_file=${sample_name}.svg track:plot
} &
docker attach sqljs-benchmark-run
docker cp sqljs-benchmark-run:/tmp/build/suite-result.json ${sample_name}-result.json
docker rm sqljs-benchmark-run
done

View File

@@ -0,0 +1,28 @@
# This command may run when "sqljs-benchmark-run" does not yet exist or run
[renice:watch]
interval: 2
repeat: 30
environment:
ROOT_PID=docker inspect -f "{{.State.Pid}}" sqljs-benchmark-run 2> /dev/null || true
query:
PIDS=$..children[?(@.stat.pid in [$ROOT_PID])]..pid
command:
echo $PIDS | tr , '\n' | xargs --no-run-if-empty -I{} -- renice -n -5 -p {}
# Expected input arguments: database_file
[track:record]
interval: 1
stop_without_result: 1
environment:
ROOT_PID=docker inspect -f "{{.State.Pid}}" sqljs-benchmark-run
query:
$..children[?(@.stat.pid == $ROOT_PID)]
pid_list: $ROOT_PID
# Expected input arguments: database_file, plot_file
[track:plot]
moving_average_window: 5
title: Chromium vs Firefox (№1 RSS, №2 CPU)
custom_query_file:
procpath/top2_rss.sql
procpath/top2_cpu.sql

View File

@@ -0,0 +1,29 @@
WITH diff_all AS (
SELECT
record_id,
ts,
stat_pid,
stat_utime + stat_stime - LAG(stat_utime + stat_stime) OVER (
PARTITION BY stat_pid
ORDER BY record_id
) tick_diff,
ts - LAG(ts) OVER (
PARTITION BY stat_pid
ORDER BY record_id
) ts_diff
FROM record
), diff AS (
SELECT * FROM diff_all WHERE tick_diff IS NOT NULL
), one_time_pid_condition AS (
SELECT stat_pid
FROM record
GROUP BY 1
ORDER BY SUM(stat_utime + stat_stime) DESC
LIMIT 2
)
SELECT
ts,
stat_pid pid,
100.0 * tick_diff / (SELECT value FROM meta WHERE key = 'clock_ticks') / ts_diff value
FROM diff
JOIN one_time_pid_condition USING(stat_pid)

View File

@@ -0,0 +1,13 @@
WITH one_time_pid_condition AS (
SELECT stat_pid
FROM record
GROUP BY 1
ORDER BY SUM(stat_rss) DESC
LIMIT 2
)
SELECT
ts,
stat_pid pid,
stat_rss / 1024.0 / 1024 * (SELECT value FROM meta WHERE key = 'page_size') value
FROM record
JOIN one_time_pid_condition USING(stat_pid)

File diff suppressed because one or more lines are too long

View File

@@ -2,9 +2,11 @@ import logging
import subprocess
from pathlib import Path
# See the setting descriptions on these pages:
# - https://emscripten.org/docs/optimizing/Optimizing-Code.html
# - https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
cflags = (
'-O2',
# SQLite configuration
'-DSQLITE_DEFAULT_CACHE_SIZE=-65536', # 64 MiB
'-DSQLITE_DEFAULT_MEMSTATUS=0',
'-DSQLITE_DEFAULT_SYNCHRONOUS=0',
@@ -13,26 +15,26 @@ cflags = (
'-DSQLITE_ENABLE_FTS3',
'-DSQLITE_ENABLE_FTS3_PARENTHESIS',
'-DSQLITE_ENABLE_FTS5',
'-DSQLITE_ENABLE_JSON1',
'-DSQLITE_ENABLE_NORMALIZE',
'-DSQLITE_EXTRA_INIT=extra_init',
'-DSQLITE_OMIT_DEPRECATED',
'-DSQLITE_OMIT_LOAD_EXTENSION',
'-DSQLITE_OMIT_SHARED_CACHE',
'-DSQLITE_THREADSAFE=0',
# Compile-time optimisation
'-Os', # reduces the code size about in half comparing to -O2
'-flto',
)
emflags = (
# Base
'--memory-init-file', '0',
'-s', 'RESERVED_FUNCTION_POINTERS=64',
'-s', 'ALLOW_TABLE_GROWTH=1',
'-s', 'SINGLE_FILE=0',
# WASM
'-s', 'WASM=1',
'-s', 'ALLOW_MEMORY_GROWTH=1',
# Optimisation
'-s', 'INLINING_LIMIT=50',
'-O3',
'-s', 'ENVIRONMENT=web,worker',
# Link-time optimisation
'-Os',
'-flto',
# sql.js
'-s', 'EXPORTED_FUNCTIONS=@src/sqljs/exported_functions.json',
@@ -50,22 +52,22 @@ def build(src: Path, dst: Path):
'emcc',
*cflags,
'-c', src / 'sqlite3.c',
'-o', out / 'sqlite3.bc',
'-o', out / 'sqlite3.o',
])
logging.info('Building LLVM bitcode for extension-functions.c')
subprocess.check_call([
'emcc',
*cflags,
'-c', src / 'extension-functions.c',
'-o', out / 'extension-functions.bc',
'-o', out / 'extension-functions.o',
])
logging.info('Building WASM from bitcode')
subprocess.check_call([
'emcc',
*emflags,
out / 'sqlite3.bc',
out / 'extension-functions.bc',
out / 'sqlite3.o',
out / 'extension-functions.o',
'-o', out / 'sql-wasm.js',
])

View File

@@ -8,7 +8,7 @@ from pathlib import Path
from urllib import request
amalgamation_url = 'https://sqlite.org/2022/sqlite-amalgamation-3390000.zip'
amalgamation_url = 'https://sqlite.org/2023/sqlite-amalgamation-3410000.zip'
# Extension-functions
# ===================
@@ -28,10 +28,11 @@ extension_urls = (
('https://sqlite.org/src/raw/09f967dc?at=decimal.c', 'sqlite3_decimal_init'),
# Third-party extension
# =====================
('https://github.com/jakethaw/pivot_vtab/raw/08ab0797/pivot_vtab.c', 'sqlite3_pivotvtab_init'),
('https://github.com/jakethaw/pivot_vtab/raw/9323ef93/pivot_vtab.c', 'sqlite3_pivotvtab_init'),
('https://github.com/nalgeon/sqlean/raw/95e8d21a/src/pearson.c', 'sqlite3_pearson_init'),
)
sqljs_url = 'https://github.com/sql-js/sql.js/archive/refs/tags/v1.5.0.zip'
sqljs_url = 'https://github.com/sql-js/sql.js/archive/refs/tags/v1.7.0.zip'
def _generate_extra_init_c_function(init_function_names):

File diff suppressed because one or more lines are too long

Binary file not shown.

22
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "sqliteviz",
"version": "0.18.1",
"version": "0.22.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "sqliteviz",
"version": "0.18.1",
"version": "0.22.0",
"license": "Apache-2.0",
"dependencies": {
"codemirror": "^5.57.0",
@@ -5248,9 +5248,9 @@
"dev": true
},
"node_modules/caniuse-lite": {
"version": "1.0.30001352",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz",
"integrity": "sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==",
"version": "1.0.30001488",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz",
"integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==",
"dev": true,
"funding": [
{
@@ -5260,6 +5260,10 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
@@ -27489,7 +27493,6 @@
"integrity": "sha512-iFv9J3F5VKUPcbx+TqW5qhGmAVyXQxPRpKpPOuTLFIVTzg+iwJnrqVbL4kJU5ECGDxPESW2oCVgxv9bTlDPu7w==",
"dev": true,
"requires": {
"@babel/core": "^7.11.0",
"@babel/helper-compilation-targets": "^7.9.6",
"@babel/helper-module-imports": "^7.8.3",
"@babel/plugin-proposal-class-properties": "^7.8.3",
@@ -27502,7 +27505,6 @@
"@vue/babel-plugin-jsx": "^1.0.3",
"@vue/babel-preset-jsx": "^1.2.4",
"babel-plugin-dynamic-import-node": "^2.3.3",
"core-js": "^3.6.5",
"core-js-compat": "^3.6.5",
"semver": "^6.1.0"
}
@@ -29627,9 +29629,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001352",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz",
"integrity": "sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==",
"version": "1.0.30001488",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz",
"integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==",
"dev": true
},
"canvas-fit": {

View File

@@ -1,6 +1,6 @@
{
"name": "sqliteviz",
"version": "0.21.1",
"version": "0.22.0",
"license": "Apache-2.0",
"private": true,
"scripts": {

View File

@@ -53,5 +53,11 @@ export default {
},
updatePredefinedInquiries (state, inquiries) {
state.predefinedInquiries = Array.isArray(inquiries) ? inquiries : [inquiries]
},
setLoadingPredefinedInquiries (state, value) {
state.loadingPredefinedInquiries = value
},
setPredefinedInquiriesLoaded (state, value) {
state.predefinedInquiriesLoaded = value
}
}

View File

@@ -4,5 +4,7 @@ export default {
currentTabId: null,
untitledLastIndex: 0,
predefinedInquiries: [],
loadingPredefinedInquiries: false,
predefinedInquiriesLoaded: false,
db: null
}

View File

@@ -1,11 +1,18 @@
<template>
<div>
<div id="my-inquiries-container">
<div id="start-guide" v-if="allInquiries.length === 0">
You don't have saved inquiries so far.
<span class="link" @click="$root.$emit('createNewInquiry')">Create</span>
the one from scratch or
<span @click="importInquiries" class="link">import</span> from a file.
</div>
<div
id="loading-predefined-status"
v-if="$store.state.loadingPredefinedInquiries"
>
<loading-indicator/>
Loading predefined inquiries...
</div>
<div id="my-inquiries-content" ref="my-inquiries-content" v-show="allInquiries.length > 0">
<div id="my-inquiries-toolbar">
<div id="toolbar-buttons">
@@ -157,6 +164,7 @@ import DeleteIcon from './svg/delete'
import CloseIcon from '@/components/svg/close'
import TextField from '@/components/TextField'
import CheckBox from '@/components/CheckBox'
import LoadingIndicator from '@/components/LoadingIndicator'
import tooltipMixin from '@/tooltipMixin'
import storedInquiries from '@/lib/storedInquiries'
@@ -169,7 +177,8 @@ export default {
DeleteIcon,
CloseIcon,
TextField,
CheckBox
CheckBox,
LoadingIndicator
},
mixins: [tooltipMixin],
data () {
@@ -248,15 +257,21 @@ export default {
}
}
},
created () {
storedInquiries.readPredefinedInquiries()
.then(inquiries => {
async created () {
this.inquiries = storedInquiries.getStoredInquiries()
const loadingPredefinedInquiries = this.$store.state.loadingPredefinedInquiries
const predefinedInquiriesLoaded = this.$store.state.predefinedInquiriesLoaded
if (!predefinedInquiriesLoaded && !loadingPredefinedInquiries) {
try {
this.$store.commit('setLoadingPredefinedInquiries', true)
const inquiries = await storedInquiries.readPredefinedInquiries()
this.$store.commit('updatePredefinedInquiries', inquiries)
})
.catch(console.error)
.finally(() => {
this.inquiries = storedInquiries.getStoredInquiries()
})
this.$store.commit('setPredefinedInquiriesLoaded', true)
} catch (e) {
console.error(e)
}
this.$store.commit('setLoadingPredefinedInquiries', false)
}
},
mounted () {
this.resizeObserver = new ResizeObserver(this.calcMaxTableHeight)
@@ -441,6 +456,21 @@ export default {
</script>
<style scoped>
#my-inquiries-container {
position: relative;
}
#loading-predefined-status {
position: absolute;
right: 0;
display: flex;
gap: 4px;
font-size: 12px;
color: var(--color-text-light-2);
align-items: center;
padding: 8px;
}
#start-guide {
position: absolute;
top: 50%;

View File

@@ -66,7 +66,8 @@ export default {
notifyOnLogging: 1
})
this.$watch(
() => this.state.data.map(trace => `${trace.type}-${trace.mode}`)
() => this.state && this.state.data && this.state.data
.map(trace => `${trace.type}${trace.mode ? '-' + trace.mode : ''}`)
.join(','),
(value) => {
events.send('viz_plotly.render', null, {

View File

@@ -160,39 +160,39 @@ describe('SQLite extensions', function () {
it('supports transitive_closure', async function () {
const actual = await db.execute(`
CREATE TABLE node(
node_id INTEGER NOT NULL PRIMARY KEY,
parent_id INTEGER,
name VARCHAR(127),
FOREIGN KEY (parent_id) REFERENCES node(node_id)
);
CREATE INDEX node_parent_id_idx ON node(parent_id);
CREATE VIRTUAL TABLE node_closure USING transitive_closure(
tablename = "node",
idcolumn = "node_id",
parentcolumn = "parent_id"
node_id INTEGER NOT NULL PRIMARY KEY,
parent_id INTEGER,
name VARCHAR(127),
FOREIGN KEY (parent_id) REFERENCES node(node_id)
);
CREATE INDEX node_parent_id_idx ON node(parent_id);
INSERT INTO node VALUES
(1, NULL, 'tests'),
(2, 1, 'lib'),
(3, 2, 'database'),
(4, 2, 'utils'),
(5, 2, 'storedQueries.spec.js'),
(6, 3, '_sql.spec.js'),
(7, 3, '_statements.spec.js'),
(8, 3, 'database.spec.js'),
(9, 3, 'sqliteExtensions.spec.js'),
(10, 4, 'fileIo.spec.js'),
(11, 4, 'time.spec.js');
CREATE VIRTUAL TABLE node_closure USING transitive_closure(
tablename = "node",
idcolumn = "node_id",
parentcolumn = "parent_id"
);
SELECT name
FROM node
WHERE node_id IN (
SELECT nc.id
FROM node_closure AS nc
WHERE nc.root = 2 AND nc.depth = 2
);
INSERT INTO node VALUES
(1, NULL, 'tests'),
(2, 1, 'lib'),
(3, 2, 'database'),
(4, 2, 'utils'),
(5, 2, 'storedQueries.spec.js'),
(6, 3, '_sql.spec.js'),
(7, 3, '_statements.spec.js'),
(8, 3, 'database.spec.js'),
(9, 3, 'sqliteExtensions.spec.js'),
(10, 4, 'fileIo.spec.js'),
(11, 4, 'time.spec.js');
SELECT name
FROM node
WHERE node_id IN (
SELECT nc.id
FROM node_closure AS nc
WHERE nc.root = 2 AND nc.depth = 2
);
`)
expect(actual.values).to.eql({
name: [
@@ -293,7 +293,7 @@ describe('SQLite extensions', function () {
it('supports decimal', async function () {
const actual = await db.execute(`
select
SELECT
decimal_add(decimal('0.1'), decimal('0.2')) "add",
decimal_sub(0.2, 0.1) sub,
decimal_mul(power(2, 69), 2) mul,
@@ -430,4 +430,29 @@ describe('SQLite extensions', function () {
]
})
})
it('supports pearson', async function () {
const actual = await db.execute(`
CREATE TABLE dataset(x REAL, y REAL, z REAL);
INSERT INTO dataset VALUES
(5,3,3.2), (5,6,4.3), (5,9,5.4),
(10,3,4), (10,6,3.8), (10,9,3.6),
(15,3,4.8), (15,6,4), (15,9,3.5);
SELECT
pearson(x, x) xx,
pearson(x, y) xy,
abs(-0.12666 - pearson(x, z)) < 0.00001 xz,
pearson(y, x) yx,
pearson(y, y) yy,
abs(0.10555 - pearson(y, z)) < 0.00001 yz,
abs(-0.12666 - pearson(z, x)) < 0.00001 zx,
abs(0.10555 - pearson(z, y)) < 0.00001 zy,
pearson(z, z) zz
FROM dataset;
`)
expect(actual.values).to.eql({
xx: [1], xy: [0], xz: [1], yx: [0], yy: [1], yz: [1], zx: [1], zy: [1], zz: [1]
})
})
})

View File

@@ -7,7 +7,9 @@ const {
setCurrentTabId,
setCurrentTab,
updatePredefinedInquiries,
setDb
setDb,
setLoadingPredefinedInquiries,
setPredefinedInquiriesLoaded
} = mutations
describe('mutations', () => {
@@ -377,4 +379,22 @@ describe('mutations', () => {
updatePredefinedInquiries(state, inquiries)
expect(state.predefinedInquiries).to.eql(inquiries)
})
it('setLoadingPredefinedInquiries', () => {
const state = {
loadingPredefinedInquiries: false
}
setLoadingPredefinedInquiries(state, true)
expect(state.loadingPredefinedInquiries).to.equal(true)
})
it('setPredefinedInquiriesLoaded', () => {
const state = {
predefinedInquiriesLoaded: false
}
setPredefinedInquiriesLoaded(state, true)
expect(state.predefinedInquiriesLoaded).to.equal(true)
})
})