# -*- tcl -*-
# Tests for the find function.
#
# Sourcing this file into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
# Copyright (c) 2007 by Andreas Kupries <andreas_kupries@users.sourceforge.net>
# All rights reserved.
#
# RCS: @(#) $Id: traverse.test,v 1.3 2012/08/29 20:42:19 andreas_kupries Exp $

# -------------------------------------------------------------------------

source [file join \
	[file dirname [file dirname [file join [pwd] [info script]]]] \
	devtools testutilities.tcl]

testsNeedTcl     8.3
testsNeedTcltest 2.1

support {
    use      control/control.tcl control
    use      snit/snit.tcl       snit

    useLocalFile find.setup
}
testing {
    useLocal traverse.tcl        fileutil::traverse
}

# -------------------------------------------------------------------------
# Filters commands to record which callbacks were run.

proc rec {x} {
    lappend ::rec $x
    return 1
}

proc recx {args} {
    lappend ::rec $args
    return
}

# -------------------------------------------------------------------------

test traverse-1.0.0 {Traverse result, circular links, unix} -setup {
    f_setupcircle
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints unix -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}] \
	       [tempPath {find 1/find 2/file* 2}]]

test traverse-1.0.1 {Traverse result, circular links, windows, 8.4+} -setup {
    f_setupcircle
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints {win tcl8.4plus} -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}]]

test traverse-1.0.2 {Traverse result, unix} -setup {
    f_setup
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints unix -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file* 2}]]

test traverse-1.0.3 {Traverse result, windows} -setup {
    f_setup
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints win -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}]]

# Find has to skip '{file 3}', in the sense that the path should be in
# the output, but it cannot be expanded further, being a broken
# link. Two tests, one for all versions of Tcl (8.2+), but only unix,
# and one for windows, restricted to Tcl 8.4+.

test traverse-1.0.4 {Traverse result, broken links, unix} -setup {
    f_setupbroken
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints unix -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}] \
	       [tempPath {find 1/find 2/file* 2}]]

test traverse-1.0.5 {Traverse result, broken links, windows, 8.4+} -setup {
    f_setupbroken
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints {win tcl8.4plus} -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}]]


test traverse-1.0.6 {Traverse result, circular links to base, unix} -setup {
    f_setupcircle2
    set t [fileutil::traverse %AUTO% [tempPath {find 1}]]
} -constraints unix -body {
    lsort [$t files]
} -cleanup {
    $t destroy
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}] \
	       [tempPath {find 1/find 2/file* 2}]]

# -------------------------------------------------------------------------

test traverse-1.1.0 {Traverse filter execution, circular links, unix} -setup {
    f_setupcircle
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -filter ::rec]
} -constraints unix -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}] \
	       [tempPath {find 1/find 2/file* 2}]]

test traverse-1.1.1 {Traverse filter execution, circular links, windows, 8.4+} -setup {
    f_setupcircle
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -filter ::rec]
} -constraints {win tcl8.4plus} -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file 3}]]

test traverse-1.1.2 {Traverse filter execution, unix} -setup {
    f_setup
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -filter ::rec]
} -constraints unix -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}] \
	       [tempPath {find 1/find 2/file* 2}]]

test traverse-1.1.3 {Traverse filter execution, windows} -setup {
    f_setup
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -filter ::rec]
} -constraints win -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/file [1]}] \
	       [tempPath {find 1/find 2}]]

# -------------------------------------------------------------------------

test traverse-1.2.0 {Traverse prefilter execution, unix} -setup {
    f_setupcircle
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -prefilter ::rec]
} -constraints unix -body {
    $t files
    lsort $rec
    # Note: The link 'file 3' is _not_ run through the pre-filter,
    # because it is filtered out as already seen before it comes to
    # the pre-filter stage.
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/find 2}]]

test traverse-1.2.1 {Traverse prefilter execution, windows, 8.4+} -setup {
    f_setupcircle
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -prefilter ::rec]
} -constraints {win tcl8.4plus} -body {
    $t files
    lsort $rec
    # Note: The link 'file 3' is _not_ run through the pre-filter,
    # because it is filtered out as already seen before it comes to
    # the pre-filter stage.
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/find 2}]]

test traverse-1.2.2 {Traverse prefilter execution, all platforms} -setup {
    f_setup
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath {find 1}] -prefilter ::rec]
} -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanup
} -result [list \
	       [tempPath {find 1}] \
	       [tempPath {find 1/find 2}]]

# -------------------------------------------------------------------------

test traverse-1.3.0 {Traverse error execution, unix, 8.4+} -setup {
    f_setupnostat
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath find3] -errorcmd ::recx]
} -constraints {unix tcl8.4plus} -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanupnostat
} -result {}

test traverse-1.3.1 {Traverse error execution, unix, 8.3} -setup {
    f_setupnostat
    set rec {}
    set t [fileutil::traverse %AUTO% [tempPath find3] -errorcmd ::recx]
} -constraints {unix tcl8.3only} -body {
    $t files
    lsort $rec
} -cleanup {
    $t destroy
    unset rec
    f_cleanupnostat
} -result [list [list [tempPath find3/find4] {Inacessible directory}]]

# traverse 1.3.x - error callback, all platforms - Not possible. We have
# no win32 setup code for non-readable/non-accessible directories.

# -------------------------------------------------------------------------

f_cleanall
testsuiteCleanup
return
