# file      : tests/test/script/runner/set.testscript
# license   : MIT; see accompanying LICENSE file

.include ../common.testscript

: special
:
{
  : pipelining
  :
  $c <'set foo | cat >bar' && $b 2>>EOE != 0
  testscript:1:1: error: set builtin must be the last pipe command
    info: test id: 1
  EOE

  : redirecting
  :
  {
    : stdout
    :
    $c <'set foo >bar' && $b 2>>EOE != 0
    testscript:1:1: error: set builtin stdout cannot be redirected
      info: test id: 1
    EOE

    : stderr
    :
    $c <'set foo 2>bar' && $b 2>>EOE != 0
    testscript:1:1: error: set builtin stderr cannot be redirected
      info: test id: 1
    EOE
  }

  : status
  :
  $c <'set foo == 1' && $b 2>>EOE != 0
  testscript:1:1: error: set builtin exit code cannot be checked
    info: test id: 1
  EOE
}

: options
:
{
  : unknown
  :
  $c <'set -u' && $b 2>>EOE != 0
  testscript:1:1: error: set: unknown option '-u'
    info: test id: 1
  EOE

  : both-newline-whitespace
  :
  $c <'set -nw' && $b 2>>EOE != 0
  testscript:1:1: error: set: both -n|--newline and -w|--whitespace specified
    info: test id: 1
  EOE
}

: arguments
:
{
  : none
  :
  $c <'set -e' && $b 2>>EOE != 0
  testscript:1:1: error: set: missing variable name
    info: test id: 1
  EOE

  : unexpected
  :
  $c <'set foo bar baz' && $b 2>>EOE != 0
  testscript:1:1: error: set: unexpected argument 'baz'
    info: test id: 1
  EOE

  : empty-attrs
  :
  $c <"set '' baz" && $b 2>>EOE != 0
  testscript:1:1: error: set: empty variable attributes
    info: test id: 1
  EOE

  : empty-var
  :
  $c <"set ''" && $b 2>>EOE != 0
  testscript:1:1: error: set: empty variable name
    info: test id: 1
  EOE
}

: whitespace-separated-list
:
{
  : non-exact
  :
  {
    : non-empty
    :
    $c <<EOI && $b
    set -w baz <' foo   bar ';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"'
    EOI

    : empty
    :
    $c <<EOI && $b
    set -w baz <:'';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >''
    EOI

    : spaces
    :
    $c <<EOI && $b
    set -w baz <'  ';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >''
    EOI
  }

  : exact
  :
  {
    : trailing-ws
    :
    $c <<EOI && $b
    set --exact --whitespace baz <' foo   bar ';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar" ""'
    EOI

    : no-trailing-ws
    :
    : Note that we need to strip the default trailing newline as well with the
    : ':' modifier.
    :
    $c <<EOI && $b
    set -e -w baz <:' foo bar';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"'
    EOI

    : empty
    :
    $c <<EOI && $b
    set -e -w baz <:'';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >''
    EOI

    : spaces
    :
    $c <<EOI && $b
    set -e -w baz <'  ';
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'""'
    EOI
  }
}

: newline-separated-list
:
{
  : non-exact
  :
  $c <<EOI && $b
  set -n baz <<EOF;

  foo

  bar

  EOF
  echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" ""'
  EOI

  : exact
  :
  {
    : trailing-newline
    :
    $c <<EOI && $b
    set --exact --newline baz <<EOF;

    foo

    bar

    EOF
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" "" ""'
    EOI

    : no-trailing-newline
    :
    $c <<EOI && $b
    set --exact --newline baz <<:EOF;

    foo

    bar
    EOF
    echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar"'
    EOI
  }
}

: string
:
{
  : non-exact
  :
  $c <<EOI && $b
  set baz <<EOF;

  foo

  bar

  EOF
  echo ($baz[0]) >>EOO

  foo

  bar

  EOO
  EOI

  : roundtrip
  :
  echo 'foo' | set bar;
  echo "$bar" >'foo'

  : exact
  :
  : Note that echo adds the trailing newline, so EOF and EOO here-documents
  : differ by this newline.
  :
  {
    : trailing-newline
    :
    $c <<EOI && $b
    set -e baz <<EOF;

    foo

    bar
    EOF
    echo ($baz[0]) >>EOO

    foo

    bar

    EOO
    EOI

    : no-trailing-newline
    :
    $c <<EOI && $b
    set -e baz <<:EOF;

    foo

    bar
    EOF
    echo ($baz[0]) >>EOO

    foo

    bar
    EOO
    EOI
  }
}

: special-vars
:
{
  $c <<EOI && $b
    set -w test.options <'-o foo';
    $* >'foo'
    EOI
}

: deadline
:
{
  : not-reached
  :
  $c <<EOI && $b
  env -t 10 -- $* -o 'foo' | set bar;
  echo "$bar" >'foo'
  EOI

  : non-pipe
  :
  $c <<EOI && $b
  env -t 10 -- set bar <'foo';
  echo "$bar" >'foo'
  EOI

  : set-reached
  :
  $c <<EOI && $b 2>>~%EOE% != 0
  $* -o 'foo' -l 10 | env -t 1 -- set bar
  EOI
  %testscript:.*: error: set terminated: execution timeout expired%
  %.
  EOE

  : driver-reached
  :
  $c <<EOI && $b 2>>~%EOE% != 0
  env -t 1 -- $* -o 'foo' -l 10 | set bar
  EOI
  %testscript:.*: error: .+driver.* terminated: execution timeout expired%
  %.
  EOE

  : read-some-data
  :
  {
    s="----------------------------------------------------------------------"
    s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s"
    s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s"

    : failure
    :
    $c <<EOI && $b 2>>~%EOE% != 0
    echo "$s" >=f;
    $* -o 'foo' -l 10 | cat f - | env -t 2 -- set bar
    EOI
    %testscript:.*: error: set terminated: execution timeout expired%
    %.
    EOE

    : success
    :
    : Note that the cat builtin ends up with the 'broken pipe' diagnostics or
    : similar.
    :
    $c <<EOI && $b
    echo "$s" >=f;
    timeout --success 2;
    $* -o 'foo' -l 10 | cat f - 2>>~%EOE% | set bar
      %cat: .+%
      EOE
    EOI
  }
}

: attributes
:
{
  : dir_path
  :
  $c <<EOI && $b
  set [dir_path] bar <'foo';
  echo $bar >/'foo/'
  EOI

  : null
  :
  $c <<EOI && $b
  set [null] foo <-;
  echo $foo >''
  EOI

  : none
  :
  $c <<EOI && $b 2>>EOE != 0
  set -w baz <'foo bar';
  echo "$baz"
  EOI
  testscript:2:8: error: concatenating variable expansion contains multiple values
  EOE

  # @@ Move the following tests to build2 parser unit tests when created.
  #
  : empty-brackets
  :
  $c <<EOI && $b 2>>EOE != 0
  set -w '[]' baz <'foo bar';
  echo "$baz"
  EOI
  testscript:2:8: error: concatenating variable expansion contains multiple values
  EOE

  : no-left-bracket
  :
  $c <<EOI && $b 2>>EOE != 0
  set -w x baz
  EOI
  <attributes>:1:1: error: expected '[' instead of 'x'
    testscript:1:1: info: while parsing attributes 'x'
    info: test id: 1
  EOE

  : unknown
  :
  $c <<EOI && $b 2>>EOE != 0
  set -w [x] baz
  EOI
  <attributes>:1:1: error: unknown value attribute x
    testscript:1:1: info: while parsing attributes '[x]'
    info: test id: 1
  EOE

  : junk
  :
  $c <<EOI && $b 2>>EOE != 0
  set -w '[string] x' baz
  EOI
  <attributes>:1:10: error: trailing junk after ']'
    testscript:1:1: info: while parsing attributes '[string] x'
    info: test id: 1
  EOE
}