]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Init bits of a port of Java's SQLTester to JS. Far from complete.
authorstephan <stephan@noemail.net>
Tue, 29 Aug 2023 11:22:45 +0000 (11:22 +0000)
committerstephan <stephan@noemail.net>
Tue, 29 Aug 2023 11:22:45 +0000 (11:22 +0000)
FossilOrigin-Name: 60eec5ceda80c64870713df8e9aeabeef933c007f2010792225a07d5ef36baef

ext/wasm/SQLTester/SQLTester.mjs [new file with mode: 0644]
ext/wasm/SQLTester/SQLTester.run.mjs [new file with mode: 0644]
ext/wasm/SQLTester/index.html [new file with mode: 0644]
manifest
manifest.uuid

diff --git a/ext/wasm/SQLTester/SQLTester.mjs b/ext/wasm/SQLTester/SQLTester.mjs
new file mode 100644 (file)
index 0000000..c295bbd
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+** 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 the main application entry pointer for the
+** JS implementation of the SQLTester framework.
+*/
+
+// UNDER CONSTRUCTION. Still being ported from the Java impl.
+
+import sqlite3ApiInit from '/jswasm/sqlite3.mjs';
+
+const sqlite3 = await sqlite3ApiInit();
+
+const log = (...args)=>{
+  console.log('SQLTester:',...args);
+};
+
+// Return a new enum entry value
+const newE = ()=>Object.create(null);
+
+const newObj = (props)=>Object.assign(newE(), props);
+
+/**
+   Modes for how to escape (or not) column values and names from
+   SQLTester.execSql() to the result buffer output.
+*/
+const ResultBufferMode = Object.assign(Object.create(null),{
+  //! Do not append to result buffer
+  NONE: newE(),
+  //! Append output escaped.
+  ESCAPED: newE(),
+  //! Append output as-is
+  ASIS: newE()
+});
+
+/**
+   Modes to specify how to emit multi-row output from
+   SQLTester.execSql() to the result buffer.
+*/
+const ResultRowMode = newObj({
+  //! Keep all result rows on one line, space-separated.
+  ONLINE: newE(),
+  //! Add a newline between each result row.
+  NEWLINE: newE()
+});
+
+class SQLTesterException extends globalThis.Error {
+  constructor(...args){
+    super(args.join(' '));
+  }
+  isFatal() { return false; }
+}
+
+SQLTesterException.toss = (...args)=>{
+  throw new SQLTesterException(...args);
+}
+
+class DbException extends SQLTesterException {
+  constructor(...args){
+    super(...args);
+    //TODO...
+    //const db = args[0];
+    //if( db instanceof sqlite3.oo1.DB )
+  }
+  isFatal() { return true; }
+}
+
+class TestScriptFailed extends SQLTesterException {
+  constructor(...args){
+    super(...args);
+  }
+  isFatal() { return true; }
+}
+
+class UnknownCommand extends SQLTesterException {
+  constructor(...args){
+    super(...args);
+  }
+}
+
+class IncompatibleDirective extends SQLTesterException {
+  constructor(...args){
+    super(...args);
+  }
+}
+
+const toss = (errType, ...args)=>{
+  if( !(errType instanceof SQLTesterException)){
+    args.unshift(errType);
+    errType = SQLTesterException;
+  }
+  throw new errType(...args);
+};
+
+const __utf8Decoder = new TextDecoder();
+const __utf8Encoder = new TextEncoder('utf-8');
+const __SAB = ('undefined'===typeof globalThis.SharedArrayBuffer)
+      ? function(){} : globalThis.SharedArrayBuffer;
+
+const Util = newObj({
+  toss,
+
+  unlink: function(fn){
+    return 0==sqlite3.wasm.sqlite3_wasm_vfs_unlink(0,fn);
+  },
+
+  argvToString: (list)=>list.join(" "),
+
+  utf8Decode: function(arrayBuffer, begin, end){
+    return __utf8Decoder.decode(
+      (arrayBuffer.buffer instanceof __SAB)
+        ? arrayBuffer.slice(begin, end)
+        : arrayBuffer.subarray(begin, end)
+    );
+  },
+
+  utf8Encode: (str)=>__utf8Encoder.encode(str)
+})/*Util*/;
+
+class Outer {
+  #lnBuf = [];
+  #verbosity = 0;
+  #logger = console.log.bind(console);
+
+  out(...args){
+    this.#lnBuf.append(...args);
+    return this;
+  }
+  outln(...args){
+    this.#lnBuf.append(...args,'\n');
+    this.logger(this.#lnBuf.join(''));
+    this.#lnBuf.length = 0;
+    return this;
+  }
+
+  #verboseN(lvl, argv){
+    if( this.#verbosity>=lvl ){
+      const pre = this.getOutputPrefix ? this.getOutputPrefix() : '';
+      this.outln('VERBOSE ',lvl,' ',pre,': ',...argv);
+    }
+  }
+  verbose1(...args){ return this.#verboseN(1,args); }
+  verbose2(...args){ return this.#verboseN(2,args); }
+  verbose3(...args){ return this.#verboseN(3,args); }
+
+  verbosity(){
+    let rc;
+    if(arguments.length){
+      rc = this.#verbosity;
+      this.#verbosity = arguments[0];
+    }else{
+      rc = this.#verbosity;
+    }
+    return rc;
+  }
+
+}/*Outer*/
+
+class SQLTester {
+  SQLTester(){}
+
+  #aFiles = [];
+  #inputBuffer = [];
+  #outputBuffer = [];
+  #resultBuffer = [];
+  #nullView = "nil";
+  #metrics = newObj({
+    nTotalTest: 0, nTestFile: 0, nAbortedScript: 0
+  });
+  #emitColNames = false;
+  #keepGoing = false;
+  #aDb = [];
+  #db = newObj({
+    list: [],
+    iCurrent: 0,
+    initialDbName: "test.db",
+  });
+
+}/*SQLTester*/
+
+class Command {
+  Command(){
+  }
+  process(sqlTester,testScript,argv){
+    SQLTesterException.toss("process() must be overridden");
+  }
+  argcCheck(testScript,argv,min,max){
+    const argc = argv.length-1;
+    if(argc<min || (max>=0 && argc>max)){
+      if( min==max ){
+        testScript.toss(argv[0]," requires exactly ",min," argument(s)");
+      }else if(max>0){
+        testScript.toss(argv[0]," requires ",min,"-",max," arguments.");
+      }else{
+        testScript.toss(argv[0]," requires at least ",min," arguments.");
+      }
+    }
+
+  }
+}
+
+class Cursor {
+  src;
+  buffer = [];
+  pos = 0;
+  //! Current line number. Starts at 0 for internal reasons and will
+  // line up with 1-based reality once parsing starts.
+  lineNo = 0 /* yes, zero */;
+  //! Putback value for this.pos.
+  putbackPos = 0;
+  //! Putback line number
+  putbackLineNo = 0;
+  //! Peeked-to pos, used by peekLine() and consumePeeked().
+  peekedPos = 0;
+  //! Peeked-to line number.
+  peekedLineNo = 0;
+
+  //! Restore parsing state to the start of the stream.
+  rewind(){
+    this.buffer.length = 0;
+    this.pos = this.lineNo = this.putbackPos =
+      this.putbackLineNo = this.peekedPos = this.peekedLineNo = 0;
+  }
+}
+
+class TestScript {
+  #cursor = new Cursor();
+  #verbosity = 0;
+  #moduleName = null;
+  #filename = null;
+  #testCaseName = null;
+  #outer = new Outer();
+  #verboseN(lvl, argv){
+    if( this.#verbosity>=lvl ){
+      this.outln('VERBOSE ',lvl,': ',...argv);
+    }
+  }
+
+  verbose1(...args){ return this.#verboseN(1,args); }
+  verbose2(...args){ return this.#verboseN(2,args); }
+  verbose3(...args){ return this.#verboseN(3,args); }
+
+  TestScript(content){
+    this.cursor.src = content;
+    this.outer.outputPrefix = ()=>this.getOutputPrefix();
+  }
+
+  verbosity(){
+    let rc;
+    if(arguments.length){
+      rc = this.#verbosity;
+      this.#verbosity = arguments[0];
+    }else{
+      rc = this.#verbosity;
+    }
+    return rc;
+  }
+
+  getOutputPrefix() {
+    const rc =  "["+(this.moduleName || this.filename)+"]";
+    if( this.testCaseName ) rc += "["+this.testCaseName+"]";
+    return rc + " line "+ this.cur.lineNo;
+  }
+
+  toss(...args){
+    Util.toss(this.getOutputPrefix()+":",TestScriptFailed,...args)
+  }
+
+}/*TestScript*/;
+
+
+const namespace = newObj({
+  SQLTester: new SQLTester(),
+  DbException,
+  IncompatibleDirective,
+  SQLTesterException,
+  TestScriptFailed,
+  UnknownCommand
+});
+
+
+export {namespace as default};
diff --git a/ext/wasm/SQLTester/SQLTester.run.mjs b/ext/wasm/SQLTester/SQLTester.run.mjs
new file mode 100644 (file)
index 0000000..0a0f890
--- /dev/null
@@ -0,0 +1,8 @@
+import {default as ns} from './SQLTester.mjs';
+
+const log = (...args)=>{
+  console.log('SQLTester.run:',...args);
+};
+
+
+log("SQLTester is ostensibly ready.");
diff --git a/ext/wasm/SQLTester/index.html b/ext/wasm/SQLTester/index.html
new file mode 100644 (file)
index 0000000..e782f13
--- /dev/null
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
+    <!--link rel="stylesheet" href="../common/emscripten.css"/-->
+    <link rel="stylesheet" href="../common/testing.css"/>
+    <title>SQLTester</title>
+  </head>
+  <body>
+    <p>SQLTester App.
+    </p>
+    <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>
+      (function(){
+          const W = new Worker('scratchpad-wasmfs.mjs',{
+              type: 'module'
+          });
+      })();
+    </script-->
+  </body>
+</html>
index b237cd5f65712108c3b33a69bbdc563864703836..9e9e27578e04f12b0e589725f052b47fa8b7c960 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\ssome\sdead\scode.\sAdd\sa\sskeleton\sSQLTester\sscript\sfor\sfts5.
-D 2023-08-29T00:10:31.208
+C Init\sbits\sof\sa\sport\sof\sJava's\sSQLTester\sto\sJS.\sFar\sfrom\scomplete.
+D 2023-08-29T11:22:45.711
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -548,6 +548,9 @@ 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 a3d6ed049e578b2d0965273016f56293584823760df8ff850868c1f8aea17533
+F ext/wasm/SQLTester/SQLTester.run.mjs 156e174b98e7dd78bf6d1438d32e60d7a647f8b51d8246a3054e5fdfe6042478
+F ext/wasm/SQLTester/index.html 88d87e3ccbc33e7ab3773a8e48c1172e876951c4be31d1307c3700671262cddf
 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
@@ -2108,8 +2111,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 76d3911c370b3dc02d119045003f87ad20a6efd9f7a44d4feb59b7c801ac8981
-R 7d288c901b3674a6a88e2405123881f5
+P 6c83e31fa96f65b61377c0c801cc32b3c8ca27a0c8442f860364bec258c003cb
+R 94685fe29bdbe21cb1fdfbf40f131ffe
+T *branch * js-tester
+T *sym-js-tester *
+T -sym-trunk * Cancelled\sby\sbranch.
 U stephan
-Z 6f3a62c9006357f22c26cb9d02ee32ca
+Z 952fd010d6a4d240388ad80f3eddac99
 # Remove this line to create a well-formed Fossil manifest.
index 094b411e25e0cb3e4ba8ef335eaeff7cf86be91c..d92a1595edbd70f5b4de95990869c3048020b408 100644 (file)
@@ -1 +1 @@
-6c83e31fa96f65b61377c0c801cc32b3c8ca27a0c8442f860364bec258c003cb
\ No newline at end of file
+60eec5ceda80c64870713df8e9aeabeef933c007f2010792225a07d5ef36baef
\ No newline at end of file