--- /dev/null
+#!/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)
** 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();
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);
//! Test result buffer.
#resultBuffer = [];
//! Output representation of SQL NULL.
- #nullView = "nil";
+ #nullView;
metrics = newObj({
//! Total tests run
nTotalTest: 0,
});
constructor(){
+ this.reset();
}
outln(...args){ return this.#outer.outln(...args); }
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;");
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){
}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();
if(throwOnError){
throw new DbException(self, pDb, rc);
}else if( sb ){
- self.#appendDbErr(db, sb, rc);
+ self.#appendDbErr(pDb, sb, rc);
}
break;
}
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.");
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)+"]";
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);
}
}
+/*
+** 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){
}
}
-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
--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;
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 );
-
<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>
--- /dev/null
+/*
+** 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;
+}
-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
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
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.
-7cef4a8300826adbdcb3b205e134a4272b12b4aa7dbee97731ac12282a4a9f06
\ No newline at end of file
+bb08ba020ce1d86ca6aa92f43d5ae915f67d08fa73120e1f603d150e76166624
\ No newline at end of file