| # 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 |