Port the SQLTester 'v1' commands to the 'v2' evaluation bits. Still TODO is swapping out v1 with these separate impls.
FossilOrigin-Name: 0cf57e5b0f90779e450e9db1ca009610df5e6f4487337d49017636bde3bb02d6
This commit is contained in:
parent
35af4c5ff1
commit
e35a703b76
@ -234,7 +234,7 @@ public class SQLTester {
|
||||
sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; }
|
||||
|
||||
sqlite3 getDbById(int id) throws Exception{
|
||||
return affirmDbId(id).aDb[iCurrentDb];
|
||||
return affirmDbId(id).aDb[id];
|
||||
}
|
||||
|
||||
void closeDb(int id) throws Exception{
|
||||
|
@ -12,6 +12,8 @@
|
||||
** This file contains the TestScript2 part of the SQLTester framework.
|
||||
*/
|
||||
package org.sqlite.jni.tester;
|
||||
import static org.sqlite.jni.SQLite3Jni.*;
|
||||
import org.sqlite.jni.sqlite3;
|
||||
import java.util.Arrays;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.*;
|
||||
@ -22,6 +24,12 @@ class SQLTestException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
class TestScript2Failed extends SQLTestException {
|
||||
public TestScript2Failed(TestScript2 ts, String msg){
|
||||
super(ts.getOutputPrefix()+": "+msg);
|
||||
}
|
||||
}
|
||||
|
||||
class SkipTestRemainder2 extends SQLTestException {
|
||||
public SkipTestRemainder2(TestScript2 ts){
|
||||
super(ts.getOutputPrefix()+": skipping remainder");
|
||||
@ -73,23 +81,221 @@ abstract class Command2 {
|
||||
}
|
||||
}
|
||||
|
||||
//! --close command
|
||||
class CloseDbCommand2 extends Command2 {
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,0,1);
|
||||
Integer id;
|
||||
if(argv.length>1){
|
||||
String arg = argv[1];
|
||||
if("all".equals(arg)){
|
||||
t.closeAllDbs();
|
||||
return;
|
||||
}
|
||||
else{
|
||||
id = Integer.parseInt(arg);
|
||||
}
|
||||
}else{
|
||||
id = t.getCurrentDbId();
|
||||
}
|
||||
t.closeDb(id);
|
||||
}
|
||||
}
|
||||
|
||||
//! --db command
|
||||
class DbCommand2 extends Command2 {
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,1);
|
||||
t.setCurrentDb( Integer.parseInt(argv[1]) );
|
||||
}
|
||||
}
|
||||
|
||||
//! --glob command
|
||||
class GlobCommand2 extends Command2 {
|
||||
private boolean negate = false;
|
||||
public GlobCommand2(){}
|
||||
protected GlobCommand2(boolean negate){ this.negate = negate; }
|
||||
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,1);
|
||||
t.incrementTestCounter();
|
||||
final String sql = t.takeInputBuffer();
|
||||
int rc = t.execSql(null, true, ResultBufferMode.ESCAPED,
|
||||
ResultRowMode.ONELINE, sql);
|
||||
final String result = t.getResultText();
|
||||
final String sArgs = Util.argvToString(argv);
|
||||
//t.verbose(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs);
|
||||
final String glob = argv[1];
|
||||
rc = SQLTester.strglob(glob, result);
|
||||
if( (negate && 0==rc) || (!negate && 0!=rc) ){
|
||||
ts.toss(argv[0], " mismatch: ", glob," vs input: ",result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! --json command
|
||||
class JsonCommand2 extends ResultCommand2 {
|
||||
public JsonCommand2(){ super(ResultBufferMode.ASIS); }
|
||||
}
|
||||
|
||||
//! --json-block command
|
||||
class JsonBlockCommand2 extends TableResultCommand2 {
|
||||
public JsonBlockCommand2(){ super(true); }
|
||||
}
|
||||
|
||||
//! --new command
|
||||
class NewDbCommand2 extends OpenDbCommand2 {
|
||||
public NewDbCommand2(){ super(true); }
|
||||
}
|
||||
|
||||
//! Placeholder dummy/no-op commands
|
||||
class NoopCommand2 extends Command2 {
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
}
|
||||
}
|
||||
|
||||
//! --notglob command
|
||||
class NotGlobCommand2 extends GlobCommand2 {
|
||||
public NotGlobCommand2(){
|
||||
super(true);
|
||||
}
|
||||
}
|
||||
|
||||
//! --null command
|
||||
class NullCommand2 extends Command2 {
|
||||
public void process(
|
||||
SQLTester st, TestScript2 ts, String[] argv
|
||||
) throws Exception{
|
||||
argcCheck(argv,1);
|
||||
st.setNullValue( argv[1] );
|
||||
}
|
||||
}
|
||||
|
||||
//! --open command
|
||||
class OpenDbCommand2 extends Command2 {
|
||||
private boolean createIfNeeded = false;
|
||||
public OpenDbCommand2(){}
|
||||
protected OpenDbCommand2(boolean c){createIfNeeded = c;}
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,1);
|
||||
t.openDb(argv[1], createIfNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
//! --print command
|
||||
class PrintCommand2 extends Command2 {
|
||||
public void process(
|
||||
SQLTester st, TestScript2 ts, String[] argv
|
||||
) throws Exception{
|
||||
st.out(ts.getOutputPrefix(),": ");
|
||||
if( 1==argv.length ){
|
||||
st.outln( st.getInputText() );
|
||||
final String body = ts.fetchCommandBody();
|
||||
if( 1==argv.length && null==body ){
|
||||
st.out( st.getInputText() );
|
||||
}else{
|
||||
st.outln( Util.argvToString(argv) );
|
||||
}
|
||||
final String body = ts.fetchCommandBody();
|
||||
if( null!=body ){
|
||||
st.out(body,"\n");
|
||||
st.out(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! --result command
|
||||
class ResultCommand2 extends Command2 {
|
||||
private final ResultBufferMode bufferMode;
|
||||
protected ResultCommand2(ResultBufferMode bm){ bufferMode = bm; }
|
||||
public ResultCommand2(){ this(ResultBufferMode.ESCAPED); }
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,0,-1);
|
||||
t.incrementTestCounter();
|
||||
final String sql = t.takeInputBuffer();
|
||||
//t.verbose(argv[0]," SQL =\n",sql);
|
||||
int rc = t.execSql(null, false, bufferMode, ResultRowMode.ONELINE, sql);
|
||||
final String result = t.getResultText().trim();
|
||||
final String sArgs = argv.length>1 ? Util.argvToString(argv) : "";
|
||||
if( !result.equals(sArgs) ){
|
||||
t.outln(argv[0]," FAILED comparison. Result buffer:\n",
|
||||
result,"\nargs:\n",sArgs);
|
||||
ts.toss(argv[0]+" comparison failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! --run command
|
||||
class RunCommand2 extends Command2 {
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,0,1);
|
||||
final sqlite3 db = (1==argv.length)
|
||||
? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) );
|
||||
final String sql = t.takeInputBuffer();
|
||||
int rc = t.execSql(db, false, ResultBufferMode.NONE,
|
||||
ResultRowMode.ONELINE, sql);
|
||||
if( 0!=rc && t.isVerbose() ){
|
||||
String msg = sqlite3_errmsg(db);
|
||||
t.verbose(argv[0]," non-fatal command error #",rc,": ",
|
||||
msg,"\nfor SQL:\n",sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! --tableresult command
|
||||
class TableResultCommand2 extends Command2 {
|
||||
private final boolean jsonMode;
|
||||
protected TableResultCommand2(boolean jsonMode){ this.jsonMode = jsonMode; }
|
||||
public TableResultCommand2(){ this(false); }
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,0);
|
||||
t.incrementTestCounter();
|
||||
String body = ts.fetchCommandBody();
|
||||
if( null==body ) ts.toss("Missing ",argv[0]," body.");
|
||||
body = body.trim();
|
||||
if( !body.endsWith("\n--end") ){
|
||||
ts.toss(argv[0], " must be terminated with --end.");
|
||||
}else{
|
||||
int n = body.length();
|
||||
body = body.substring(0, n-6);
|
||||
}
|
||||
final String[] globs = body.split("\\s*\\n\\s*");
|
||||
if( globs.length < 1 ){
|
||||
ts.toss(argv[0], " requires 1 or more ",
|
||||
(jsonMode ? "json snippets" : "globs"),".");
|
||||
}
|
||||
final String sql = t.takeInputBuffer();
|
||||
t.execSql(null, true,
|
||||
jsonMode ? ResultBufferMode.ASIS : ResultBufferMode.ESCAPED,
|
||||
ResultRowMode.NEWLINE, sql);
|
||||
final String rbuf = t.getResultText();
|
||||
final String[] res = rbuf.split("\n");
|
||||
if( res.length != globs.length ){
|
||||
ts.toss(argv[0], " failure: input has ", res.length,
|
||||
" row(s) but expecting ",globs.length);
|
||||
}
|
||||
for(int i = 0; i < res.length; ++i){
|
||||
final String glob = globs[i].replaceAll("\\s+"," ").trim();
|
||||
//t.verbose(argv[0]," <<",glob,">> vs <<",res[i],">>");
|
||||
if( jsonMode ){
|
||||
if( !glob.equals(res[i]) ){
|
||||
ts.toss(argv[0], " json <<",glob, ">> does not match: <<",
|
||||
res[i],">>");
|
||||
}
|
||||
}else if( 0 != SQLTester.strglob(glob, res[i]) ){
|
||||
ts.toss(argv[0], " glob <<",glob,">> does not match: <<",res[i],">>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! --testcase command
|
||||
class TestCaseCommand2 extends Command2 {
|
||||
public void process(SQLTester t, TestScript2 ts, String[] argv) throws Exception{
|
||||
argcCheck(argv,1);
|
||||
// TODO?: do something with the test name
|
||||
final String body = ts.fetchCommandBody();
|
||||
t.clearResultBuffer();
|
||||
t.clearInputBuffer().append(null==body ? "" : body);
|
||||
}
|
||||
}
|
||||
|
||||
class CommandDispatcher2 {
|
||||
|
||||
private static java.util.Map<String,Command2> commandMap =
|
||||
@ -103,7 +309,21 @@ class CommandDispatcher2 {
|
||||
Command2 rv = commandMap.get(name);
|
||||
if( null!=rv ) return rv;
|
||||
switch(name){
|
||||
case "close": rv = new CloseDbCommand2(); break;
|
||||
case "db": rv = new DbCommand2(); break;
|
||||
case "glob": rv = new GlobCommand2(); break;
|
||||
case "json": rv = new JsonCommand2(); break;
|
||||
case "json-block": rv = new JsonBlockCommand2(); break;
|
||||
case "new": rv = new NewDbCommand2(); break;
|
||||
case "notglob": rv = new NotGlobCommand2(); break;
|
||||
case "null": rv = new NullCommand2(); break;
|
||||
case "oom": rv = new NoopCommand2(); break;
|
||||
case "open": rv = new OpenDbCommand2(); break;
|
||||
case "print": rv = new PrintCommand2(); break;
|
||||
case "result": rv = new ResultCommand2(); break;
|
||||
case "run": rv = new RunCommand2(); break;
|
||||
case "tableresult": rv = new TableResultCommand2(); break;
|
||||
case "testcase": rv = new TestCaseCommand2(); break;
|
||||
default: rv = null; break;
|
||||
}
|
||||
if( null!=rv ) commandMap.put(name, rv);
|
||||
@ -187,11 +407,10 @@ class TestScript2 {
|
||||
return "["+(moduleName==null ? filename : moduleName)+"] line "+
|
||||
cur.lineNo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private TestScript2 verbose(Object... vals){
|
||||
private TestScript2 verboseN(int level, Object... vals){
|
||||
final int verbosity = outer.getVerbosity();
|
||||
if(verbosity>0){
|
||||
if(verbosity>=level){
|
||||
outer.out("VERBOSE",(verbosity>1 ? "+ " : " "),
|
||||
getOutputPrefix(),": ");
|
||||
outer.outln(vals);
|
||||
@ -199,6 +418,9 @@ class TestScript2 {
|
||||
return this;
|
||||
}
|
||||
|
||||
private TestScript2 verbose1(Object... vals){return verboseN(1,vals);}
|
||||
private TestScript2 verbose2(Object... vals){return verboseN(2,vals);}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public TestScript2 warn(Object... vals){
|
||||
outer.out("WARNING ", getOutputPrefix(),": ");
|
||||
@ -355,7 +577,7 @@ class TestScript2 {
|
||||
if(line.startsWith("#")){
|
||||
throw new IncompatibleDirective(this, "C-preprocessor input: "+line);
|
||||
}else if(line.startsWith("---")){
|
||||
new IncompatibleDirective(this, "Triple-dash: "+line);
|
||||
new IncompatibleDirective(this, "triple-dash: "+line);
|
||||
}
|
||||
Matcher m = patternScriptModuleName.matcher(line);
|
||||
if( m.find() ){
|
||||
@ -370,12 +592,19 @@ class TestScript2 {
|
||||
if( m.find() ){
|
||||
throw new IncompatibleDirective(this, m.group(1)+": "+m.group(3));
|
||||
}
|
||||
if( line.indexOf("\n|")>=0 ){
|
||||
throw new IncompatibleDirective(this, "newline-pipe combination.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public boolean isCommandLine(String line){
|
||||
public boolean isCommandLine(String line, boolean checkForImpl){
|
||||
final Matcher m = patternCommand.matcher(line);
|
||||
return m.find();
|
||||
boolean rc = m.find();
|
||||
if( rc && checkForImpl ){
|
||||
rc = null!=CommandDispatcher2.getCommandByName(m.group(2));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -388,33 +617,45 @@ class TestScript2 {
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches lines until the next command. Throws if
|
||||
Fetches lines until the next recognized command. Throws if
|
||||
checkForDirective() does. Returns null if there is no input or
|
||||
it's only whitespace. The returned string is trim()'d of
|
||||
leading/trailing whitespace.
|
||||
it's only whitespace. The returned string retains all whitespace.
|
||||
|
||||
Note that "subcommands", --command-like constructs in the body
|
||||
which do not match a known command name are considered to be
|
||||
content, not commands.
|
||||
*/
|
||||
public String fetchCommandBody(){
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while( (null != (line = peekLine())) ){
|
||||
checkForDirective(line);
|
||||
if( !isCommandLine(line) ){
|
||||
if( !isCommandLine(line, true) ){
|
||||
sb.append(line).append("\n");
|
||||
consumePeeked();
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = sb.toString().trim();
|
||||
return line.isEmpty() ? null : line;
|
||||
line = sb.toString();
|
||||
return line.trim().isEmpty() ? null : line;
|
||||
}
|
||||
|
||||
public void processCommand(SQLTester t, String[] argv) throws Exception{
|
||||
//verbose("got argv: ",argv[0], " ", Util.argvToString(argv));
|
||||
//verbose("Input buffer = ",t.getInputBuffer());
|
||||
verbose1("running command: ",argv[0], " ", Util.argvToString(argv));
|
||||
if(outer.getVerbosity()>1){
|
||||
final String input = t.getInputText();
|
||||
if( !input.isEmpty() ) verbose2("Input buffer = ",input);
|
||||
}
|
||||
CommandDispatcher2.dispatch(t, this, argv);
|
||||
}
|
||||
|
||||
public void toss(Object... msg) throws TestScript2Failed {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(Object s : msg) sb.append(s);
|
||||
throw new TestScript2Failed(this, sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
Runs this test script in the context of the given tester object.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
** This is a comment. There are many like it but this one is mine.
|
||||
**
|
||||
** SCRIPT_MODULE_NAME: sanity-check
|
||||
@ -8,14 +8,35 @@
|
||||
** REQUIRED_PROPERTIES:
|
||||
**
|
||||
*/
|
||||
|
||||
/*#if foo*/
|
||||
/*---foo*/
|
||||
/* --print without flags dumps current input buffer */
|
||||
--print
|
||||
|
||||
non-command/non-directive text after --print is also emitted.
|
||||
--print 🤩😃
|
||||
SELECT 1;
|
||||
SELECT 2;
|
||||
--print the end
|
||||
--close all
|
||||
--oom
|
||||
--db 0
|
||||
--new my.db
|
||||
--null zilch
|
||||
--testcase 1.0
|
||||
SELECT 1, null;
|
||||
--result 1 zilch
|
||||
--glob *zil*
|
||||
--notglob *ZIL*
|
||||
SELECT 1, 2;
|
||||
intentional error;
|
||||
--run
|
||||
--testcase json-1
|
||||
SELECT json_array(1,2,3)
|
||||
--json [1,2,3]
|
||||
--testcase tableresult-1
|
||||
select 1, 'a';
|
||||
select 2, 'b';
|
||||
--tableresult
|
||||
# [a-z]
|
||||
2 b
|
||||
--end
|
||||
--testcase json-block-1
|
||||
select json_array(1,2,3);
|
||||
select json_object('a',1,'b',2);
|
||||
--json-block
|
||||
[1,2,3]
|
||||
{"a":1,"b":2}
|
||||
--end
|
||||
--close
|
||||
--print 🤩😃 the end
|
||||
|
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Correct\sREQUIRED_PROPERTIES\shandling\sto\snot\sfail\sif\sthere\sare\sno\sproperties.
|
||||
D 2023-08-09T22:30:10.275
|
||||
C Port\sthe\sSQLTester\s'v1'\scommands\sto\sthe\s'v2'\sevaluation\sbits.\sStill\sTODO\sis\sswapping\sout\sv1\swith\sthese\sseparate\simpls.
|
||||
D 2023-08-09T23:47:14.521
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -266,11 +266,11 @@ F ext/jni/src/org/sqlite/jni/sqlite3_context.java d26573fc7b309228cb49786e907859
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
||||
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
||||
F ext/jni/src/org/sqlite/jni/tester/Outer.java b06acf9c79e8dbc8fea4a98b00724a6a76e3ee4503eb114671d2885f8fb3df8b
|
||||
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 2663dffe3977b73730ba3cbdd6dc0fe053699479759b75bb46c1f966773f0b76
|
||||
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 1ae38d872d2cb582e1a1abd67b5e9c276bf2f610cacc918428b63c668131642e
|
||||
F ext/jni/src/org/sqlite/jni/tester/TestScript.java 463021981a65ffe7147a1bfada557b275b0cba3c33176ac328502ff09d146f28
|
||||
F ext/jni/src/org/sqlite/jni/tester/TestScript2.java 3fc6700ab92e614f61856eeb87469589e57342cb66f5c4f9de425b45425f278f
|
||||
F ext/jni/src/org/sqlite/jni/tester/TestScript2.java 25895a534a1e4634268beecd1a689bdfc0aafbfe32071c27b5189ccb8aeec31e
|
||||
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md ab7169b08566a082ef55c9ef8a553827f99958ed3e076f31eef757563fae51ba
|
||||
F ext/jni/src/tests/000-000-sanity.test2 dca0364ca25dacdff38355870fee51be7112eade930b3597c808c2f88c44a782
|
||||
F ext/jni/src/tests/000-000-sanity.test2 dfbcccc7b3548ae56deb2ef8fe17dd9235a81fbd552536ef9202284549c7fcf3
|
||||
F ext/jni/src/tests/000_first.test cd5fb732520cf36d7a3e5ad94a274c7327a9504b01a1a7f98e1f946df6c539fd
|
||||
F ext/jni/src/tests/010_ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||
@ -2092,8 +2092,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 4fa2ad33edbcef393dd98dbf90586ad8f32ec0beab02f197c8038a44be86c314
|
||||
R c8b3185b3c963903b037db53ffaa5711
|
||||
P 7a19bef4f572a90fb7896b9360f9c72b052955ca9b0549be870b2b245c1f1b2b
|
||||
R eed3d04c8636ba991a620a2a8f5a013d
|
||||
U stephan
|
||||
Z f51d1e9a0eee42db59afa92b063b01d4
|
||||
Z bdeddd00da26b413ab473bf39ad731fc
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
7a19bef4f572a90fb7896b9360f9c72b052955ca9b0549be870b2b245c1f1b2b
|
||||
0cf57e5b0f90779e450e9db1ca009610df5e6f4487337d49017636bde3bb02d6
|
Loading…
Reference in New Issue
Block a user