From: stephan Date: Wed, 9 Aug 2023 13:51:50 +0000 (+0000) Subject: Add --json and --json-block SQLTester commands. X-Git-Tag: version-3.43.0~47^2~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5158a9a9a736750a80cc2c53c4b68c99e05b966e;p=thirdparty%2Fsqlite.git Add --json and --json-block SQLTester commands. FossilOrigin-Name: 478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5 --- diff --git a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java b/ext/jni/src/org/sqlite/jni/tester/SQLTester.java index e4d21f88d0..cd13206116 100644 --- a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java +++ b/ext/jni/src/org/sqlite/jni/tester/SQLTester.java @@ -521,7 +521,6 @@ class GlobCommand extends Command { public void process(SQLTester t, String[] argv, String content) throws Exception{ argcCheck(argv,1); affirmNoContent(content); - t.incrementTestCounter(); final String sql = t.takeInputBuffer(); //t.verbose(argv[0]," SQL =\n",sql); @@ -539,6 +538,16 @@ class GlobCommand extends Command { } } +//! --json command +class JsonCommand extends ResultCommand { + public JsonCommand(){ super(ResultBufferMode.ASIS); } +} + +//! --json-block command +class JsonBlockCommand extends TableResultCommand { + public JsonBlockCommand(){ super(true); } +} + //! --new command class NewDbCommand extends Command { public void process(SQLTester t, String[] argv, String content) throws Exception{ @@ -551,7 +560,7 @@ class NewDbCommand extends Command { } } -//! Placeholder dummy/no-op command +//! Placeholder dummy/no-op commands class NoopCommand extends Command { public void process(SQLTester t, String[] argv, String content) throws Exception{ } @@ -596,15 +605,18 @@ class PrintCommand extends Command { } } +//! --result command class ResultCommand extends Command { + private final ResultBufferMode bufferMode; + protected ResultCommand(ResultBufferMode bm){ bufferMode = bm; } + public ResultCommand(){ this(ResultBufferMode.ESCAPED); } public void process(SQLTester t, String[] argv, String content) throws Exception{ argcCheck(argv,0,-1); affirmNoContent(content); t.incrementTestCounter(); final String sql = t.takeInputBuffer(); //t.verbose(argv[0]," SQL =\n",sql); - int rc = t.execSql(null, true, ResultBufferMode.ESCAPED, - ResultRowMode.ONELINE, sql); + int rc = t.execSql(null, true, bufferMode, ResultRowMode.ONELINE, sql); final String result = t.getResultText().trim(); final String sArgs = argv.length>1 ? Util.argvToString(argv) : ""; //t.verbose(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs); @@ -614,6 +626,7 @@ class ResultCommand extends Command { } } +//! --run command class RunCommand extends Command { public void process(SQLTester t, String[] argv, String content) throws Exception{ argcCheck(argv,0,1); @@ -630,10 +643,15 @@ class RunCommand extends Command { } } +//! --tableresult command class TableResultCommand extends Command { + private final boolean jsonMode; + protected TableResultCommand(boolean jsonMode){ this.jsonMode = jsonMode; } + public TableResultCommand(){ this(false); } public void process(SQLTester t, String[] argv, String content) throws Exception{ argcCheck(argv,0); affirmHasContent(content); + t.incrementTestCounter(); if( !content.endsWith("\n--end") ){ Util.toss(TestFailure.class, argv[0], " must be terminated with --end."); }else{ @@ -642,7 +660,8 @@ class TableResultCommand extends Command { } final String[] globs = content.split("\s*\n\s*"); if( globs.length < 1 ){ - Util.toss(TestFailure.class, argv[0], " requires 1 or more globs."); + Util.toss(TestFailure.class, argv[0], " requires 1 or more ", + (jsonMode ? "json snippets" : "globs"),"."); } final String sql = t.takeInputBuffer(); t.execSql(null, true, ResultBufferMode.ESCAPED, ResultRowMode.NEWLINE, sql); @@ -654,14 +673,21 @@ class TableResultCommand extends Command { } for(int i = 0; i < res.length; ++i){ final String glob = GlobCommand.globToStrglob(globs[i]).replaceAll("\s+"," "); - if( 0 != sqlite3_strglob(glob, res[i]) ){ - Util.toss(TestFailure.class, argv[0], " glob {",glob, - "} does not match: {",res[i],"}"); + //t.verbose(argv[0]," <<",glob,">> vs <<",res[i],">>"); + if( jsonMode ){ + if( !glob.equals(res[i]) ){ + Util.toss(TestFailure.class, argv[0], " json <<",glob, + ">> does not match: <<",res[i],">>"); + } + }else if( 0 != sqlite3_strglob(glob, res[i]) ){ + Util.toss(TestFailure.class, argv[0], " glob <<",glob, + ">> does not match: <<",res[i],">>"); } } } } +//! --testcase command class TestCaseCommand extends Command { public void process(SQLTester t, String[] argv, String content) throws Exception{ argcCheck(argv,1); @@ -673,37 +699,48 @@ class TestCaseCommand extends Command { } } +/** + Helper for dispatching Command instances. +*/ class CommandDispatcher { private static java.util.Map commandMap = new java.util.HashMap<>(); + + /** + Returns a (cached) instance mapped to name, or null if no match + is found. + */ static Command getCommandByName(String name){ - // TODO? Do this dispatching using a custom annotation on - // Command impls. That requires a surprisingly huge amount - // of code, though. Command rv = commandMap.get(name); if( null!=rv ) return rv; switch(name){ - case "close": rv = new CloseDbCommand(); break; - case "db": rv = new DbCommand(); break; - case "glob": rv = new GlobCommand(); break; - case "new": rv = new NewDbCommand(); break; - case "notglob": rv = new NotGlobCommand(); break; - case "null": rv = new NullCommand(); break; - case "oom": rv = new NoopCommand(); break; - case "open": rv = new OpenDbCommand(); break; - case "print": rv = new PrintCommand(); break; - case "result": rv = new ResultCommand(); break; - case "run": rv = new RunCommand(); break; + case "close": rv = new CloseDbCommand(); break; + case "db": rv = new DbCommand(); break; + case "glob": rv = new GlobCommand(); break; + case "json": rv = new JsonCommand(); break; + case "json-block": rv = new JsonBlockCommand(); break; + case "new": rv = new NewDbCommand(); break; + case "notglob": rv = new NotGlobCommand(); break; + case "null": rv = new NullCommand(); break; + case "oom": rv = new NoopCommand(); break; + case "open": rv = new OpenDbCommand(); break; + case "print": rv = new PrintCommand(); break; + case "result": rv = new ResultCommand(); break; + case "run": rv = new RunCommand(); break; case "tableresult": rv = new TableResultCommand(); break; - case "testcase": rv = new TestCaseCommand(); break; + case "testcase": rv = new TestCaseCommand(); break; default: rv = null; break; } if( null!=rv ) commandMap.put(name, rv); return rv; } - @SuppressWarnings("unchecked") + /** + Treats argv[0] as a command name, looks it up with + getCommandByName(), and calls process() on that instance, passing + it arguments given to this function. + */ static void dispatch(SQLTester tester, String[] argv, String content) throws Exception{ final Command cmd = getCommandByName(argv[0]); if(null == cmd){ @@ -722,7 +759,12 @@ class CommandDispatcher { } } +/** + General utilities for the SQLTester bits. +*/ final class Util { + + //! Throws a new T, appending all msg args into a string for the message. public static void toss(Class errorType, Object... msg) throws Exception { StringBuilder sb = new StringBuilder(); for(Object s : msg) sb.append(s); @@ -739,6 +781,7 @@ final class Util { toss(IllegalArgumentException.class, msg); } + //! Tries to delete the given file, silently ignoring failure. public static void unlink(String filename){ try{ final java.io.File f = new java.io.File(filename); @@ -748,6 +791,11 @@ final class Util { } } + /** + Appends all entries in argv[1..end] into a space-separated + string, argv[0] is not included because it's expected to + be a command name. + */ public static String argvToString(String[] argv){ StringBuilder sb = new StringBuilder(); for(int i = 1; i < argv.length; ++i ){ diff --git a/ext/jni/src/tests/000_first.test b/ext/jni/src/tests/000_first.test index 742ebfa451..2f970b243d 100644 --- a/ext/jni/src/tests/000_first.test +++ b/ext/jni/src/tests/000_first.test @@ -12,8 +12,8 @@ junk --new SQLTester.db --null zilch --run -select 1; -select 2; + SELECT 1; + SELECT 2; -- comment -- uncomment to introduce intentional syntax error --oom @@ -22,24 +22,34 @@ This is from the print command's body. --print Also from the print command. --- also ignored ---testcase first -select 'a', 'b'; -select 'a', 'b'; +--testcase 1 + SELECT 'a', 'b'; + SELECT 'a', 'b'; --result a b a b ---testcase second -select 123 +--testcase 2 + SELECT 123 --glob ### ---testcase third -select 'a' +--testcase 3 + SELECT 'a' --notglob # --close --open SQLTester.db --print Re-opened db. --testcase fourth -SELECT 1, 2; -SELECT 'b', 'c'; + SELECT 1, 2; + SELECT 'b', 'c'; --tableresult [0-9] # b c --end +--testcase json-array-1 +SELECT json_array(1,2,3) +--json [1,2,3] +--testcase json-array-2 + SELECT json_array(1,2,3); + SELECT json_object('a',1,'b',2); +--json-block +[1,2,3] +{"a":1,"b":2} +--end --an-uknown-command diff --git a/manifest b/manifest index 7f72a5fc63..aacd223c2e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sSQLTester\s--tableresult\scommand. -D 2023-08-09T13:16:10.208 +C Add\s--json\sand\s--json-block\sSQLTester\scommands. +D 2023-08-09T13:51:50.893 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -266,10 +266,10 @@ 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 3d9c40f8ed58ec0df05ca160986ea06ec84ec1f338b069cfba9604bbba467a01 -F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 59ac50bbc1abc37b34bc4cd47b564d770de2828e045ba59c056f873543de10b3 +F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 41f48e3d4834e08bf35e21f8c62b8350c61161aafb498e4961c642194c06a29d F ext/jni/src/org/sqlite/jni/tester/TestScript.java f2a87c88ab23fa4601a985eb69bdc8b4f81cabfab04fdc3544ecefde207e08d4 F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md ae1d6706f723517e03a04ab578a539fa3df66fe38adad113f10b61eabc524d09 -F ext/jni/src/tests/000_first.test 461f465cd1e9c60f19a8fd4231721c1bbd01702d9677696d56087a58f9d2e09e +F ext/jni/src/tests/000_first.test ea6ac62e13a3787f3f6d402fa5e9c7a7e85b43ec11ce10e260d673be7ecc537b F ext/jni/src/tests/010_ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70 F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 @@ -2090,8 +2090,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 5323e4fd254274cc527af7536c622b786394599c68eca2da6c7fc641727dbdb2 -R c0ec1fc5e7c5611a47b223974ef77855 +P 8c5b6d893df4a4e82c6d8e07507fc160b11412ede4bb903ff4e3f5ffa59a9cb9 +R 90d3df2a48743fa4d0421d9f7ba4a451 U stephan -Z 3ccc1c720ec01884cd7c12ccaa2f6b70 +Z 0acfbb2c69aeffb3bdb56736e07c0e08 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 44b47e7b2a..78d0e64d71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c5b6d893df4a4e82c6d8e07507fc160b11412ede4bb903ff4e3f5ffa59a9cb9 \ No newline at end of file +478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5 \ No newline at end of file