diff options
author | stephan <stephan@noemail.net> | 2022-10-19 07:34:36 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2022-10-19 07:34:36 +0000 |
commit | fd31ae3bf9a2093ae5f29a1d70226bd46baceb1a (patch) | |
tree | b6bba52c15e3cc8d6cfb7373ada9afb17d7b23d3 /ext/wasm/testing2.js | |
parent | 9dc4d5e6b44c2491b291a9b1b7d6d6be78f33364 (diff) | |
download | sqlite-fd31ae3bf9a2093ae5f29a1d70226bd46baceb1a.tar.gz sqlite-fd31ae3bf9a2093ae5f29a1d70226bd46baceb1a.zip |
Rename several demo/test files and include more of them in the end-user dist archive.
FossilOrigin-Name: 9c85835f6f50eb3b1a2b89c817816335743f04440c48bfa05aa89ec519cc0d51
Diffstat (limited to 'ext/wasm/testing2.js')
-rw-r--r-- | ext/wasm/testing2.js | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/ext/wasm/testing2.js b/ext/wasm/testing2.js deleted file mode 100644 index 5ea48db6b..000000000 --- a/ext/wasm/testing2.js +++ /dev/null @@ -1,344 +0,0 @@ -/* - 2022-05-22 - - 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. - - *********************************************************************** - - A basic test script for sqlite3-worker1.js. - - Note that the wrapper interface demonstrated in - testing-worker1-promiser.js is much easier to use from client code, as it - lacks the message-passing acrobatics demonstrated in this file. -*/ -'use strict'; -(function(){ - const T = self.SqliteTestUtil; - const SW = new Worker("jswasm/sqlite3-worker1.js"); - const DbState = { - id: undefined - }; - const eOutput = document.querySelector('#test-output'); - const log = console.log.bind(console); - const logHtml = function(cssClass,...args){ - log.apply(this, args); - const ln = document.createElement('div'); - if(cssClass) ln.classList.add(cssClass); - ln.append(document.createTextNode(args.join(' '))); - eOutput.append(ln); - }; - const warn = console.warn.bind(console); - const error = console.error.bind(console); - const toss = (...args)=>{throw new Error(args.join(' '))}; - - SW.onerror = function(event){ - error("onerror",event); - }; - - let startTime; - - /** - A queue for callbacks which are to be run in response to async - DB commands. See the notes in runTests() for why we need - this. The event-handling plumbing of this file requires that - any DB command which includes a `messageId` property also have - a queued callback entry, as the existence of that property in - response payloads is how it knows whether or not to shift an - entry off of the queue. - */ - const MsgHandlerQueue = { - queue: [], - id: 0, - push: function(type,callback){ - this.queue.push(callback); - return type + '-' + (++this.id); - }, - shift: function(){ - return this.queue.shift(); - } - }; - - const testCount = ()=>{ - logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms"); - }; - - const logEventResult = function(ev){ - const evd = ev.result; - logHtml(evd.errorClass ? 'error' : '', - "runOneTest",ev.messageId,"Worker time =", - (ev.workerRespondTime - ev.workerReceivedTime),"ms.", - "Round-trip event time =", - (performance.now() - ev.departureTime),"ms.", - (evd.errorClass ? ev.message : "")//, JSON.stringify(evd) - ); - }; - - const runOneTest = function(eventType, eventArgs, callback){ - T.assert(eventArgs && 'object'===typeof eventArgs); - /* ^^^ that is for the testing and messageId-related code, not - a hard requirement of all of the Worker-exposed APIs. */ - const messageId = MsgHandlerQueue.push(eventType,function(ev){ - logEventResult(ev); - if(callback instanceof Function){ - callback(ev); - testCount(); - } - }); - const msg = { - type: eventType, - args: eventArgs, - dbId: DbState.id, - messageId: messageId, - departureTime: performance.now() - }; - log("Posting",eventType,"message to worker dbId="+(DbState.id||'default')+':',msg); - SW.postMessage(msg); - }; - - /** Methods which map directly to onmessage() event.type keys. - They get passed the inbound event.data. */ - const dbMsgHandler = { - open: function(ev){ - DbState.id = ev.dbId; - log("open result",ev); - }, - exec: function(ev){ - log("exec result",ev); - }, - export: function(ev){ - log("export result",ev); - }, - error: function(ev){ - error("ERROR from the worker:",ev); - logEventResult(ev); - }, - resultRowTest1: function f(ev){ - if(undefined === f.counter) f.counter = 0; - if(null === ev.rowNumber){ - /* End of result set. */ - T.assert(undefined === ev.row) - .assert(Array.isArray(ev.columnNames)) - .assert(ev.columnNames.length); - }else{ - T.assert(ev.rowNumber > 0); - ++f.counter; - } - //log("exec() result row:",ev); - T.assert(null === ev.rowNumber || 'number' === typeof ev.row.b); - } - }; - - /** - "The problem" now is that the test results are async. We - know, however, that the messages posted to the worker will - be processed in the order they are passed to it, so we can - create a queue of callbacks to handle them. The problem - with that approach is that it's not error-handling - friendly, in that an error can cause us to bypass a result - handler queue entry. We have to perform some extra - acrobatics to account for that. - - Problem #2 is that we cannot simply start posting events: we - first have to post an 'open' event, wait for it to respond, and - collect its db ID before continuing. If we don't wait, we may - well fire off 10+ messages before the open actually responds. - */ - const runTests2 = function(){ - const mustNotReach = ()=>{ - throw new Error("This is not supposed to be reached."); - }; - runOneTest('exec',{ - sql: ["create table t(a,b);", - "insert into t(a,b) values(1,2),(3,4),(5,6)" - ], - resultRows: [], columnNames: [] - }, function(ev){ - ev = ev.result; - T.assert(0===ev.resultRows.length) - .assert(0===ev.columnNames.length); - }); - runOneTest('exec',{ - sql: 'select a a, b b from t order by a', - resultRows: [], columnNames: [], saveSql:[] - }, function(ev){ - ev = ev.result; - T.assert(3===ev.resultRows.length) - .assert(1===ev.resultRows[0][0]) - .assert(6===ev.resultRows[2][1]) - .assert(2===ev.columnNames.length) - .assert('b'===ev.columnNames[1]); - }); - //if(1){ error("Returning prematurely for testing."); return; } - runOneTest('exec',{ - sql: 'select a a, b b from t order by a', - resultRows: [], columnNames: [], - rowMode: 'object' - }, function(ev){ - ev = ev.result; - T.assert(3===ev.resultRows.length) - .assert(1===ev.resultRows[0].a) - .assert(6===ev.resultRows[2].b) - }); - runOneTest('exec',{sql:'intentional_error'}, mustNotReach); - // Ensure that the message-handler queue survives ^^^ that error... - runOneTest('exec',{ - sql:'select 1', - resultRows: [], - //rowMode: 'array', // array is the default in the Worker interface - }, function(ev){ - ev = ev.result; - T.assert(1 === ev.resultRows.length) - .assert(1 === ev.resultRows[0][0]); - }); - runOneTest('exec',{ - sql: 'select a a, b b from t order by a', - callback: 'resultRowTest1', - rowMode: 'object' - }, function(ev){ - T.assert(3===dbMsgHandler.resultRowTest1.counter); - dbMsgHandler.resultRowTest1.counter = 0; - }); - runOneTest('exec',{ - sql:[ - "pragma foreign_keys=0;", - // ^^^ arbitrary query with no result columns - "select a, b from t order by a desc;", - "select a from t;" - // multi-statement exec only honors results from the first - // statement with result columns (regardless of whether) - // it has any rows). - ], - rowMode: 1, - resultRows: [] - },function(ev){ - const rows = ev.result.resultRows; - T.assert(3===rows.length). - assert(6===rows[0]); - }); - runOneTest('exec',{sql: 'delete from t where a>3'}); - runOneTest('exec',{ - sql: 'select count(a) from t', - resultRows: [] - },function(ev){ - ev = ev.result; - T.assert(1===ev.resultRows.length) - .assert(2===ev.resultRows[0][0]); - }); - if(0){ - // export requires reimpl. for portability reasons. - runOneTest('export',{}, function(ev){ - ev = ev.result; - T.assert('string' === typeof ev.filename) - .assert(ev.buffer instanceof Uint8Array) - .assert(ev.buffer.length > 1024) - .assert('application/x-sqlite3' === ev.mimetype); - }); - } - /***** close() tests must come last. *****/ - runOneTest('close',{unlink:true},function(ev){ - ev = ev.result; - T.assert('string' === typeof ev.filename); - }); - runOneTest('close',{unlink:true},function(ev){ - ev = ev.result; - T.assert(undefined === ev.filename); - logHtml('warning',"This is the final test."); - }); - logHtml('warning',"Finished posting tests. Waiting on async results."); - }; - - const runTests = function(){ - /** - Design decision time: all remaining tests depend on the 'open' - command having succeeded. In order to support multiple DBs, the - upcoming commands ostensibly have to know the ID of the DB they - want to talk to. We have two choices: - - 1) We run 'open' and wait for its response, which contains the - db id. - - 2) We have the Worker automatically use the current "default - db" (the one which was most recently opened) if no db id is - provided in the message. When we do this, the main thread may - well fire off _all_ of the test messages before the 'open' - actually responds, but because the messages are handled on a - FIFO basis, those after the initial 'open' will pick up the - "default" db. However, if the open fails, then all pending - messages (until next next 'open', at least) except for 'close' - will fail and we have no way of cancelling them once they've - been posted to the worker. - - Which approach we use below depends on the boolean value of - waitForOpen. - */ - const waitForOpen = 1, - simulateOpenError = 0 /* if true, the remaining tests will - all barf if waitForOpen is - false. */; - logHtml('', - "Sending 'open' message and",(waitForOpen ? "" : "NOT ")+ - "waiting for its response before continuing."); - startTime = performance.now(); - runOneTest('open', { - filename:'testing2.sqlite3', - simulateError: simulateOpenError - }, function(ev){ - log("open result",ev); - T.assert('testing2.sqlite3'===ev.result.filename) - .assert(ev.dbId) - .assert(ev.messageId); - DbState.id = ev.dbId; - if(waitForOpen) setTimeout(runTests2, 0); - }); - if(!waitForOpen) runTests2(); - }; - - SW.onmessage = function(ev){ - if(!ev.data || 'object'!==typeof ev.data){ - warn("Unknown sqlite3-worker message type:",ev); - return; - } - ev = ev.data/*expecting a nested object*/; - //log("main window onmessage:",ev); - if(ev.result && ev.messageId){ - /* We're expecting a queued-up callback handler. */ - const f = MsgHandlerQueue.shift(); - if('error'===ev.type){ - dbMsgHandler.error(ev); - return; - } - T.assert(f instanceof Function); - f(ev); - return; - } - switch(ev.type){ - case 'sqlite3-api': - switch(ev.result){ - case 'worker1-ready': - log("Message:",ev); - self.sqlite3TestModule.setStatus(null); - runTests(); - return; - default: - warn("Unknown sqlite3-api message type:",ev); - return; - } - default: - if(dbMsgHandler.hasOwnProperty(ev.type)){ - try{dbMsgHandler[ev.type](ev);} - catch(err){ - error("Exception while handling db result message", - ev,":",err); - } - return; - } - warn("Unknown sqlite3-api message type:",ev); - } - }; - log("Init complete, but async init bits may still be running."); -})(); |