# file      : tests/function/path/testscript
# license   : MIT; see accompanying LICENSE file

.include ../../common.testscript

windows = ($cxx.target.class == 'windows')
posix = (!$windows)

s = ($posix ? '/' : '\')

: posix-string
:
{
  : relative
  :
  {
    s = ($posix ? '/' : '\\')

    $* <"print \$posix_string\([path] a$(s)b)"                 >'a/b'     : path
    $* <"print \$posix_string\([paths] a$(s)b a$(s)c$(s))"     >'a/b a/c' : paths
    $* <"print \$posix_string\([dir_path] a$(s)b)"             >'a/b'     : dir-path
    $* <"print \$posix_string\([dir_paths] a$(s)b a$(s)c$(s))" >'a/b a/c' : dir-paths
    $* <"print \$path.posix_string\(a$(s)b a$(s)c$(s))"        >'a/b a/c' : untyped
  }

  : absolute
  :
  {
    if $posix
    {
      $* <'print $posix_string([paths] /a/b /a/c/)'     >'/a/b /a/c' : paths
      $* <'print $posix_string([dir_paths] /a/b /a/c/)' >'/a/b /a/c' : dir-paths
      $* <'print $posix_string([dir_path] /)'           >'/'         : root-dir
      $* <'print $path.posix_string(/a/b /a/c/)'        >'/a/b /a/c' : untyped
    }
    else
    {
      $* <'print $posix_string([paths] "c:\\a\\b" "C:\\a\\c\\")'     >'c:/a/b C:/a/c' : paths
      $* <'print $posix_string([dir_paths] "c:\\a\\b" "C:\\a\\c\\")' >'c:/a/b C:/a/c' : dir-paths
      $* <'print $posix_string([dir_paths] "c:\\" "C:")'             >'c:/ C:/'       : root-dir
      $* <'print $path.posix_string("c:\\a\\b" "C:\\a\\c\\")'        >'c:/a/b C:/a/c' : untyped
      $* <'print $path.posix_string("c:\\" "C:")'                    >'c:/ C:/'       : untyped-root
    }
  }
}

: posix-representation
:
{
  : relative
  :
  {
    s = ($posix ? '/' : '\\')

    $* <"print \$posix_representation\([path] a$(s)b)"                 >'a/b'       : path
    $* <"print \$posix_representation\([paths] a$(s)b a$(s)c$(s))"     >'a/b a/c/'  : paths
    $* <"print \$posix_representation\([dir_path] a$(s)b)"             >'a/b/'      : dir-path
    $* <"print \$posix_representation\([dir_paths] a$(s)b a$(s)c$(s))" >'a/b/ a/c/' : dir-paths
    $* <"print \$path.posix_representation\(a$(s)b a$(s)c$(s))"        >'a/b a/c/'  : untyped
  }

  : absolute
  :
  {
    if $posix
    {
      $* <'print $posix_representation([paths] /a/b /a/c/)'     >'/a/b /a/c/'  : paths
      $* <'print $posix_representation([dir_paths] /a/b /a/c/)' >'/a/b/ /a/c/' : dir-paths
      $* <'print $posix_representation([dir_path] /)'           >'/'           : root-dir
      $* <'print $path.posix_representation(/a/b /a/c/)'        >'/a/b /a/c/'  : untyped
    }
    else
    {
      $* <'print $posix_representation([paths] "c:\\a\\b" "C:\\a\\c\\")'     >'c:/a/b C:/a/c/'  : paths
      $* <'print $posix_representation([dir_paths] "c:\\a\\b" "C:\\a\\c\\")' >'c:/a/b/ C:/a/c/' : dir-paths
      $* <'print $posix_representation([dir_paths] "c:\\" "C:")'             >'c:/ C:/'         : root-dir
      $* <'print $path.posix_representation("c:\\a\\b" "C:\\a\\c\\")'        >'c:/a/b C:/a/c/'  : untyped
      $* <'print $path.posix_representation("c:\\" "C:")'                    >'c:/ C:/'         : untyped-root
    }
  }
}

: canonicalize
:
{
  $* <'print $canonicalize([path] a/b)'           >"a$(s)b"            : path
  $* <'print $canonicalize([paths] a/b a/c)'      >"a$(s)b a$(s)c"     : paths
  $* <'print $canonicalize([dir_path] a/b)'       >"a$(s)b$s"          : dir-path
  $* <'print $canonicalize([dir_paths] a/b a/c/)' >"a$(s)b$s a$(s)c$s" : dir-paths
  $* <'print $path.canonicalize(a/b)'             >"a$(s)b"            : untyped
  $* <'print $path.canonicalize(a/b/ a/c)'        >"a$(s)b$s a$(s)c"   : mixed
}

: normalize
:
{
  $* <'print $normalize([path] a/../b)'              >"b"        : path
  $* <'print $normalize([paths] a/../b a/../c)'      >"b c"      : paths
  $* <'print $normalize([dir_path] a/../b)'          >"b$s"      : dir-path
  $* <'print $normalize([dir_paths] a/../b a/../c/)' >"b$s c$s"  : dir-paths
  $* <'print $path.normalize(a/../b)'                >"b"        : untyped
  $* <'print $path.normalize(a/../b/ a/../c)'        >"b$s c"    : mixed
}

: actualize
:
if! $posix
{
  mkdir Foo;
  $* <'print $path.actualize($out_base/foo)' >~'/.+\\Foo/'
}


: directory
:
{
  $* <'print $directory([path] a/b)'           >"a/"    : path
  $* <'print $directory([dir_path] a/b)'       >"a/"    : dir-path
  $* <'print $directory([paths] a/b c/d/)'     >"a/ c/" : paths
  $* <'print $directory([dir_paths] a/b c/d/)' >"a/ c/" : dir-paths
  $* <'print $path.directory(a/b c/d/)'        >"a/ c/" : dir-names
}

: root_directory
:
{
  : posix
  :
  if $posix
  {
    $* <'print $root_directory([path] /a/b)' >'/' : basics
    $* <'print $root_directory([path] /)' >'/'    : root
  }

  : windows
  :
  if $windows
  {
    $* <'print $root_directory([path] "c:\\a\\b")' >'c:\' : basics
    $* <'print $root_directory([path] "c:")'       >'c:\' : root
  }

  $* <'print $root_directory([path] a/b)' >'' : relative
}

: base
:
{
  $* <'print $base([path] a.c)'               >"a"      : path
  $* <'print $base([dir_path] a.tmp)'         >"a$s"    : dir-path
  $* <'print $base([paths] a.c b.tmp/)'       >"a b/"   : paths
  $* <'print $base([dir_paths] a.tmp b.tmp/)' >"a$s b/" : dir-paths
  $* <'print $path.base(a.c b.tmp/)'          >"a b/"   : dir-names
}

: leaf
:
{
  $* <'print $leaf([path] a/b)'                          >"b"        : path
  $* <'print $leaf([dir_path] a/b)'                      >"b$s"      : dir-path
  $* <'print $leaf([path] a/b/c, [dir_path] a)'          >"b/c"      : sub-path
  $* <'print $leaf([dir_path] a/b/c, [dir_path] a)'      >"b/c$s"    : sub-dir-path
  $* <'print $leaf([paths] a/b/c a/b/e, [dir_path] a/b)' >"c e"      : sub-paths
  $* <'print $leaf([dir_paths] a/b/c, [dir_path] a/b)'   >"c$s"      : sub-dir-paths
  $* <'print $path.leaf(a/b c/d/)'                       >"b d/"     : dir-names
  $* <'print $path.leaf(a/b/c a/b/d/, [dir_path] a)'     >"b/c b/d/" : sub-dir-names

  : not-prefix
  :
  $* <'print $leaf([path] a/b/c, [dir_path] a/d)' 2>>"EOE" != 0
  error: 'a/d$s' is not a prefix of 'a/b/c'
    <stdin>:1:8: info: while calling leaf\(path, dir_path\)
  EOE
}

: relative
:
{
  $* <'print $relative([path] a/b/c, [dir_path] a/x/y)' >"..$s..$(s)b/c" : basics
}

: extension
:
{
  $* <'print $extension([path] a.c)'        >"c"      : path
  $* <'print $extension([dir_path] a.tmp/)' >"tmp"    : dir_path
  $* <'print $path.extension(a.c)'          >"c"      : untyped
  $* <'print $path.extension(a)'            >"[null]" : null
}

: combined
:
{
  mkdir -p a/b;
  touch a/b/c.t.cpp;
  $* <<EOI >>/EOO
  t = $src_base/a/b/c.t.cpp
  d = $path.leaf($path.directory($t), $src_base)
  n = $path.base($path.base($path.leaf($t)))
  print $d/exe{$n}
  print $d/{+$n*.cpp}
  EOI
  a/b/exe{c}
  a/b/c.t.cpp
  EOO
}

: sort
:
{
  $* <'print $sort([paths] a c b a)'        >'a a b c' : basics
  $* <'print $sort([paths] a c b a, dedup)' >'a b c'   : dedup

  : icase
  :
  if $windows
  {
    $* <'print $sort([paths] a C B a)' >'a a B C'
  }
}

: size
:
{
  $* <'print $size([path] abc)' >'3' : basics
  $* <'print $size([path] )'    >'0' : zero

  $* <'print $size([dir_path] abc)'  >'3' : dir-basics
  $* <'print $size([dir_path] abc/)' >'3' : dir-separator
  $* <'print $size([dir_path] )'     >'0' : dir-zero
}

: find
:
{
  $* <'print $find([paths] x y z, y)' >'true'  : basics-true
  $* <'print $find([paths] x y z, a)' >'false' : basics-false
}

: find_index
:
{
  $* <'print $find_index([dir_paths] x y z, y)' >'1' : basics-true
  $* <'print $find_index([dir_paths] x y z, a)' >'3' : basics-false
}

: invalid-path
:
p = ($posix ? /../foo : 'c:/../foo');
$* <"\$path.normalize\('$p')" 2>>"EOE" != 0
error: invalid path: '$p'
  <stdin>:1:2: info: while calling path.normalize\(<untyped>\)
EOE

: path-match
:
{
  : string
  :
  : Test overloads for at least one of the first two arguments being of the
  : string type.
  :
  {
    : string-string
    :
    $* <'print $path.match([string] "b", [string] "b*")' >'true'

    : untyped-string
    :
    $* <'print $path.match("b", [string] "b*")' >'true'

    : string-untyped
    :
    $* <'print $path.match([string] "b", "b*")' >'true'

    : path-string
    :
    $* <'print $match([path] "b", [string] "b*")' >'true'
  }

  : path
  :
  : Test overloads for at least one of the first two arguments being of the
  : path type.
  :
  {
    : path-path
    :
    $* <'print $match([path] "a/b", [path] "b**")' >'true'

    : path-untyped-untyped
    :
    $* <'print $match([path] "a/b", "b**", "$src_base")' >'true'

    : untyped-path
    :
    $* <'print $match("a/b", [path] "b**")' >'true'

    : untyped-path-dir
    :
    $* <'print $match("a/b", [path] "b**", $src_base)' >'true'

    : path-untyped
    :
    $* <'print $match([path] "a/b", "b**")' >'true'
  }

  : untyped
  :
  : Test overloads for the first two arguments being untyped.
  :
  {
    : converted-to-strings
    :
    $* <'print $path.match("b", "b**")' >'true'

    : converted-to-paths-due-to
    {
      : pattern
      :
      $* <'print $path.match("a/b/", "b**/")' >'true'

      : entry
      :
      $* <'print $path.match("a/b", "b**")' >'true'

      : start-dir
      :
      $* <'print $path.match("", "s***/", "$src_base")' >'true'
    }
  }
}
