# 2025-02-24 # # 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. # #*********************************************************************** # TESTRUNNER: shell # # Test cases for the command-line shell - focusing on .mode and # especially control-character escaping and the --escape option. # # set testdir [file dirname $argv0] source $testdir/tester.tcl set CLI [test_cli_invocation] do_execsql_test shellA-1.0 { CREATE TABLE t1(a INT, x TEXT); INSERT INTO t1 VALUES (1, 'line with '' single quote'), (2, concat(char(0x1b),'[31mVT-100 codes',char(0x1b),'[0m')), (3, NULL), (4, 1234), (5, 568.25), (6, unistr('new\u000aline')), (7, unistr('carriage\u000dreturn')), (8, 'last line'); } {} # Initial verification that the database created correctly # and that our calls to the CLI are working. # do_test_with_ansi_output shellA-1.2 { exec {*}$CLI test.db {.mode box --escape symbol} {SELECT * FROM t1;} } { ┌───┬──────────────────────────┐ │ a │ x │ ├───┼──────────────────────────┤ │ 1 │ line with ' single quote │ ├───┼──────────────────────────┤ │ 2 │ ␛[31mVT-100 codes␛[0m │ ├───┼──────────────────────────┤ │ 3 │ │ ├───┼──────────────────────────┤ │ 4 │ 1234 │ ├───┼──────────────────────────┤ │ 5 │ 568.25 │ ├───┼──────────────────────────┤ │ 6 │ new │ │ │ line │ ├───┼──────────────────────────┤ │ 7 │ carriage␍return │ ├───┼──────────────────────────┤ │ 8 │ last line │ └───┴──────────────────────────┘ } # ".mode list" # do_test shellA-1.3 { exec {*}$CLI test.db {SELECT x FROM t1 WHERE a=2;} } { ^[[31mVT-100 codes^[[0m } do_test_with_ansi_output shellA-1.4 { exec {*}$CLI test.db --escape symbol {SELECT x FROM t1 WHERE a=2;} } { ␛[31mVT-100 codes␛[0m } do_test shellA-1.5 { exec {*}$CLI test.db --escape ascii {SELECT x FROM t1 WHERE a=2;} } { ^[[31mVT-100 codes^[[0m } do_test_with_ansi_output shellA-1.6 { exec {*}$CLI test.db {.mode list --escape symbol} {SELECT x FROM t1 WHERE a=2;} } { ␛[31mVT-100 codes␛[0m } do_test shellA-1.7 { exec {*}$CLI test.db {.mode list --escape ascii} {SELECT x FROM t1 WHERE a=2;} } { ^[[31mVT-100 codes^[[0m } do_test shellA-1.8 { file delete -force out.txt exec {*}$CLI test.db {.mode list --escape off} {SELECT x FROM t1 WHERE a=7;} \ >out.txt set fd [open out.txt rb] set res [read $fd] close $fd string trim $res } "carriage\rreturn" do_test shellA-1.9 { set rc [catch { exec {*}$CLI test.db {.mode test --escape xyz} } msg] lappend rc $msg } {1 {unknown control character escape mode "xyz" - choices: ascii symbol off}} do_test shellA-1.10 { set rc [catch { exec {*}$CLI --escape abc test.db .q } msg] lappend rc $msg } {1 {unknown control character escape mode "abc" - choices: ascii symbol off}} # ".mode quote" # do_test shellA-2.1 { exec {*}$CLI test.db --quote {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { 1,'line with '' single quote' 2,unistr('\u001b[31mVT-100 codes\u001b[0m') 6,'new line' 7,unistr('carriage\u000dreturn') 8,'last line' } do_test shellA-2.2 { exec {*}$CLI test.db --quote {.mode} } {current output mode: quote --escape ascii} do_test shellA-2.3 { exec {*}$CLI test.db --quote --escape SYMBOL {.mode} } {current output mode: quote --escape symbol} do_test shellA-2.4 { exec {*}$CLI test.db --quote --escape OFF {.mode} } {current output mode: quote --escape off} # ".mode line" # do_test_with_ansi_output shellA-3.1 { exec {*}$CLI test.db --line --escape symbol \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { a = 1 x = line with ' single quote a = 2 x = ␛[31mVT-100 codes␛[0m a = 6 x = new line a = 7 x = carriage␍return a = 8 x = last line } do_test shellA-3.2 { exec {*}$CLI test.db --line --escape ascii \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { a = 1 x = line with ' single quote a = 2 x = ^[[31mVT-100 codes^[[0m a = 6 x = new line a = 7 x = carriage^Mreturn a = 8 x = last line } # ".mode box" # do_test_with_ansi_output shellA-4.1 { exec {*}$CLI test.db --box --escape ascii \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { ┌───┬──────────────────────────┐ │ a │ x │ ├───┼──────────────────────────┤ │ 1 │ line with ' single quote │ ├───┼──────────────────────────┤ │ 2 │ ^[[31mVT-100 codes^[[0m │ ├───┼──────────────────────────┤ │ 6 │ new │ │ │ line │ ├───┼──────────────────────────┤ │ 7 │ carriage^Mreturn │ ├───┼──────────────────────────┤ │ 8 │ last line │ └───┴──────────────────────────┘ } do_test_with_ansi_output shellA-4.2 { exec {*}$CLI test.db {.mode qbox} {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { ┌───┬───────────────────────────────────────────┐ │ a │ x │ ├───┼───────────────────────────────────────────┤ │ 1 │ 'line with '' single quote' │ ├───┼───────────────────────────────────────────┤ │ 2 │ unistr('\u001b[31mVT-100 codes\u001b[0m') │ ├───┼───────────────────────────────────────────┤ │ 6 │ 'new │ │ │ line' │ ├───┼───────────────────────────────────────────┤ │ 7 │ unistr('carriage\u000dreturn') │ ├───┼───────────────────────────────────────────┤ │ 8 │ 'last line' │ └───┴───────────────────────────────────────────┘ } # ".mode insert" # do_test shellA-5.1 { exec {*}$CLI test.db {.mode insert t1 --escape ascii} \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { INSERT INTO t1 VALUES(1,'line with '' single quote'); INSERT INTO t1 VALUES(2,unistr('\u001b[31mVT-100 codes\u001b[0m')); INSERT INTO t1 VALUES(6,unistr('new\u000aline')); INSERT INTO t1 VALUES(7,unistr('carriage\u000dreturn')); INSERT INTO t1 VALUES(8,'last line'); } do_test shellA-5.2 { exec {*}$CLI test.db {.mode insert t1 --escape symbol} \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { INSERT INTO t1 VALUES(1,'line with '' single quote'); INSERT INTO t1 VALUES(2,unistr('\u001b[31mVT-100 codes\u001b[0m')); INSERT INTO t1 VALUES(6,unistr('new\u000aline')); INSERT INTO t1 VALUES(7,unistr('carriage\u000dreturn')); INSERT INTO t1 VALUES(8,'last line'); } do_test shellA-5.3 { file delete -force out.txt exec {*}$CLI test.db {.mode insert t1 --escape off} \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} >out.txt set fd [open out.txt rb] set res [read $fd] close $fd string trim [string map [list \r\n \n] $res] } " INSERT INTO t1 VALUES(1,'line with '' single quote'); INSERT INTO t1 VALUES(2,'\033\13331mVT-100 codes\033\1330m'); INSERT INTO t1 VALUES(6,'new line'); INSERT INTO t1 VALUES(7,'carriage\rreturn'); INSERT INTO t1 VALUES(8,'last line'); " finish_test