Add a mechanism with which to import external SQLTester scripts into the JS testing tool.
FossilOrigin-Name: bb08ba020ce1d86ca6aa92f43d5ae915f67d08fa73120e1f603d150e76166624
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#!/this/is/make
|
||||
#
|
||||
# This makefile compiles SQLTester test files into something
|
||||
# we can readily import into JavaScript.
|
||||
all:
|
||||
|
||||
SHELL := $(shell which bash 2>/dev/null)
|
||||
MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||
CLEAN_FILES :=
|
||||
DISTCLEAN_FILES := ./--dummy-- *~
|
||||
|
||||
test-list.mjs := test-list.mjs
|
||||
test-list.mjs.gz := $(test-list.mjs).gz
|
||||
CLEAN_FILES += $(test-list.mjs)
|
||||
|
||||
tests.dir := $(firstword $(wildcard tests ../../jni/src/tests))
|
||||
$(info test script dir=$(tests.dir))
|
||||
|
||||
tests.all := $(wildcard $(tests.dir)/*.test)
|
||||
|
||||
bin.touint8array := ./touint8array
|
||||
$(bin.touint8array): $(bin.touint8array).c $(MAKEFILE)
|
||||
$(CC) -o $@ $<
|
||||
CLEAN_FILES += $(bin.touint8array)
|
||||
|
||||
ifneq (,$(tests.all))
|
||||
$(test-list.mjs): $(bin.touint8array) $(tests.all) $(MAKEFILE)
|
||||
@{\
|
||||
echo 'export default ['; \
|
||||
sep=''; \
|
||||
for f in $(sort $(tests.all)); do \
|
||||
echo -en $$sep'{"name": "'$${f##*/}'", "content":'; \
|
||||
$(bin.touint8array) < $$f; \
|
||||
echo -n '}'; \
|
||||
sep=',\n'; \
|
||||
done; \
|
||||
echo '];'; \
|
||||
} > $@
|
||||
@echo "Created $@"
|
||||
$(test-list.mjs.gz): $(test-list.mjs)
|
||||
gzip -c $< > $@
|
||||
CLEAAN_FILES += $(test-list.mjs.gz)
|
||||
all: $(test-list.mjs.gz)
|
||||
else
|
||||
@echo "Cannot build $(test-list.mjs) for lack of input test files."; \
|
||||
echo "Symlink ./tests to a directory containing SQLTester-format "; \
|
||||
echo "test scripts named *.test, then try again"; \
|
||||
exit 1
|
||||
endif
|
||||
|
||||
.PHONY: clean distclean
|
||||
clean:
|
||||
-rm -f $(CLEAN_FILES)
|
||||
distclean: clean
|
||||
-rm -f $(DISTCLEAN_FILES)
|
||||
@@ -9,12 +9,13 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains the main application entry pointer for the
|
||||
** JS implementation of the SQLTester framework.
|
||||
** This file contains the main application entry pointer for the JS
|
||||
** implementation of the SQLTester framework. This version is not well
|
||||
** documented because the one it's a direct port of is documented:
|
||||
** in the main SQLite3 source tree, see
|
||||
** ext/jni/src/org/sqlite/jni/tester/SQLite3Tester.java.
|
||||
*/
|
||||
|
||||
// UNDER CONSTRUCTION. Still being ported from the Java impl.
|
||||
|
||||
import sqlite3ApiInit from '/jswasm/sqlite3.mjs';
|
||||
|
||||
const sqlite3 = await sqlite3ApiInit();
|
||||
@@ -23,6 +24,43 @@ const log = (...args)=>{
|
||||
console.log('SQLTester:',...args);
|
||||
};
|
||||
|
||||
const tryInstallVfs = function f(vfsName){
|
||||
if(f.vfsName) return false;
|
||||
const pVfs = sqlite3.capi.sqlite3_vfs_find(vfsName);
|
||||
if(pVfs){
|
||||
log("Installing",'"'+vfsName+'"',"as default VFS.");
|
||||
const rc = sqlite3.capi.sqlite3_vfs_register(pVfs, 1);
|
||||
if(rc){
|
||||
sqlite3.SQLite3Error.toss(rc,"While trying to register",vfsName,"vfs.");
|
||||
}
|
||||
f.vfsName = vfsName;
|
||||
}
|
||||
return !!pVfs;
|
||||
};
|
||||
tryInstallVfs.vfsName = undefined;
|
||||
|
||||
if( 1 ){
|
||||
// Try OPFS storage, if available...
|
||||
if(sqlite3.installOpfsSAHPoolVfs){
|
||||
await sqlite3.installOpfsSAHPoolVfs({
|
||||
clearOnInit: true,
|
||||
initialCapacity: 15,
|
||||
name: 'opfs-SQLTester'
|
||||
}).then(pool=>{
|
||||
tryInstallVfs(pool.vfsName);
|
||||
}).catch(e=>{
|
||||
log("OpfsSAHPool could not load:",e);
|
||||
});
|
||||
}
|
||||
if(sqlite3.oo1.OpfsDb){
|
||||
tryInstallVfs("opfs");
|
||||
}
|
||||
}
|
||||
|
||||
const wPost = (type,...payload)=>{
|
||||
postMessage({type, payload});
|
||||
};
|
||||
|
||||
// Return a new enum entry value
|
||||
const newE = ()=>Object.create(null);
|
||||
|
||||
@@ -215,7 +253,7 @@ class SQLTester {
|
||||
//! Test result buffer.
|
||||
#resultBuffer = [];
|
||||
//! Output representation of SQL NULL.
|
||||
#nullView = "nil";
|
||||
#nullView;
|
||||
metrics = newObj({
|
||||
//! Total tests run
|
||||
nTotalTest: 0,
|
||||
@@ -245,6 +283,7 @@ class SQLTester {
|
||||
});
|
||||
|
||||
constructor(){
|
||||
this.reset();
|
||||
}
|
||||
|
||||
outln(...args){ return this.#outer.outln(...args); }
|
||||
@@ -261,7 +300,7 @@ class SQLTester {
|
||||
this.#clearBuffer(this.#db.initSql);
|
||||
this.closeAllDbs();
|
||||
this.metrics.nTest = 0;
|
||||
this.nullView = "nil";
|
||||
this.#nullView = "nil";
|
||||
this.emitColNames = false;
|
||||
this.#db.iCurrentDb = 0;
|
||||
//this.#db.initSql.push("SELECT 1;");
|
||||
@@ -424,12 +463,19 @@ class SQLTester {
|
||||
|
||||
runTests(){
|
||||
const tStart = (new Date()).getTime();
|
||||
let isVerbose = this.verbosity();
|
||||
for(const ts of this.#aScripts){
|
||||
this.reset();
|
||||
++this.metrics.nTestFile;
|
||||
let threw = false;
|
||||
const timeStart = (new Date()).getTime();
|
||||
let msgTail = '';
|
||||
try{
|
||||
if( isVerbose ){
|
||||
this.#outer.verbose1("Running ",ts.filename());
|
||||
}else{
|
||||
msgTail = ' '+ts.filename();
|
||||
}
|
||||
ts.run(this);
|
||||
}catch(e){
|
||||
if(e instanceof SQLTesterException){
|
||||
@@ -446,7 +492,7 @@ class SQLTester {
|
||||
}finally{
|
||||
const timeEnd = (new Date()).getTime();
|
||||
this.outln("🏁", (threw ? "❌" : "✅"), " ", this.metrics.nTest,
|
||||
" test(s) in ", (timeEnd-timeStart),"ms.");
|
||||
" test(s) in ", (timeEnd-timeStart),"ms.",msgTail);
|
||||
}
|
||||
}
|
||||
const tEnd = (new Date()).getTime();
|
||||
@@ -544,7 +590,7 @@ class SQLTester {
|
||||
if(throwOnError){
|
||||
throw new DbException(self, pDb, rc);
|
||||
}else if( sb ){
|
||||
self.#appendDbErr(db, sb, rc);
|
||||
self.#appendDbErr(pDb, sb, rc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -666,13 +712,20 @@ class TestScript {
|
||||
if( 2 == args.length ){
|
||||
filename = args[0];
|
||||
content = args[1];
|
||||
}else{
|
||||
content = args[0];
|
||||
}else if( 1 == args.length ){
|
||||
if(args[0] instanceof Object){
|
||||
const o = args[0];
|
||||
filename = o.name;
|
||||
content = o.content;
|
||||
}else{
|
||||
content = args[0];
|
||||
}
|
||||
}
|
||||
if(!(content instanceof Uint8Array)){
|
||||
if('string' === typeof content){
|
||||
content = Util.utf8Encode(content);
|
||||
}else if(content instanceof ArrayBuffer){
|
||||
}else if((content instanceof ArrayBuffer)
|
||||
||(content instanceof Array)){
|
||||
content = new Uint8Array(content);
|
||||
}else{
|
||||
toss(Error, "Invalid content type for TestScript constructor.");
|
||||
@@ -686,6 +739,10 @@ class TestScript {
|
||||
return (0==arguments.length)
|
||||
? this.#testCaseName : (this.#testCaseName = arguments[0]);
|
||||
}
|
||||
filename(){
|
||||
return (0==arguments.length)
|
||||
? this.#filename : (this.#filename = arguments[0]);
|
||||
}
|
||||
|
||||
getOutputPrefix() {
|
||||
let rc = "["+(this.#moduleName || this.#filename)+"]";
|
||||
@@ -1041,7 +1098,7 @@ class RunCommand extends Command {
|
||||
ResultRowMode.ONELINE, sql);
|
||||
if( 0!==rc && t.verbosity()>0 ){
|
||||
const msg = sqlite3.capi.sqlite3_errmsg(pDb);
|
||||
ts.verbose1(argv[0]," non-fatal command error #",rc,": ",
|
||||
ts.verbose2(argv[0]," non-fatal command error #",rc,": ",
|
||||
msg,"\nfor SQL:\n",sql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
/*
|
||||
** 2023-08-29
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains a test application for SQLTester.js.
|
||||
*/
|
||||
import {default as ns} from './SQLTester.mjs';
|
||||
import {default as tests} from './test-list.mjs';
|
||||
|
||||
globalThis.sqlite3 = ns.sqlite3;
|
||||
const log = function f(...args){
|
||||
@@ -19,16 +33,13 @@ const affirm = function(expr, msg){
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Loaded",ns);
|
||||
|
||||
log("ns =",ns);
|
||||
outln("SQLTester is ready.");
|
||||
log("SQLTester is ready.");
|
||||
|
||||
let ts = new ns.TestScript('/foo.test',`
|
||||
/*
|
||||
** This is a comment. There are many like it but this one is mine.
|
||||
**
|
||||
** SCRIPT_MODULE_NAME: sanity-check
|
||||
** SCRIPT_MODULE_NAME: sanity-check-0
|
||||
** xMIXED_MODULE_NAME: mixed-module
|
||||
** xMODULE_NAME: module-name
|
||||
** xREQUIRED_PROPERTIES: small fast reliable
|
||||
@@ -45,10 +56,10 @@ let ts = new ns.TestScript('/foo.test',`
|
||||
--oom
|
||||
--db 0
|
||||
--new my.db
|
||||
--null zilch
|
||||
--null zilchy
|
||||
--testcase 1.0
|
||||
SELECT 1, null;
|
||||
--result 1 zilch
|
||||
--result 1 zilchy
|
||||
--glob *zil*
|
||||
--notglob *ZIL*
|
||||
SELECT 1, 2;
|
||||
@@ -85,20 +96,27 @@ SELECT json_array(1,2,3)
|
||||
|
||||
const sqt = new ns.SQLTester();
|
||||
try{
|
||||
affirm( !sqt.getCurrentDb(), 'sqt.getCurrentDb()' );
|
||||
sqt.openDb('/foo.db', true);
|
||||
affirm( !!sqt.getCurrentDb(),'sqt.getCurrentDb()' );
|
||||
sqt.verbosity(0);
|
||||
if(false){
|
||||
affirm( 'zilch' !== sqt.nullValue() );
|
||||
ts.run(sqt);
|
||||
affirm( 'zilch' === sqt.nullValue() );
|
||||
if( 0 ){
|
||||
affirm( !sqt.getCurrentDb(), 'sqt.getCurrentDb()' );
|
||||
sqt.openDb('/foo.db', true);
|
||||
affirm( !!sqt.getCurrentDb(),'sqt.getCurrentDb()' );
|
||||
sqt.verbosity(0);
|
||||
if(false){
|
||||
affirm( 'zilch' !== sqt.nullValue() );
|
||||
ts.run(sqt);
|
||||
affirm( 'zilch' === sqt.nullValue() );
|
||||
}
|
||||
sqt.addTestScript(ts);
|
||||
sqt.runTests();
|
||||
}else{
|
||||
for(const t of tests){
|
||||
sqt.addTestScript( new ns.TestScript(t) );
|
||||
}
|
||||
tests.length = 0;
|
||||
sqt.verbosity(0);
|
||||
sqt.runTests();
|
||||
}
|
||||
sqt.addTestScript(ts);
|
||||
sqt.runTests();
|
||||
}finally{
|
||||
log( "Metrics:", sqt.metrics );
|
||||
sqt.reset();
|
||||
}
|
||||
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||
log( "Metrics:", sqt.metrics );
|
||||
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
<p>All stuff on this page happens in the dev console.</p>
|
||||
<hr>
|
||||
<div id='test-output'></div>
|
||||
<script src='SQLTester.run.mjs' type='module'></script>
|
||||
<!--script>
|
||||
<!--script src='SQLTester.run.mjs' type='module'></script-->
|
||||
<script>
|
||||
(function(){
|
||||
const W = new Worker('scratchpad-wasmfs.mjs',{
|
||||
type: 'module'
|
||||
});
|
||||
// Noting that Firefox can't do this yet.
|
||||
const W = new Worker('SQLTester.run.mjs',{
|
||||
type: 'module'
|
||||
});
|
||||
})();
|
||||
</script-->
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
** 2023-08-29
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains a tool for writing out the contents of stdin as
|
||||
** a comma-separated list of numbers, one per byte.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
int main(int argc, char const **argv){
|
||||
int i;
|
||||
int rc = 0, colWidth = 30;
|
||||
int ch;
|
||||
printf("[");
|
||||
for( i=0; EOF!=(ch = fgetc(stdin)); ++i ){
|
||||
if( 0!=i ) printf(",");
|
||||
if( i && 0==(i%colWidth) ) puts("");
|
||||
printf("%d",ch);
|
||||
}
|
||||
printf("]");
|
||||
return rc;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
C Add\sdirectives\ssupport\sto\sJS\sSQLTester\scomparable\sto\sthe\sJava\simpl.\sThis\sbrings\sthe\stwo\sto\sfeature\sparity.
|
||||
D 2023-08-29T21:30:37.122
|
||||
C Add\sa\smechanism\swith\swhich\sto\simport\sexternal\sSQLTester\sscripts\sinto\sthe\sJS\stesting\stool.
|
||||
D 2023-08-30T00:22:54.642
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -548,9 +548,11 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce
|
||||
F ext/wasm/GNUmakefile 0e362f3fc04eab6628cbe4f1e35f4ab4a200881f6b5f753b27fb45eabeddd9d2
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
||||
F ext/wasm/SQLTester/SQLTester.mjs 40583ad88bbc32c602e9bfbcd7a90ea6bdfeed41994c1fcc0a7e9d0ffdcd9a5e
|
||||
F ext/wasm/SQLTester/SQLTester.run.mjs de03763f8085a130e17706a8c475d7bab37f77eff4f5322b0cc33504733394d7
|
||||
F ext/wasm/SQLTester/index.html 88d87e3ccbc33e7ab3773a8e48c1172e876951c4be31d1307c3700671262cddf
|
||||
F ext/wasm/SQLTester/GNUmakefile ba0430646d75a832d1647d6d204c999112d831f5e85d3ed99d8f663fea20fe19
|
||||
F ext/wasm/SQLTester/SQLTester.mjs 378868be0fcbbb92456aea10e3056f88b042e106b2c348aa51060e93726f6e10
|
||||
F ext/wasm/SQLTester/SQLTester.run.mjs 2695490e2092af0c6a9d1e4128edf830648687a54ec1f0ecd16bd1be083f3938
|
||||
F ext/wasm/SQLTester/index.html 317636557257608b103fa740c07f2d440d57b924ef2072e59c1372d4a4004c06
|
||||
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
@@ -2111,8 +2113,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 8c503dfb9fa15389613a819fcc1792e23d3c05f99a9f450f82eac5125298726f
|
||||
R e03f3f1709d7ca32242a0e49e3b98e3f
|
||||
P 7cef4a8300826adbdcb3b205e134a4272b12b4aa7dbee97731ac12282a4a9f06
|
||||
R 018b862c43a96a36d2df3223b087af85
|
||||
U stephan
|
||||
Z ecc2ea98d4d7da8116d2d29b184f2709
|
||||
Z 18f8112180ee272e1f7e50a87a0ce726
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7cef4a8300826adbdcb3b205e134a4272b12b4aa7dbee97731ac12282a4a9f06
|
||||
bb08ba020ce1d86ca6aa92f43d5ae915f67d08fa73120e1f603d150e76166624
|
||||
Reference in New Issue
Block a user