# 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 -noinit test.db {.mode box -quote off --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 -noinit -list test.db {SELECT x FROM t1 WHERE a=2;}
} {
^[[31mVT-100 codes^[[0m
}
do_test_with_ansi_output shellA-1.4 {
  exec {*}$CLI -noinit -list test.db --escape symbol {SELECT x FROM t1 WHERE a=2;}
} {
␛[31mVT-100 codes␛[0m
}
do_test shellA-1.5 {
  exec {*}$CLI -noinit -list 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 -noinit test.db {.mode list --escape symbol} {SELECT x FROM t1 WHERE a=2;}
} {
␛[31mVT-100 codes␛[0m
}
do_test shellA-1.7 {
  exec {*}$CLI -noinit 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 -noinit 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 -noinit test.db {.mode test --escape xyz}
  } msg]
  lappend rc $msg
} {1 {argv[3]: .mode test --escape xyz
argv[3]:       ^--- unknown mode
argv[3]: Use ".help .mode" for more info}}
do_test shellA-1.10 {
  set rc [catch {
     exec {*}$CLI --noinit --escape abc test.db .q
  } msg]
  lappend rc $msg
} {1 {unknown control character escape mode "abc" - choices: auto off ascii symbol}}

# ".mode quote"
#
do_test shellA-2.1 {
 exec {*}$CLI -noinit 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,unistr('new\u000aline')
7,unistr('carriage\u000dreturn')
8,'last line'
}
do_test shellA-2.2 {
  exec {*}$CLI -noinit test.db --quote {.mode -v}
} {/*.mode quote* --escape auto*/}
do_test shellA-2.3 {
  exec {*}$CLI -noinit test.db --quote --escape SYMBOL {.mode}
} {.mode quote --escape symbol}
do_test shellA-2.4 {
  exec {*}$CLI -noinit test.db --quote --escape OFF {.mode}
} {.mode quote --escape off}


# ".mode line"
#
do_test_with_ansi_output shellA-3.1 {
 exec {*}$CLI -noinit 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 -noinit 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 -noinit 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.1b {
 exec {*}$CLI -noinit test.db --box --escape ascii \
    {.mode -border off} \
    {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 -noinit 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 │ unistr('new\u000aline')                   │
│ 7 │ unistr('carriage\u000dreturn')            │
│ 8 │ 'last line'                               │
╰───┴───────────────────────────────────────────╯
}
do_test_with_ansi_output shellA-4.2b {
 exec {*}$CLI -noinit test.db {.mode qbox -border off} \
    {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 │ unistr('new\u000aline')
 7 │ unistr('carriage\u000dreturn')
 8 │ 'last line'
}

# ".mode insert"
#
do_test shellA-5.1 {
 exec {*}$CLI -noinit 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 -noinit 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 -noinit 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');
"

# ".mode split"
#
do_test shellA-6.1 {
  db eval {
    CREATE TABLE t2(x);
    INSERT INTO t2(x) VALUES
      ('one'), ('two'), ('three'), ('four'), ('five'),
      ('six'), ('seven'), ('eight'), ('nine'), ('ten'),
      ('eleven'), ('twelve'), ('thirteen'), ('fourteen');
  }
  exec {*}$CLI -noinit test.db \
      {.print} \
      {.mode split -screenwidth 30} \
      {SELECT x FROM t2}
} {
one    five   nine    thirteen
two    six    ten     fourteen
three  seven  eleven
four   eight  twelve}
# 3456789 123456789 123456789

do_test shellA-6.2 {
  exec {*}$CLI -noinit test.db \
      {.print} \
      {.mode split -screenwidth 30} \
      {SELECT x FROM t2} \
      {.mode column -titles off} \
      {SELECT x FROM t2}
} {
one    five   nine    thirteen
two    six    ten     fourteen
three  seven  eleven
four   eight  twelve
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen}

do_test shellA-6.3 {
  exec {*}$CLI -noinit test.db \
      {.print} \
      {.mode table} \
      {.mode --once split -screenwidth 30} \
      {SELECT x FROM t2} \
      {SELECT x FROM t2}
} {
one    five   nine    thirteen
two    six    ten     fourteen
three  seven  eleven
four   eight  twelve
+----------+
|    x     |
+----------+
| one      |
| two      |
| three    |
| four     |
| five     |
| six      |
| seven    |
| eight    |
| nine     |
| ten      |
| eleven   |
| twelve   |
| thirteen |
| fourteen |
+----------+}

finish_test
