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

.include ../common.testscript

: form-1
:
: for x: ...
:
{{
  : basics
  :
  $c <<EOI && $b >>EOO
    for x: a b
      echo "$x" >|
    EOI
    a
    b
    EOO

  : continue
  :
  $c <<EOI && $b >>EOO
    for x: a b c
    {
      if ($x == 'b')
        continue

      echo "$x" >|
    }
    EOI
    a
    c
    EOO

  : break
  :
  $c <<EOI && $b >>EOO
    for x: a b c
    {
      echo "$x" >|

      if ($x == 'b')
        break
    }
    EOI
    a
    b
    EOO

  : test-options
  :
  $c <<EOI && $b >>~%EOO%
    for test.options: -a -b
      echo $* >|
    EOI
    %.+ -a%
    %.+ -b%
    EOO

  : custom-iteration
  :
  $c <<EOI && $b >>EOO
    j = $json.parse('[1, 2, 3]')
    for e: $j
      echo $e >|
    EOI
    1
    2
    3
    EOO

  : special-var
  :
  $c <<EOI && $b 2>>EOE != 0
    for ~: -a -b
      echo $~ >|
    EOI
    testscript:1:5: error: attempt to set '~' variable directly
    EOE

  : exit
  :
  $c <<EOI && $b >>EOO
    for x: a b
    {
      echo "$x" >|
      exit
    }
    EOI
    a
    EOO

  : error
  :
  $c <<EOI && $b >>EOO 2>>EOE != 0
    for x: a b
    {
      echo "$x" >|
      exit 'fed up'
    }
    EOI
    a
    EOO
    testscript:4:3: error: fed up
      info: test id: 1
    EOE
}}

: form-2
:
: ... | for x
:
{{
  : whitespace-split
  :
  $c <<EOI && $b >>EOO
    echo " a b " | for -w x
      echo "'$x'" >|
    EOI
    'a'
    'b'
    EOO

  : newline-split
  :
  $c <<EOI && $b >>EOO
    cat <<EOF | for -n x


    a


    b

    EOF
      echo "'$x'" >|
    EOI
    ''
    ''
    'a'
    ''
    ''
    'b'
    ''
    EOO

  : typed
  :
  $c <<EOI && $b >>/EOO
    echo "a b" | for -w x [dir_path]
      echo $x >|
    EOI
    a/
    b/
    EOO

  : continue
  :
  $c <<EOI && $b >>EOO
    echo a b c | for x
    {
      if ($x == 'b')
        continue

      echo "$x" >|
    }
    EOI
    a
    c
    EOO

  : break
  :
  $c <<EOI && $b >>EOO
    echo a b c | for x
    {
      echo "$x" >|

      if ($x == 'b')
        break
    }
    EOI
    a
    b
    EOO

  : nested
  :
  $c <<EOI && $b >>EOO
    echo "a b" | for -w x
      echo "x y" | for -w y
        echo "'$x $y'" >|
    EOI
    'a x'
    'a y'
    'b x'
    'b y'
    EOO

  : nested-diag
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    echo "a b" | for -w x
      echo "x y" | for -w y
        echo "'$x $y'" >"'a x'"
    EOI
    testscript:3:5: error: echo stdout doesn't match expected
      info: stdout: test/1/stdout-i1-i2-n3
      info: expected stdout: test/1/stdout-i1-i2-n3.orig
      info: stdout diff: test/1/stdout-i1-i2-n3.diff
    %.+
    EOE

  : nested-diag-test-id
  :
  $c <<EOI && $b 2>>EOE != 0
    echo "a b" | for -w x
      echo "x y" | for -w y
        test -f $x$y
    EOI
    testscript:3:5: error: builtin test exited with code 1
      info: test id: 1
    EOE

  : var-value
  :
  $c <<EOI && $b >>EOO
    x = 'x';
    echo "a b" | for -w x
    {
    };
    echo $x >|
    EOI
    b
    EOO

  : both-sep-options
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    echo "a b" | for -n -w x
      echo $x >|
    EOI
    testscript:1:1: error: for: both -n|--newline and -w|--whitespace specified
    %.+
    EOE

  : invalid-option
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    echo "a b" | for -a x
      echo $x >|
    EOI
    testscript:1:1: error: for: unknown option '-a'
    %.+
    EOE

  : no-variable
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    echo "a b" | for -w
      echo $x >|
    EOI
    testscript:1:1: error: for: missing variable name
    %.+
    EOE

  : special-var
  :
  $c <<EOI && $b 2>>EOE != 0
    echo "a b" | for -w ~
      echo $* >|
    EOI
    testscript:1:1: error: attempt to set '~' variable directly
      info: test id: 1
    EOE

  : unsep-attrs
  :
  $c <<EOI && $b 2>>EOE != 0
    echo "a b" | for -w x[string]
      echo $x >|
    EOI
    testscript:1:1: error: for: expected variable name instead of x[string]
      info: test id: 1
    EOE

  : misuse
  :
  {{
    : after-var
    :
    $c <<EOI && $b 2>>EOE != 0
      echo "a b" | for v:
        echo $v >|
      EOI
      testscript:1:19: error: expected newline instead of ':'
      EOE

    : after-attrs
    :
    $c <<EOI && $b 2>>EOE != 0
      echo "a b" | for v [string]:
        echo $v >|
      EOI
      testscript:1:28: error: expected newline instead of ':'
      EOE
  }}

  : exit
  :
  $c <<EOI && $b >>EOO
    echo "a b" | for x
    {
      echo "$x" >|
      exit
    }
    EOI
    a
    EOO

  : exit-unread
  :
  {
    $c <<EOI && $b --no-diag-buffer
      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$s$s$s$s$s$s$s$s$s$s$s$s";
      cat <"a $s" 2>| | for v
      {
        if ($v == "a")
          exit 0
      }
      EOI
  }

  : error
  :
  $c <<EOI && $b >>EOO 2>>EOE != 0
    echo "a b" | for x
    {
      echo "$x" >|
      exit 'fed up'
    }
    EOI
    a
    EOO
    testscript:4:3: error: fed up
      info: test id: 1
    EOE
}}

: form-3
:
: for x <...
:
{{
  : whitespace-split
  :
  $c <<EOI && $b >>EOO
    for -w x <" a b "
      echo "'$x'" >|
    EOI
    'a'
    'b'
    EOO

  : quoted-opt
  :
  $c <<EOI && $b >>EOO
    o = -n
    for "$o" x <<EOF
      a
      b
      EOF
      echo "'$x'" >|;
    for "($o)" x <<EOF
      c
      d
      EOF
      echo "'$x'" >|
    EOI
    'a'
    'b'
    'c'
    'd'
    EOO

  : newline-split
  :
  $c <<EOI && $b >>EOO
    for -n x <<EOF


    a


    b

    EOF
      echo "'$x'" >|
    EOI
    ''
    ''
    'a'
    ''
    ''
    'b'
    ''
    EOO

  : string-before-var
  :
  $c <<EOI && $b >>EOO
    for <"a b" -w x
      echo "'$x'" >|
    EOI
    'a'
    'b'
    EOO

  : here-doc-before-var
  :
  $c <<EOI && $b >>EOO
    for <<EOF -n x
    a
    b
    EOF
      echo "'$x'" >|
    EOI
    'a'
    'b'
    EOO

  : typed
  :
  $c <<EOI && $b >>/EOO
    for -w x [dir_path] <"a b"
      echo $x >|
    EOI
    a/
    b/
    EOO

  : typed-no-ops
  :
  $c <<EOI && $b >>/EOO
    for x [dir_path] <"a b"
      echo $x >|
    EOI
    a/
    b/
    EOO

  : continue
  :
  $c <<EOI && $b >>EOO
    for x <"a b c"
    {
      if ($x == 'b')
        continue

      echo "$x" >|
    }
    EOI
    a
    c
    EOO

  : break
  :
  $c <<EOI && $b >>EOO
    for x <"a b c"
    {
      echo "$x" >|

      if ($x == 'b')
        break
    }
    EOI
    a
    b
    EOO

  : nested
  :
  $c <<EOI && $b >>EOO
    for -w x <"a b"
      for -w y <"x y"
        echo "'$x $y'" >|
    EOI
    'a x'
    'a y'
    'b x'
    'b y'
    EOO

  : nested-diag
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    for -w x <"a b"
      for -w y <"x y"
        echo "'$x $y'" >"'a x'"
    EOI
    testscript:3:5: error: echo stdout doesn't match expected
      info: stdout: test/1/stdout-i1-i2-n3
      info: expected stdout: test/1/stdout-i1-i2-n3.orig
      info: stdout diff: test/1/stdout-i1-i2-n3.diff
    %.+
    EOE

  : nested-diag-test-id
  :
  $c <<EOI && $b 2>>EOE != 0
    for -w x <"a b"
      for -w y <"x y"
        test -f $x$y
    EOI
    testscript:3:5: error: builtin test exited with code 1
      info: test id: 1
    EOE

  : var-value
  :
  $c <<EOI && $b >>EOO
    x = 'x';
    for -w x <"a b"
    {
    };
    echo $x >|
    EOI
    b
    EOO

  : invalid-option
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    for -a x <"a b"
      echo $x >|
    EOI
    testscript:1:1: error: for: unknown option '-a'
    %.
    EOE

  : no-variable
  :
  $c <<EOI && $b 2>>/~%EOE% != 0
    for -w <"a b"
      echo $x >|
    EOI
    testscript:1:1: error: for: missing variable name
    %.
    EOE

  : special-var
  :
  $c <<EOI && $b 2>>EOE != 0
    for ~ <"a b"
      echo $~ >|
    EOI
    testscript:1:5: error: attempt to set '~' variable directly
    EOE

  : exit
  :
  $c <<EOI && $b >>EOO
    for x <"a b"
    {
      echo "$x" >|
      exit
    }
    EOI
    a
    EOO

  : error
  :
  $c <<EOI && $b >>EOO 2>>EOE != 0
    for x <"a b"
    {
      echo "$x" >|
      exit 'fed up'
    }
    EOI
    a
    EOO
    testscript:4:3: error: fed up
      info: test id: 1
    EOE
}}

: syntax-1
:
{{
  b = [cmdline] $regex.apply($b, '(.+testscript.syntax).+', "\1 = 1'")

  : form-1
  :
  : for x: ...
  :
  {{
    : basics
    :
    $c <<EOI && $b >>EOO
      for x: a b
        echo "$x" >|
      end
      EOI
      a
      b
      EOO

    : test-options
    :
    $c <<EOI && $b >>~%EOO%
      for test.options: -a -b
        echo $* >|
      end
      EOI
      %.+ -a%
      %.+ -b%
      EOO

    : custom-iteration
    :
    $c <<EOI && $b >>EOO
      j = $json.parse('[1, 2, 3]')
      for e: $j
        echo $e >|
      end
      EOI
      1
      2
      3
      EOO

    : special-var
    :
    $c <<EOI && $b 2>>EOE != 0
      for ~: -a -b
        echo $~ >|
      end
      EOI
      testscript:1:5: error: attempt to set '~' variable directly
      EOE

    : exit
    :
    $c <<EOI && $b >>EOO
      for x: a b
        echo "$x" >|
        exit
      end
      EOI
      a
      EOO

    : error
    :
    $c <<EOI && $b >>EOO 2>>EOE != 0
      for x: a b
        echo "$x" >|
        exit 'fed up'
      end
      EOI
      a
      EOO
      testscript:3:3: error: fed up
        info: test id: 1
      EOE
  }}

  : form-2
  :
  : ... | for x
  :
  {{
    : whitespace-split
    :
    $c <<EOI && $b >>EOO
      echo " a b " | for -w x
        echo "'$x'" >|
      end
      EOI
      'a'
      'b'
      EOO

    : newline-split
    :
    $c <<EOI && $b >>EOO
      cat <<EOF | for -n x


      a


      b

      EOF
        echo "'$x'" >|
      end
      EOI
      ''
      ''
      'a'
      ''
      ''
      'b'
      ''
      EOO

    : typed
    :
    $c <<EOI && $b >>/EOO
      echo "a b" | for -w x [dir_path]
        echo $x >|
      end
      EOI
      a/
      b/
      EOO

    : nested
    :
    $c <<EOI && $b >>EOO
      echo "a b" | for -w x
        echo "x y" | for -w y
          echo "'$x $y'" >|
        end
      end
      EOI
      'a x'
      'a y'
      'b x'
      'b y'
      EOO

    : nested-diag
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      echo "a b" | for -w x
        echo "x y" | for -w y
          echo "'$x $y'" >"'a x'"
        end
      end
      EOI
      testscript:3:5: error: echo stdout doesn't match expected
        info: stdout: test/1/stdout-i1-i2-n3
        info: expected stdout: test/1/stdout-i1-i2-n3.orig
        info: stdout diff: test/1/stdout-i1-i2-n3.diff
      %.+
      EOE

    : nested-diag-test-id
    :
    $c <<EOI && $b 2>>EOE != 0
      echo "a b" | for -w x
        echo "x y" | for -w y
          test -f $x$y
        end
      end
      EOI
      testscript:3:5: error: builtin test exited with code 1
        info: test id: 1
      EOE

    : var-value
    :
    $c <<EOI && $b >>EOO
      x = 'x';
      echo "a b" | for -w x
      end;
      echo $x >|
      EOI
      b
      EOO

    : both-sep-options
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      echo "a b" | for -n -w x
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: both -n|--newline and -w|--whitespace specified
      %.+
      EOE

    : invalid-option
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      echo "a b" | for -a x
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: unknown option '-a'
      %.+
      EOE

    : no-variable
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      echo "a b" | for -w
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: missing variable name
      %.+
      EOE

    : special-var
    :
    $c <<EOI && $b 2>>EOE != 0
      echo "a b" | for -w ~
        echo $* >|
      end
      EOI
      testscript:1:1: error: attempt to set '~' variable directly
        info: test id: 1
      EOE

    : unsep-attrs
    :
    $c <<EOI && $b 2>>EOE != 0
      echo "a b" | for -w x[string]
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: expected variable name instead of x[string]
        info: test id: 1
      EOE

    : misuse
    :
    {{
      : after-var
      :
      $c <<EOI && $b 2>>EOE != 0
        echo "a b" | for v:
          echo $v >|
        end
        EOI
        testscript:1:19: error: expected newline instead of ':'
        EOE

      : after-attrs
      :
      $c <<EOI && $b 2>>EOE != 0
        echo "a b" | for v [string]:
          echo $v >|
        end
        EOI
        testscript:1:28: error: expected newline instead of ':'
        EOE
    }}

    : exit
    :
    $c <<EOI && $b >>EOO
      echo "a b" | for x
        echo "$x" >|
        exit
      end
      EOI
      a
      EOO

    : error
    :
    $c <<EOI && $b >>EOO 2>>EOE != 0
      echo "a b" | for x
        echo "$x" >|
        exit 'fed up'
      end
      EOI
      a
      EOO
      testscript:3:3: error: fed up
        info: test id: 1
      EOE
  }}

  : form-3
  :
  : for x <...
  :
  {{
    : whitespace-split
    :
    $c <<EOI && $b >>EOO
      for -w x <" a b "
        echo "'$x'" >|
      end
      EOI
      'a'
      'b'
      EOO

    : quoted-opt
    :
    $c <<EOI && $b >>EOO
      o = -n
      for "$o" x <<EOF
        a
        b
        EOF
        echo "'$x'" >|
      end;
      for "($o)" x <<EOF
        c
        d
        EOF
        echo "'$x'" >|
      end
      EOI
      'a'
      'b'
      'c'
      'd'
      EOO

    : newline-split
    :
    $c <<EOI && $b >>EOO
      for -n x <<EOF


      a


      b

      EOF
        echo "'$x'" >|
      end
      EOI
      ''
      ''
      'a'
      ''
      ''
      'b'
      ''
      EOO

    : string-before-var
    :
    $c <<EOI && $b >>EOO
      for <"a b" -w x
        echo "'$x'" >|
      end
      EOI
      'a'
      'b'
      EOO

    : here-doc-before-var
    :
    $c <<EOI && $b >>EOO
      for <<EOF -n x
      a
      b
      EOF
        echo "'$x'" >|
      end
      EOI
      'a'
      'b'
      EOO

    : typed
    :
    $c <<EOI && $b >>/EOO
      for -w x [dir_path] <"a b"
        echo $x >|
      end
      EOI
      a/
      b/
      EOO

    : typed-no-ops
    :
    $c <<EOI && $b >>/EOO
      for x [dir_path] <"a b"
        echo $x >|
      end
      EOI
      a/
      b/
      EOO

    : nested
    :
    $c <<EOI && $b >>EOO
      for -w x <"a b"
        for -w y <"x y"
          echo "'$x $y'" >|
        end
      end
      EOI
      'a x'
      'a y'
      'b x'
      'b y'
      EOO

    : nested-diag
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      for -w x <"a b"
        for -w y <"x y"
          echo "'$x $y'" >"'a x'"
        end
      end
      EOI
      testscript:3:5: error: echo stdout doesn't match expected
        info: stdout: test/1/stdout-i1-i2-n3
        info: expected stdout: test/1/stdout-i1-i2-n3.orig
        info: stdout diff: test/1/stdout-i1-i2-n3.diff
      %.+
      EOE

    : nested-diag-test-id
    :
    $c <<EOI && $b 2>>EOE != 0
      for -w x <"a b"
        for -w y <"x y"
          test -f $x$y
        end
      end
      EOI
      testscript:3:5: error: builtin test exited with code 1
        info: test id: 1
      EOE

    : var-value
    :
    $c <<EOI && $b >>EOO
      x = 'x';
      for -w x <"a b"
      end;
      echo $x >|
      EOI
      b
      EOO

    : invalid-option
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      for -a x <"a b"
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: unknown option '-a'
      %.
      EOE

    : no-variable
    :
    $c <<EOI && $b 2>>/~%EOE% != 0
      for -w <"a b"
        echo $x >|
      end
      EOI
      testscript:1:1: error: for: missing variable name
      %.
      EOE

    : special-var
    :
    $c <<EOI && $b 2>>EOE != 0
      for ~ <"a b"
        echo $~ >|
      end
      EOI
      testscript:1:5: error: attempt to set '~' variable directly
      EOE

    : exit
    :
    $c <<EOI && $b >>EOO
      for x <"a b"
        echo "$x" >|
        exit
      end
      EOI
      a
      EOO

    : error
    :
    $c <<EOI && $b >>EOO 2>>EOE != 0
      for x <"a b"
        echo "$x" >|
        exit 'fed up'
      end
      EOI
      a
      EOO
      testscript:3:3: error: fed up
        info: test id: 1
      EOE
  }}
}}
