# file      : libbuild2/test/script/parser+scope-if.test.testscript
# license   : MIT; see accompanying LICENSE file

: group
:
{{
  : if
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if true foo
    {{
      cmd
    }}
    EOI
    {{
      ? true foo
      {{
        {
          cmd
        }
      }}
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false foo
    {{
      cmd
    }}
    EOI
    {{
      ? false foo
    }}
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if! true
    {{
      cmd
    }}
    EOI
    {{
      ? true
    }}
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if! false
    {{
      cmd
    }}
    EOI
    {{
      ? false
      {{
        {
          cmd
        }
      }}
    }}
    EOO

    : eos-inside
    :
    $* <<EOI 2>>EOE != 0
    if
    {{
    EOI
    testscript:3:1: error: expected '}}' at the end of the group scope
    EOE

    : in-command
    :
    $* <<EOI 2>>EOE != 0
    cmd;
    if false
    {{
      cmd1
    }};
    cmd2
    EOI
    testscript:3:1: error: expected command or '{' instead of '{{'
    EOE

    : semi-after-block
    :
    $* <<EOI 2>>EOE != 0
    if false
    {{
      cmd1
    }};
    cmd2
    EOI
    testscript:4:3: error: expected newline after '}}'
    EOE

    : colon-after-block
    :
    $* <<EOI 2>>EOE != 0
    if false
    {{
      cmd1
    }} : description
    EOI
    testscript:4:4: error: expected newline after '}}'
    EOE
  }}

  : elif
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    elif true
    {{
      cmd1
    }}
    EOI
    {{
      ? false
      ? true
      {{
        {
          cmd1
        }
      }}
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    elif false
    {{
      cmd
    }}
    EOI
    {{
      ? false
      ? false
    }}
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    elif! false
    {{
      cmd1
    }}
    EOI
    {{
      ? false
      ? false
      {{
        {
          cmd1
        }
      }}
    }}
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    elif! true
    {{
      cmd
    }}
    EOI
    {{
      ? false
      ? true
    }}
    EOO

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {{
      cmd
    }}
    else
    {{
      cmd
    }}
    elif true
    {{
      cmd
    }}
    EOI
    testscript:9:1: error: 'elif' after 'else'
    EOE
  }}

  : else
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    else
    {{
      cmd1
    }}
    EOI
    {{
      ? false
      {{
        {
          cmd1
        }
      }}
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if true
    {{
      cmd1
    }}
    else
    {{
      cmd
    }}
    EOI
    {{
      ? true
      {{
        {
          cmd1
        }
      }}
    }}
    EOO

    : chain
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd
    }}
    elif false
    {{
      cmd
      cmd
    }}
    elif false
    {{
      cmd
    }}
    elif true
    {{
      cmd1
      cmd2
    }}
    elif false
    {{
      cmd
    }}
    else
    {{
      cmd
      cmd
    }}
    EOI
    {{
      ? false
      ? false
      ? false
      ? true
      {{
        {
          cmd1
        }
        {
          cmd2
        }
      }}
    }}
    EOO

    : scope-expected
    :
    $* <<EOI 2>>EOE != 0
    if
    {{
      cmd
    }}
    else
    cmd
    EOI
    testscript:6:1: error: expected group scope after 'else'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {{
      cmd
    }}
    else
    {{
      cmd
    }}
    else
    {{
      cmd
    }}
    EOI
    testscript:9:1: error: 'else' after 'else'
    EOE
  }}

  : if-predicate
  :
  {{
    test.options += -s

    : ifn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd1
          }
          {
            cmd2
          }
        }}
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : without-value
      :
      $* <<EOI 2>>EOE != 0
      ifn
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      testscript:1:4: error: expected value after 'ifn'
      EOE
    }}

    : elifn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn foo
      {{
        cmd1
        cmd2
      }}
      elifn $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn foo
      {
        cmd1
        cmd2
      }
      elifn $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : after-else
      :
      $* <<EOI 2>>EOE != 0
      ifn foo
      {{
        cmd
      }}
      else
      {{
        cmd
      }}
      elifn bar
      {{
        cmd
      }}
      EOI
      testscript:9:1: error: 'elifn' after 'else'
      EOE
    }}

    : ifnn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn! $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn! $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd1
          }
          {
            cmd2
          }
        }}
      }}
      EOO
    }}

    : elifnn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn foo
      {{
        cmd1
        cmd2
      }}
      elifn! $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn foo
      {{
        cmd1
        cmd2
      }}
      elifn! $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO
    }}

    : ife
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd1
          }
          {
            cmd2
          }
        }}
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : without-value
      :
      $* <<EOI 2>>EOE != 0
      ife
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      testscript:1:4: error: expected value after 'ife'
      EOE
    }}

    : elife
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife foo
      {{
        cmd1
        cmd2
      }}
      elife $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife foo
      {
        cmd1
        cmd2
      }
      elife $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : after-else
      :
      $* <<EOI 2>>EOE != 0
      ife foo
      {{
        cmd
      }}
      else
      {{
        cmd
      }}
      elife bar
      {{
        cmd
      }}
      EOI
      testscript:9:1: error: 'elife' after 'else'
      EOE
    }}

    : ifen
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife! $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife! $foo
      {{
        cmd1
        cmd2
      }}
      else
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd1
          }
          {
            cmd2
          }
        }}
      }}
      EOO
    }}

    : elifen
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife foo
      {{
        cmd1
        cmd2
      }}
      elife! $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife foo
      {{
        cmd1
        cmd2
      }}
      elife! $foo
      {{
        cmd3
        cmd4
      }}
      EOI
      {{
        {{
          {
            cmd3
          }
          {
            cmd4
          }
        }}
      }}
      EOO
    }}
  }}

  : nested
  :
  {{
    : take
    :
    $* -s <<EOI >>EOO
    if true
    {{
      cmd1
      if false
      {{
        cmd
      }}
      elif false
      {{
        if true
        {{
          cmd
        }}
      }}
      else
      {{
        cmd2
      }}
      cmd3
    }}
    EOI
    {{
      ? true
      {{
        {
          cmd1
        }
        ? false
        ? false
        {{
          {
            cmd2
          }
        }}
        {
          cmd3
        }
      }}
    }}
    EOO

    : skip
    :
    $* -s <<EOI >>EOO
    if false
    {{
      cmd1
      if false
      {{
        cmd
      }}
      elif false
      {{
        if true
        {{
          cmd
        }}
      }}
      else
      {{
        cmd2
      }}
      cmd3
    }}
    else
    {{
      cmd
    }}
    EOI
    {{
      ? false
      {{
        {
          cmd
        }
      }}
    }}
    EOO
  }}

  : line-index
  : Make sure command line index spans setup/if/teardown
  :
  $* -s -l <<EOI >>EOO
  +setup          # 1

  if false one    # 2
  {{
    cmd
  }}
  elif false two  # 3
  {{
    cmd
  }}
  elif true       # 4
  {{
    cmd1
  }}
  elif false      # 5
  {{
    cmd
  }}
  else
  {{
    cmd
  }}

  if false one    # 6
  {{
    cmd
  }}
  elif false two  # 7
  {{
    cmd
  }}
  else
  {{
    cmd2
  }}

  -tdown          # 8
  EOI
  {{
    +setup # 1
    ? false one # 2
    ? false two # 3
    ? true # 4
    {{
      {
        cmd1 # 0
      }
    }}
    ? false one # 6
    ? false two # 7
    {{
      {
        cmd2 # 0
      }
    }}
    -tdown # 8
  }}
  EOO

  : scope-command-if
  :
  $* -s <<EOI >>EOO
  if true
  {{
    cmd
  }}
  if true
  {
    cmd1
    cmd2
  };
  cmd3
  EOI
  {{
    ? true
    {{
      {
        cmd
      }
    }}
    {
      ? true
      cmd1
      cmd2
      cmd3
    }
  }}
  EOO

  : shared-id-desc
  :
  $* -s -i <<EOI >>EOO
  : test summary
  :
  if false
  {{
    cmd
  }}
  else
  {{
    cmd1
  }}
  EOI
  {{
    ? false
    : sm:test summary
    {{ # 3
      { # 3/9
        cmd1
      }
    }}
  }}
  EOO

  : trailing-desc
  :
  $* -s <<EOI 2>>EOE != 0
  if true
  {{
    cmd
  }} : test summary
  EOI
  testscript:4:4: error: expected newline after '}}'
  EOE
}}

: test
:
{{
  : if
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if true foo
    {
      cmd
    }
    EOI
    {{
      ? true foo
      {
        cmd
      }
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false foo
    {
      cmd
    }
    EOI
    {{
      ? false foo
    }}
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if! true
    {
      cmd
    }
    EOI
    {{
      ? true
    }}
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if! false
    {
      cmd
    }
    EOI
    {{
      ? false
      {
        cmd
      }
    }}
    EOO

    : eos-inside
    :
    $* <<EOI 2>>EOE != 0
    if
    {
    EOI
    testscript:3:1: error: expected '}' at the end of test scope
    EOE
  }}

  : elif
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif true
    {
      cmd1
    }
    EOI
    {{
      ? false
      ? true
      {
        cmd1
      }
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif false
    {
      cmd
    }
    EOI
    {{
      ? false
      ? false
    }}
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif! false
    {
      cmd1
    }
    EOI
    {{
      ? false
      ? false
      {
        cmd1
      }
    }}
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif! true
    {
      cmd
    }
    EOI
    {{
      ? false
      ? true
    }}
    EOO

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd
    }
    else
    {
      cmd
    }
    elif true
    {
      cmd
    }
    EOI
    testscript:9:1: error: 'elif' after 'else'
    EOE
  }}

  : else
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    else
    {
      cmd1
    }
    EOI
    {{
      ? false
      {
        cmd1
      }
    }}
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if true
    {
      cmd1
    }
    else
    {
      cmd
    }
    EOI
    {{
      ? true
      {
        cmd1
      }
    }}
    EOO

    : chain
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif false
    {
      cmd
      cmd
    }
    elif false
    {
      cmd
    }
    elif true
    {
      cmd1
      cmd2
    }
    elif false
    {
      cmd
    }
    else
    {
      cmd
      cmd
    }
    EOI
    {{
      ? false
      ? false
      ? false
      ? true
      {
        cmd1
        cmd2
      }
    }}
    EOO

    : scope-expected
    :
    $* <<EOI 2>>EOE != 0
    if
    {
      cmd
    }
    else
    EOI
    testscript:6:1: error: expected command instead of <end of file> inside test scope
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd
    }
    else
    {
      cmd
    }
    else
    {
      cmd
    }
    EOI
    testscript:9:1: error: 'else' after 'else'
    EOE
  }}

  : if-predicate
  :
  {{
    test.options += -s

    : ifn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd1
          cmd2
        }
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : without-value
      :
      $* <<EOI 2>>EOE != 0
      ifn
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      testscript:1:4: error: expected value after 'ifn'
      EOE
    }}

    : elifn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn foo
      {
        cmd1
        cmd2
      }
      elifn $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn foo
      {
        cmd1
        cmd2
      }
      elifn $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : after-else
      :
      $* <<EOI 2>>EOE != 0
      ifn foo
      {
        cmd
      }
      else
      {
        cmd
      }
      elifn bar
      {
        cmd
      }
      EOI
      testscript:9:1: error: 'elifn' after 'else'
      EOE
    }}

    : ifnn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn! $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn! $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd1
          cmd2
        }
      }}
      EOO
    }}

    : elifnn
    :
    {{
      : null
      :
      $* <<EOI >>EOO
      ifn foo
      {
        cmd1
        cmd2
      }
      elifn! $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : not-null
      :
      $* <<EOI >>EOO
      foo =
      ifn foo
      {
        cmd1
        cmd2
      }
      elifn! $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO
    }}

    : ife
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd1
          cmd2
        }
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : without-value
      :
      $* <<EOI 2>>EOE != 0
      ife
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      testscript:1:4: error: expected value after 'ife'
      EOE
    }}

    : elife
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife foo
      {
        cmd1
        cmd2
      }
      elife $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife foo
      {
        cmd1
        cmd2
      }
      elife $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : after-else
      :
      $* <<EOI 2>>EOE != 0
      ife foo
      {
        cmd
      }
      else
      {
        cmd
      }
      elife bar
      {
        cmd
      }
      EOI
      testscript:9:1: error: 'elife' after 'else'
      EOE
    }}

    : ifen
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife! $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife! $foo
      {
        cmd1
        cmd2
      }
      else
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd1
          cmd2
        }
      }}
      EOO
    }}

    : elifen
    :
    {{
      : empty
      :
      $* <<EOI >>EOO
      foo =
      ife foo
      {
        cmd1
        cmd2
      }
      elife! $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
      }}
      EOO

      : not-empty
      :
      $* <<EOI >>EOO
      foo = 'abc'
      ife foo
      {
        cmd1
        cmd2
      }
      elife! $foo
      {
        cmd3
        cmd4
      }
      EOI
      {{
        {
          cmd3
          cmd4
        }
      }}
      EOO
    }}
  }}

  : nested
  :
  {{
    : take
    :
    $* -s <<EOI >>EOO
    if true
    {
      cmd1
      if false
      {
        cmd
      }
      elif false
      {
        if true
        {
          cmd
        }
      }
      else
      {
        cmd2
      }
      cmd3
    }
    EOI
    {{
      ? true
      {
        cmd1
        ? false
        ? false
        cmd2
        cmd3
      }
    }}
    EOO

    : skip
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd1
      if false
      {
        cmd
      }
      elif false
      {
        if true
        {
          cmd
        }
      }
      else
      {
        cmd2
      }
      cmd3
    }
    else
    {
      cmd
    }
    EOI
    {{
      ? false
      {
        cmd
      }
    }}
    EOO
  }}

  : line-index
  : Make sure command line index spans setup/if/teardown
  :
  $* -s -l <<EOI >>EOO
  +setup1         # 1

  +ifn [null]
    setup2        # 2

  +ife ()
    setup3        # 3

  if false one    # 4
  {
    cmd
  }
  elif false two  # 5
  {
    cmd
  }
  elif true       # 6
  {
    cmd1
  }
  elif false      # 7
  {
    cmd
  }
  else
  {
    cmd
  }

  if false one    # 8
  {
    cmd
  }
  elif false two  # 9
  {
    cmd
  }
  else
  {
    cmd2
  }

  -ife! foo
    tdown1        # 10

  -ifn! foo
    tdown2        # 11

  -tdown3         # 12
  EOI
  {{
    +setup1 # 1
    +setup2 # 2
    +setup3 # 3
    ? false one # 4
    ? false two # 5
    ? true # 6
    {
      cmd1 # 0
    }
    ? false one # 8
    ? false two # 9
    {
      cmd2 # 0
    }
    -tdown1 # 10
    -tdown2 # 11
    -tdown3 # 12
  }}
  EOO

  : scope-command-if
  :
  $* -s <<EOI >>EOO
  if true
  {
    cmd
  }
  if true
  {
    cmd1
    cmd2
  };
  cmd3
  EOI
  {{
    ? true
    {
      cmd
    }
    {
      ? true
      cmd1
      cmd2
      cmd3
    }
  }}
  EOO

  : shared-id-desc
  :
  $* -s -i <<EOI >>EOO
  : test summary
  :
  if false
  {
    cmd
  }
  else
  {
    cmd1
  }
  EOI
  {{
    ? false
    : sm:test summary
    { # 3
      cmd1
    }
  }}
  EOO

  : trailing-desc
  :
  $* -s <<EOI >>EOO
  if true
    cmd : test summary
  EOI
  {{
    : sm:test summary
    {
      ? true
      cmd
    }
  }}
  EOO

  : trailing-desc-block
  :
  $* -s <<EOI >>EOO
  if true
  {
    cmd
  } : test summary
  EOI
  {{
    : sm:test summary
    {
      ? true
      cmd
    }
  }}
  EOO

  : var-only
  :
  $* -s <<EOI >>EOO
  foo = a
  if true
  {
  }
  if true
  {
    foo += b
  }
  cmd1 $foo
  cmd2 $foo
  EOI
  {{
    ? true
    ? true
    {
      cmd1 a b
    }
    {
      cmd2 a b
    }
  }}
  EOO
}}

: syntax-1
:
{{
  test.options += -v 1

  : if
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if true foo
    {
      cmd
    }
    EOI
    {
      ? true foo
      {
        cmd
      }
    }
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false foo
    {
      cmd
    }
    EOI
    {
      ? false foo
    }
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if! true
    {
      cmd
    }
    EOI
    {
      ? true
    }
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if! false
    {
      cmd
    }
    EOI
    {
      ? false
      {
        cmd
      }
    }
    EOO

    : eos-inside
    :
    $* <<EOI 2>>EOE != 0
    if
    {
    EOI
    testscript:3:1: error: expected '}' at the end of the scope
    EOE

    : in-command
    :
    $* <<EOI 2>>EOE != 0
    cmd;
    if false
    {
      cmd1
    };
    cmd2
    EOI
    testscript:3:1: error: expected command instead of '{'
    EOE

    : semi-after-block
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd1
    };
    cmd2
    EOI
    testscript:4:2: error: expected newline after '}'
    EOE

    : colon-after-block
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd1
    } : description
    EOI
    testscript:4:3: error: expected newline after '}'
    EOE
  }}

  : elif
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif true
    {
      cmd1
    }
    EOI
    {
      ? false
      ? true
      {
        cmd1
      }
    }
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif false
    {
      cmd
    }
    EOI
    {
      ? false
      ? false
    }
    EOO

    : not-false
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif! false
    {
      cmd1
    }
    EOI
    {
      ? false
      ? false
      {
        cmd1
      }
    }
    EOO

    : not-true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif! true
    {
      cmd
    }
    EOI
    {
      ? false
      ? true
    }
    EOO

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd
    }
    else
    {
      cmd
    }
    elif true
    {
      cmd
    }
    EOI
    testscript:9:1: error: 'elif' after 'else'
    EOE
  }}

  : else
  :
  {{
    : true
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    else
    {
      cmd1
    }
    EOI
    {
      ? false
      {
        cmd1
      }
    }
    EOO

    : false
    :
    $* -s <<EOI >>EOO
    if true
    {
      cmd1
    }
    else
    {
      cmd
    }
    EOI
    {
      ? true
      {
        cmd1
      }
    }
    EOO

    : chain
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif false
    {
      cmd
      cmd
    }
    elif false
    {
      cmd
    }
    elif true
    {
      cmd1
      cmd2
    }
    elif false
    {
      cmd
    }
    else
    {
      cmd
      cmd
    }
    EOI
    {
      ? false
      ? false
      ? false
      ? true
      {
        {
          cmd1
        }
        {
          cmd2
        }
      }
    }
    EOO

    : scope-expected
    :
    $* <<EOI 2>>EOE != 0
    if
    {
      cmd
    }
    else
    cmd
    EOI
    testscript:6:1: error: expected scope after 'else'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
    {
      cmd
    }
    else
    {
      cmd
    }
    else
    {
      cmd
    }
    EOI
    testscript:9:1: error: 'else' after 'else'
    EOE
  }}

  : nested
  :
  {{
    : take
    :
    $* -s <<EOI >>EOO
    if true
    {
      cmd1
      if false
      {
        cmd
      }
      elif false
      {
        if true
        {
          cmd
        }
      }
      else
      {
        cmd2
      }
      cmd3
    }
    EOI
    {
      ? true
      {
        {
          cmd1
        }
        ? false
        ? false
        {
          {
            cmd2
          }
        }
        {
          cmd3
        }
      }
    }
    EOO

    : skip
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd1
      if false
      {
        cmd
      }
      elif false
      {
        if true
        {
          cmd
        }
      }
      else
      {
        cmd2
      }
      cmd3
    }
    else
    {
      cmd
    }
    EOI
    {
      ? false
      {
        {
          cmd
        }
      }
    }
    EOO
  }}

  : demote
  :
  {{
    : group
    : Chain remains a group
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif true
    {
      cmd1
      cmd2
    }
    else
    {
      cmd
    }
    EOI
    {
      ? false
      ? true
      {
        {
          cmd1
        }
        {
          cmd2
        }
      }
    }
    EOO

    : test
    : Chain demoted to test
    :
    $* -s <<EOI >>EOO
    if false
    {
      cmd
    }
    elif true
    {
      cmd1
    }
    else
    {
      cmd
    }
    EOI
    {
      ? false
      ? true
      {
        cmd1
      }
    }
    EOO
  }}

  : line-index
  : Make sure command line index spans setup/if/teardown
  :
  $* -s -l <<EOI >>EOO
  +setup          # 1

  if false one    # 2
  {
    cmd
  }
  elif false two  # 3
  {
    cmd
  }
  elif true       # 4
  {
    cmd1
  }
  elif false      # 5
  {
    cmd
  }
  else
  {
    cmd
  }

  if false one    # 6
  {
    cmd
  }
  elif false two  # 7
  {
    cmd
  }
  else
  {
    cmd2
  }

  -tdown          # 8
  EOI
  {
    +setup # 1
    ? false one # 2
    ? false two # 3
    ? true # 4
    {
      cmd1 # 0
    }
    ? false one # 6
    ? false two # 7
    {
      cmd2 # 0
    }
    -tdown # 8
  }
  EOO

  : scope-command-if
  :
  $* -s <<EOI >>EOO
  if true
  {
    cmd
  }
  if true
    cmd1
    cmd2
  end
  EOI
  {
    ? true
    {
      cmd
    }
    {
      ? true
      cmd1
      cmd2
    }
  }
  EOO

  : shared-id-desc
  :
  $* -s -i <<EOI >>EOO
  : test summary
  :
  if false
  {
    cmd
  }
  else
  {
    cmd1
  }
  EOI
  {
    ? false
    : sm:test summary
    { # 3
      cmd1
    }
  }
  EOO

  : var-only
  :
  $* -s <<EOI >>EOO
  foo = a
  if true
  end
  if true
    foo += b
  end
  cmd1 $foo
  cmd2 $foo
  EOI
  {
    ? true
    ? true
    {
      cmd1 a b
    }
    {
      cmd2 a b
    }
  }
  EOO
}}
