]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
For sqlite3x, rudimentary testing in place as make target shellxtest . More to come.
authorlarrybr <larrybr@noemail.net>
Sun, 17 Apr 2022 00:48:49 +0000 (00:48 +0000)
committerlarrybr <larrybr@noemail.net>
Sun, 17 Apr 2022 00:48:49 +0000 (00:48 +0000)
FossilOrigin-Name: b73928befb013622a369bf8f9904b5aeca626a5598884b4030229a33f684960f

ext/misc/tclshext.c.in
manifest
manifest.uuid
src/shell.c.in
src/test_shellext_c.c
src/test_shellext_cpp.cpp
test/shell_x/shell10.test [new file with mode: 0644]
test/shell_x/shell9.test

index 37ff3486d62c1a0deba7e0b1acd1a698497b9fbe..227ed247e10b42b1b916a75204ebcd132239b2f3 100644 (file)
@@ -1219,7 +1219,7 @@ int sqlite3_tclshext_init(
          * to leave Tk objects and variables set so that when a GUI event
          * loop is run, some useful GUI program runs and can terminate.
          *
-         * Before running the setup code, a variable, ::isHost, is set 
+         * Before running the setup code, a variable, ::isHost, is set
          * true to possibly inform the setup code that it should avoid
          * exit and exec calls. Setup code which is designed for either
          * hosted or standalone use, when run with $::isHost!=0, may opt
index 6c123237a47a7abbde929bfc2eb7f1725a908e9f..e2bdb37c0281488b378917cbc769c6f5e1b3fc53 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Get\ssqlite3x\sand\sextensions\stesting\sfrom\sMakefile\ssetup,\sand\ssome\sof\swapptest\schanges\sdone\sto\srun\ssame.\s(a\sWIP)
-D 2022-04-15T21:21:01.750
+C For\ssqlite3x,\srudimentary\stesting\sin\splace\sas\smake\starget\sshellxtest\s.\sMore\sto\scome.
+D 2022-04-17T00:48:49.519
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -330,7 +330,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
 F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6
 F ext/misc/stmt.c 35063044a388ead95557e4b84b89c1b93accc2f1c6ddea3f9710e8486a7af94a
-F ext/misc/tclshext.c.in 93228dbc48e6b300aa3d8632d2a061edaafcab60a83664ae7549e5e682e3b48b
+F ext/misc/tclshext.c.in e0e4387b95410172385488feaea2f622ad1d398f1ac6a4275874791fbfd31d4e
 F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
 F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
 F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
@@ -557,7 +557,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3
-F src/shell.c.in da1afe360a268736d373218fabfce706558628ba49655855bdcb759be963880e
+F src/shell.c.in 47c84d1511e44ef28fb215c70a80065c6c103650579743ac60a129f541af17b2
 F src/shext_linkage.h 41e7e665fffd125b38b8211dc650233d4fe54941acd8177f23d3deb9d6f70154
 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -607,8 +607,8 @@ F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
 F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b
 F src/test_schema.c f5d6067dfc2f2845c4dd56df63e66ee826fb23877855c785f75cc2ca83fd0c1b
 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
-F src/test_shellext_c.c e0cd6bf508d4d5c7147766d58b926bf36d49265654896ab91b1abad0aa8d7656 w src/test_shellext.c
-F src/test_shellext_cpp.cpp ae20a1d280311348910ac8c6b2dce7ddc36b38c82ff13929434eb98114696342 w src/test_shellext.cpp
+F src/test_shellext_c.c b611e468bb99ba27df9211f8b6f1179cbd77f29390a0c7b846eb0d00e14dd1dc
+F src/test_shellext_cpp.cpp d33cc8538ebe76f10114c8c9e5d65caa4e183fb461a4311145739f0affb15566
 F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a
 F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
 F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939
@@ -1404,7 +1404,8 @@ F test/shell5.test 39d2cffb3c1c67456b2c42eb5e46bec1e3780c68a6d71bb156e012d3f5373
 F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
 F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae
-F test/shell_x/shell9.test c3e5aefa4cc6088efe9034b22ed33157e18653d599cb109f254904a7344cd230 w test/shell9.test
+F test/shell_x/shell10.test 9b396b83c3b150ffb4c3bca62600f28ed91d0e31a4f82d4de482e20f3b84570a
+F test/shell_x/shell9.test 22f15500ccdec5561cbedb3a4c28f0f2175a2b8eff1b837cc127de59c3bc0f73
 F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
@@ -1953,8 +1954,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P f78d7b8b89b667daba486fdb67de105bd8524203cc44bb02c3cb94acd85560e9
-R 1ba3c589060988b7f35661d48f220afd
+P d238fcf4beb0b121e4754e288df9906cb61d38a827f1fe38cf4aaa784520fc08
+Q +82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf
+R ef5b2dbf2d2afa126edf6b3816e08feb
 U larrybr
-Z 85689539bcda51dbf9a7b11c35f28148
+Z a3ff9fe808da85c8206c0da625259951
 # Remove this line to create a well-formed Fossil manifest.
index c17ba602cb05f5f2f5946d772f77ae70a732483e..9d45e0f0511c4cb20f9ba749e0fe7134d17d4a91 100644 (file)
@@ -1 +1 @@
-d238fcf4beb0b121e4754e288df9906cb61d38a827f1fe38cf4aaa784520fc08
\ No newline at end of file
+b73928befb013622a369bf8f9904b5aeca626a5598884b4030229a33f684960f
\ No newline at end of file
index 665d3951e12a4a2f947694161f26d076e8f2544a..5da38e325ef81a07cab2c9a94153079986b5943f 100644 (file)
@@ -7798,6 +7798,13 @@ UPDATE ColNames AS t SET reps=\
   static const char * const zColDigits = "\
 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
 ";
+#else
+  /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */
+  static const char * const zColDigits = "\
+SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \
+ WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \
+ ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \
+";
 #endif
   static const char * const zRenameRank =
 #ifdef SHELL_COLUMN_RENAME_CLEAN
@@ -7883,11 +7890,7 @@ FROM (\
     /* Formulate the columns spec, close the DB, zero *pDb. */
     char *zColsSpec = 0;
     int hasDupes = db_int(*pDb, zHasDupes);
-#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
     int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
-#else
-# define nDigits 2
-#endif
     if( hasDupes ){
 #ifdef SHELL_COLUMN_RENAME_CLEAN
       rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
index 7dd0cbaa1d8591689b7997a9b5cb4f72a4735b34..6eab72d8ea7d6d3bb6dc40b0b7ca3e0c4b8a275e 100644 (file)
@@ -31,7 +31,7 @@ static void sayHowMany( BatBeing *pbb, FILE *out, ShellExState *psx );
  * The function bodies are not so easily written, of course. */
 
 DERIVED_METHOD(void, destruct, DotCommand,BatBeing, 0, ()){
-  fprintf(stderr, "BatBeing unbecoming.\n");
+  fprintf(stdout, "BatBeing unbecoming.\n");
 }
 
 DERIVED_METHOD(const char *, name, DotCommand,BatBeing, 0,()){
@@ -52,16 +52,7 @@ DERIVED_METHOD(DotCmdRC, argsCheck, DotCommand,BatBeing, 3,
 }
 
 DERIVED_METHOD(DotCmdRC, execute, DotCommand,BatBeing, 4,
-             (ShellExState *psx, char **pzErrMsg, int nArgs, char *azArgs[])){
-  FILE *out = pExtHelpers->currentOutputFile(psx);
-  switch( nArgs ){
-  default: fprintf(out, "The Penguin, Joker and Riddler have teamed up!\n");
-  case 2: fprintf(out, "The Dynamic Duo arrives, and ... ");
-  case 1: fprintf(out, "@#$ KaPow! $#@\n");
-  }
-  sayHowMany((BatBeing *)pThis, out, psx);
-  return DCR_Ok;
-}
+           (ShellExState *psx, char **pzErrMsg, int nArgs, char *azArgs[]));
 
 /* Define a DotCommand v-table initialized to reference above methods. */
 DotCommand_IMPLEMENT_VTABLE(BatBeing, batty_methods);
@@ -73,18 +64,52 @@ DotCommand_IMPLEMENT_VTABLE(BatBeing, batty_methods);
 INSTANCE_BEGIN(BatBeing);
   int numCalls;
   DotCommand * pPrint;
+  DotCommand * pPrior;
 INSTANCE_END(BatBeing) batty = {
   &batty_methods,
-  0, 0
+  0, 0, 0
 };
 
+DERIVED_METHOD(DotCmdRC, execute, DotCommand,BatBeing, 4,
+             (ShellExState *psx, char **pzErrMsg, int nArgs, char *azArgs[])){
+  FILE *out = pExtHelpers->currentOutputFile(psx);
+  BatBeing *pbb = (BatBeing*)pThis;
+  switch( nArgs ){
+  default:
+    {
+      if( pbb->pPrior ){
+        char *az1 = azArgs[1];
+        for( int i=2; i<nArgs; ++i ) azArgs[i-1] = azArgs[i];
+        azArgs[nArgs-1] = az1;
+        return pbb->pPrior->pMethods->execute(pbb->pPrior, psx,
+                                              pzErrMsg, nArgs, azArgs);
+      }else{
+        int cix;
+        SHX_HELPER(setColumnWidths)(psx, azArgs+1, nArgs-1);
+        fprintf(out, "Column widths:");
+        for( cix=0; cix<psx->numWidths; ++cix ){
+          fprintf(out, " %d", psx->pSpecWidths[cix]);
+        }
+        fprintf(out, "\n");
+      }
+    }
+    break;
+  case 3:
+    fprintf(out, "The Penguin, Joker and Riddler have teamed up!\n");
+  case 2: fprintf(out, "The Dynamic Duo arrives, and ... ");
+  case 1: fprintf(out, "@#$ KaPow! $#@\n");
+  }
+  sayHowMany((BatBeing *)pThis, out, psx);
+  return DCR_Ok;
+}
+
 static void sayHowMany( BatBeing *pbb, FILE *out, ShellExState *psx ){
   if( pbb->pPrint ){
     char *az[] = { "print", 0 };
     char *zErr = 0;
     DotCommand * pdcPrint = pbb->pPrint;
     DotCmdRC rc;
-    az[1] = sqlite3_mprintf("This execute has been called %d times.\n",
+    az[1] = sqlite3_mprintf("This execute has been called %d times.",
                             ++pbb->numCalls);
     rc = pdcPrint->pMethods->execute(pdcPrint, psx, &zErr, 2, az);
     sqlite3_free(az[1]);
@@ -105,10 +130,13 @@ static int shellEventHandle(void *pv, NoticeKind nk,
     fprintf(out, "BatBeing incommunicado.\n");
   }else if( nk==NK_DbUserAppeared || nk==NK_DbUserVanishing ){
     const char *zWhat = (nk==NK_DbUserAppeared)? "appeared" : "vanishing";
-    fprintf(out, "dbUser(%p) %s\n", pvSubject, zWhat);
+    int isDbu = pvSubject==psx->dbUser;
+    fprintf(out, "db%s %s\n", isDbu? "User" : "?", zWhat);
     if( psx->dbUser != pvSubject ) fprintf(out, "not dbx(%p)\n", psx->dbUser);
   }else if( nk==NK_DbAboutToClose ){
-    fprintf(out, "db(%p) closing\n", pvSubject);
+    const char *zdb = (pvSubject==psx->dbUser)? "User"
+      : (pvSubject==psx->dbShell)? "Shell" : "?";
+    fprintf(out, "db%s closing\n", zdb);
   }
   return 0;
 }
@@ -119,7 +147,7 @@ static int shellEventHandle(void *pv, NoticeKind nk,
 #ifdef _WIN32
 __declspec(dllexport)
 #endif
-int sqlite3_testshellext_c_init(
+int sqlite3_testshellextc_init(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -138,13 +166,22 @@ int sqlite3_testshellext_c_init(
     ShellExState *psx = pShExtLink->pSXS;
     DotCommand *pdc = (DotCommand *)&batty;
     int rc;
+    char *zLoadArgs = sqlite3_mprintf("Load arguments:");
+    int ila;
 
-    SHX_API(subscribeEvents)(psx, sqlite3_testshellext_c_init, &batty,
+    for( ila=0; ila<pShExtLink->nLoadArgs; ++ila ){
+      zLoadArgs = sqlite3_mprintf("%z %s", zLoadArgs,
+                                  pShExtLink->azLoadArgs[ila]);
+    }
+    if( ila ) fprintf(SHX_HELPER(currentOutputFile)(psx), "%s\n", zLoadArgs);
+    sqlite3_free(zLoadArgs);
+    SHX_API(subscribeEvents)(psx, sqlite3_testshellextc_init, &batty,
                              NK_CountOf, shellEventHandle);
     batty.pPrint = SHX_HELPER(findDotCommand)("print", psx, &rc);
-    rc = SHX_API(registerDotCommand)(psx, sqlite3_testshellext_c_init, pdc);
+    batty.pPrior = SHX_HELPER(findDotCommand)("bat_being", psx, &rc);
+    rc = SHX_API(registerDotCommand)(psx, sqlite3_testshellextc_init, pdc);
     if( rc!=0 ) ++nErr;
-    pShExtLink->eid = sqlite3_testshellext_c_init;
+    pShExtLink->eid = sqlite3_testshellextc_init;
   }
   return nErr ? SQLITE_ERROR : SQLITE_OK;
 }
index c7102c6f2428b542ffd96d3595d453344ee6cb50..6b203b0b221f3d232011ef9c7dc0967157cb68b4 100644 (file)
@@ -25,9 +25,13 @@ SHELL_EXTENSION_INIT1(pShExtApi, pExtHelpers, shextLinkFetcher);
 
 struct BatBeing : DotCommand {
 
-  ~BatBeing() {}; // No held resources; copy/assign is fine and dying is easy.
+  ~BatBeing() {
+    fprintf(stdout, "BatBeing RIP.\n");
+  }; // No held resources; copy/assign is fine and dying is easy.
 
-  void destruct() { this->~BatBeing(); }
+  void destruct() {
+    fprintf(stdout, "BatBeing unbecoming.\n");
+  }
 
   const char *name() { return "bat_being"; };
 
@@ -48,12 +52,15 @@ struct BatBeing : DotCommand {
   BatBeing(DotCommand *pp = 0) {
     numCalls = 0;
     pPrint = pp;
+    pPrior = 0;
+    fprintf(stdout, "BatBeing lives.\n");
   };
 
   // Default copy/assign are fine; nothing held.
 
   int numCalls;
   DotCommand * pPrint;
+  DotCommand * pPrior;
 };
 
 static void sayHowMany( BatBeing *pbb, FILE *out, ShellExState *psx ){
@@ -62,7 +69,7 @@ static void sayHowMany( BatBeing *pbb, FILE *out, ShellExState *psx ){
     char *az[] = { cmd, 0 };
     char *zErr = 0;
     DotCmdRC rc;
-    az[1] = sqlite3_mprintf("This execute has been called %d times.\n",
+    az[1] = sqlite3_mprintf("This execute has been called %d times.",
                             ++pbb->numCalls);
     rc = pbb->pPrint->execute(psx, &zErr, 2, az);
     sqlite3_free(az[1]);
@@ -76,7 +83,25 @@ DotCmdRC BatBeing::execute(ShellExState *psx, char **pzErrMsg,
                            int nArgs, char *azArgs[]) {
   FILE *out = SHX_HELPER(currentOutputFile)(psx);
   switch( nArgs ){
-  default: fprintf(out, "The Penguin, Joker and Riddler have teamed up!\n");
+  default:
+    {
+      if( pPrior ){
+        char *az1 = azArgs[1];
+        for( int i=2; i<nArgs; ++i ) azArgs[i-1] = azArgs[i];
+        azArgs[nArgs-1] = az1;
+        return pPrior->execute(psx, pzErrMsg, nArgs, azArgs);
+      }else{
+        SHX_HELPER(setColumnWidths)(psx, azArgs+1, nArgs-1);
+        fprintf(out, "Column widths:");
+        for( int cix=0; cix<psx->numWidths; ++cix ){
+          fprintf(out, " %d", psx->pSpecWidths[cix]);
+        }
+        fprintf(out, "\n");
+      }
+    }
+    break;
+  case 3:
+    fprintf(out, "The Penguin, Joker and Riddler have teamed up!\n");
   case 2: fprintf(out, "The Dynamic Duo arrives, and ... ");
   case 1: fprintf(out, "@#$ KaPow! $#@\n");
   }
@@ -84,7 +109,7 @@ DotCmdRC BatBeing::execute(ShellExState *psx, char **pzErrMsg,
   return DCR_Ok;
 }
 
-/* Define/initialize BatBeing as a DotCommand subclass using above v-table. 
+/* Define/initialize BatBeing as a DotCommand subclass using above v-table.
  * This compiles in a type-safe manner because the batty_methods v-table
  * and methods it incorporates strictly match the DotCommand interface.
  */
@@ -101,10 +126,13 @@ static int shellEventHandle(void *pv, NoticeKind nk,
     fprintf(out, "BatBeing incommunicado.\n");
   }else if( nk==NK_DbUserAppeared || nk==NK_DbUserVanishing ){
     const char *zWhat = (nk==NK_DbUserAppeared)? "appeared" : "vanishing";
-    fprintf(out, "dbUser(%p) %s\n", pvSubject, zWhat);
+    int isDbu = pvSubject==psx->dbUser;
+    fprintf(out, "db%s %s\n", isDbu? "User" : "?", zWhat);
     if( psx->dbUser != pvSubject ) fprintf(out, "not dbx(%p)\n", psx->dbUser);
   }else if( nk==NK_DbAboutToClose ){
-    fprintf(out, "db(%p) closing\n", pvSubject);
+    const char *zdb = (pvSubject==psx->dbUser)? "User"
+      : (pvSubject==psx->dbShell)? "Shell" : "?";
+    fprintf(out, "db%s closing\n", zdb);
   }
   return 0;
 }
@@ -116,7 +144,7 @@ extern "C"
 #ifdef _WIN32
 __declspec(dllexport)
 #endif
-int sqlite3_testshellext_cpp_init(
+int sqlite3_testshellextcpp_init(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -134,14 +162,23 @@ int sqlite3_testshellext_cpp_init(
   }else{
     ShellExState *psx = pShExtLink->pSXS;
     int rc;
+    char *zLoadArgs = sqlite3_mprintf("Load arguments:");
+    int ila;
 
-    SHX_API(subscribeEvents)(psx, sqlite3_testshellext_cpp_init, &batty,
+    for( ila=0; ila<pShExtLink->nLoadArgs; ++ila ){
+      zLoadArgs = sqlite3_mprintf("%z %s", zLoadArgs,
+                                  pShExtLink->azLoadArgs[ila]);
+    }
+    if( ila ) fprintf(SHX_HELPER(currentOutputFile)(psx), "%s\n", zLoadArgs);
+    sqlite3_free(zLoadArgs);
+    SHX_API(subscribeEvents)(psx, sqlite3_testshellextcpp_init, &batty,
                              NK_CountOf, shellEventHandle);
     batty.pPrint = SHX_HELPER(findDotCommand)("print", psx, &rc);
+    batty.pPrior = SHX_HELPER(findDotCommand)(batty.name(), psx, &rc);
     rc = SHX_API(registerDotCommand)(psx,
-                                     sqlite3_testshellext_cpp_init, &batty);
+                                     sqlite3_testshellextcpp_init, &batty);
     if( rc!=0 ) ++nErr;
-    pShExtLink->eid = sqlite3_testshellext_cpp_init;
+    pShExtLink->eid = sqlite3_testshellextcpp_init;
   }
   return nErr ? SQLITE_ERROR : SQLITE_OK;
 }
diff --git a/test/shell_x/shell10.test b/test/shell_x/shell10.test
new file mode 100644 (file)
index 0000000..d904721
--- /dev/null
@@ -0,0 +1,126 @@
+# 2022 Apr 16
+#
+# 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.
+#
+#***********************************************************************
+#
+# The focus of this file is testing the extensible CLI shell tool's
+# feature whereby shell extensions may be loaded and used, particularly
+# the Tcl extension.
+#
+
+# Test plan:
+#
+#   shell10-1.*: loading/running the {C,C++}-written test extensions
+#   shell10-2.*: Tcl extension load and execution environment switching
+#   shell10-3.*: Tcl extension ad hoc command creation
+
+set testdir [file join [file dirname $argv0] ..]
+source [file join $testdir tester.tcl]
+set CLI [test_find_cli sqlite3x]
+set blddir [file normalize [file join $testdir ..]]
+
+db close
+forcedelete test.db test.db-journal test.db-wal
+forcedelete x.db xn.db
+
+sqlite3 db test.db
+set mdb ":memory:"
+
+proc catch_mdb_cmd {args} {
+  global CLI
+  set cmd [join $args "\n"]
+  set rc [catch { exec $CLI :memory: << $cmd } msg]
+  list $rc $msg
+}
+
+#----------------------------------------------------------------------------
+# Test cases shell10-1.*: loading/running the {C,C++}-written test extensions
+set cmds ".
+ .load $blddir/test_shellext_cpp -shext C++
+"
+do_test shell10-1.1 {
+  catch_mdb_cmd $cmds
+} {0 {BatBeing lives.
+Load arguments: C++
+dbUser closing
+dbShell closing
+BatBeing incommunicado.
+BatBeing unbecoming.
+BatBeing RIP.}}
+
+set cmds ".
+ .load $blddir/test_shellext_c -shext C
+ .bat 10 20 30
+ .load $blddir/test_shellext_cpp -shext C++
+ .bat 10 20 30
+"
+do_test shell10-1.2 {
+  catch_mdb_cmd $cmds
+} {0 {Load arguments: C
+Column widths: 10 20 30
+This execute has been called 1 times.
+BatBeing lives.
+Load arguments: C++
+Column widths: 20 30 10
+This execute has been called 2 times.
+dbUser closing
+dbUser closing
+dbShell closing
+dbShell closing
+BatBeing incommunicado.
+BatBeing incommunicado.
+BatBeing unbecoming.
+BatBeing unbecoming.
+BatBeing RIP.}}
+
+
+#----------------------------------------------------------------------------
+# Test cases shell10-2.*: Tcl extension load and execution environment switching
+
+set ldtce ".load $blddir/tclshext -shext"
+
+set cmds {
+ ..
+ puts Putsing
+ for {set i 0} {$i<2} {incr i} {.print $i}
+ puts [info commands ..]
+ .
+ .print Printing
+ .quit
+}
+do_test shell10-2.1 {
+  catch_mdb_cmd $ldtce $cmds
+} {0 {Putsing
+..
+0
+1
+Printing}}
+
+#----------------------------------------------------------------------------
+# Test cases shell10-3.*: Tcl extension ad hoc command creation
+
+set cmds {
+ ..
+ proc .sum {args} {
+   set sum 0
+   foreach addend $args {incr sum $addend}
+   .print $sum
+ }
+ register_adhoc_command sum ".sum   Sums arguments and prints result.
+   Arguments must be integers."
+ .
+ .help sum
+ .sum 1 2 3 4 5
+ .quit
+}
+do_test shell10-3.1 {
+  catch_mdb_cmd $ldtce $cmds
+} {0 {.sum   Sums arguments and prints result.
+   Arguments must be integers.
+15}}
index e413c3d613b4a0a7371e3b6edb0b87710c0857b1..3089ad98b5cd14f415a905c31dbda608f046324a 100644 (file)
@@ -10,7 +10,7 @@
 #***********************************************************************
 #
 # The focus of this file is testing the CLI shell tool enhanced parsing,
-# new .parameter subcommands and uses, and the new .x meta-command.
+# .parameter and .vars subcommands and uses, and the .x command.
 #
 #