]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add --json and --json-block SQLTester commands.
authorstephan <stephan@noemail.net>
Wed, 9 Aug 2023 13:51:50 +0000 (13:51 +0000)
committerstephan <stephan@noemail.net>
Wed, 9 Aug 2023 13:51:50 +0000 (13:51 +0000)
FossilOrigin-Name: 478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5

ext/jni/src/org/sqlite/jni/tester/SQLTester.java
ext/jni/src/tests/000_first.test
manifest
manifest.uuid

index e4d21f88d0137a06b87318ac248b8c9969760170..cd132061162b2f853b836cba6faebd95e2f7936c 100644 (file)
@@ -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<String,Command> 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<? extends Exception> 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 ){
index 742ebfa4518394742b54744f7dbb2a61a45de90b..2f970b243d5316476b5da517eee7647853cae49c 100644 (file)
@@ -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
index 7f72a5fc63ba0ad34865028e25674d47fc5a3cbe..aacd223c2eaf160b4efa9c257f75e02497a358b0 100644 (file)
--- 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.
index 44b47e7b2a1f30c75a789b2ec19b6f30f84e6a14..78d0e64d710731915e08a57fd5420e1c122ab14a 100644 (file)
@@ -1 +1 @@
-8c5b6d893df4a4e82c6d8e07507fc160b11412ede4bb903ff4e3f5ffa59a9cb9
\ No newline at end of file
+478129d901824e675d86494044f73c313532e9f80e7ee6f425474df8237a82f5
\ No newline at end of file