#! /bin/sh
# If executed as a shell script, the next line replaces the shell \
exec tclsh "$0" ${1+"$@"}

#
# DETERMINE EXECUTION ENVIRONMENT
#

# Check whether this script was called from a master test script
# (e.g. by [runAllTests]).
set CALLED_FROM_MASTER_TEST [info exists ::env(TCLTEST_MASTER_SCRIPT)]

proc getScriptDir {} {
	set scriptname [info script]
	if {$scriptname eq ""} {
		return -code error "Called [info level 0] outside the active invocation of a script."
	}
	return [file dirname [file normalize $scriptname]]
}


# determine directory names and cd into test dir
set Dir(test) [getScriptDir]
set Dir(install) [file dirname $Dir(test)]
cd $Dir(test)

# determine package version
if {[file isdir [file join $Dir(install) .hg]]} {
	# we're in a development tree (mercurial repository)
	set pkgVersion 0.0.0
} else {
	# we're in an installed distribution
	if {! [regexp {\d+\.\d+[.ab]\d+$} $Dir(install) pkgVersion]} {
		return -code error "failed to determine package version from installation directory $Dir(install)"
	}
}

#
# LOAD AND CONFIGURE TEST HARNESS
#

package require tcltest 2.2
namespace import -force ::tcltest::*
if {! $CALLED_FROM_MASTER_TEST} {
	tcltest::configure -verbose {body pass error}
	if {$argc > 0} {
		# pass command line arguments to tcltest
		eval tcltest::configure $argv
	}
}
testConstraint no_initial_tk [catch {package present Tk}]

# Testing on macOS is promoted, but the error returned by [init]
# interferes. Therefore we disguise Darwin for this test.
if {$tcl_platform(os) eq "Darwin"} {
	proc restoreDarwin {args} {
		set ::tcl_platform(os) "Darwin"
		trace remove execution tcltest::cleanupTests leave restoreDarwin
		rename restoreDarwin {}
	}
	set tcl_platform(os) "darwin_disguised_by_windetect_test"
	trace add execution tcltest::cleanupTests leave restoreDarwin
}

#
# ISSUE NOTIFICATION AND SYSTEM PROPERTIES
#
puts [outputChannel] \
"\n*\n* This test script only exerices the package's programming interface. The \
\n* correct operation of the detection functionality while tracking windows in\
\n* a GUI is exercised by the test script of the related package wintrackgui.\n*\n"

# Output relevant system properties for issue reporting
array set platform [array get tcl_platform]
unset -nocomplain platform(user) platform(byteOrder) platform(machine) platform(pathSeparator) platform(pointerSize) platform(wordSize)
puts "Execution environment\n---------------------"
puts "Tcl patchLevel: $tcl_patchLevel"
parray platform
puts ""
unset platform


#
# START TESTS
#

# Prevent that we inadvertently load a version of windetect
# installed elsewhere.
package forget windetect
set auto_path_sav $auto_path; set auto_path $Dir(install)

# package-1
#
# REQUIREMENTS
#
test package-1.1 {package require fails if Tk is not loaded} -constraints no_initial_tk -setup {
	set result {}
} -body {
	lappend result [catch {package require -exact windetect $pkgVersion} errMsg]
	lappend result $errMsg
	lappend result [namespace exists ::windetect]
} -cleanup {
	unset result
} -result [list 1 "windetect requires a running Tk application" 0]

test package-1.2 {package require fails with too old Tk version} -constraints no_initial_tk -setup {
	package provide Tk 8.4
	set result {}
} -body {
	lappend result [catch {package require -exact windetect $pkgVersion} errMsg]
	lappend result $errMsg
	lappend result [namespace exists ::windetect]
} -cleanup {
	unset result
	package forget Tk
} -result [list 1 "windetect $pkgVersion requires Tk 8.5 or newer" 0]

#
# Nrs. 1.50 and beyond are used for tests that may be removed in a newer version
# 
# While we can't test on macOS we impersonate it
test package-1.50 {package require fails under macOS} -setup {
	set sav $tcl_platform(os)
	set tcl_platform(os) "Darwin"; # impersonate
} -body {
	lappend result [catch {package require -exact windetect $pkgVersion} errMsg]
	lappend result $errMsg
	lappend result [namespace exists ::windetect]
} -cleanup {
	unset result
	set tcl_platform(os) $sav
	unset sav
} -result [list 1 "windetect $pkgVersion does not support macOS (or OS X / Mac OS X)" 0]


#
# The following tests require Tk 8.5, with the root window withdrawn
#
set auto_path $auto_path_sav
package require Tk 8.5
package forget windetect
set auto_path $Dir(install)

wm withdraw .
update idletasks


test package-2.1 {package require works} -body {
	package require -exact windetect $pkgVersion
} -cleanup {
	namespace delete ::windetect
	package forget windetect
} -result $pkgVersion

test exit-1.1 {leaves no traces behind} -setup {
	package require -exact windetect $pkgVersion
} -body {
	windetect::exit
	list [namespace exists ::windetect] [catch {package present windetect}]
} -result {0 1}

#
# The following tests require the correct loading of the package
#
package require -exact windetect $pkgVersion

test configure-1.1 {complain and make no changes with invalid # args} -body {
	windetect::configure -delay param2 param3
} -result "uneven # arguments" -returnCodes error

test configure-1.2 {complain with invalid arguments} -body {
	windetect::configure -invalidParam
} -result "invalid option \"-invalidParam\"" -returnCodes error

test configure-1.3 {configure returns all settings} -body {
	windetect::configure
} -result {-callback callback.default -delay 50}

test configure-1.4 {configure returns a single specific setting} -body {
	windetect::configure -delay
} -result 50

test configure-1.5 {configure changes a single specific setting} -body {
	windetect::configure -delay 40
	return $::windetect::Windetect(delay)
} -cleanup {
	windetect::configure -delay 50
} -result 40

test detect-1.1 {complain and make no changes with invalid # args} -body {
	windetect::detect param1 param2 param3
} -result "wrong # args: should be \"windetect::detect ?state?\"" -returnCodes error

test detect-1.2 {complain with invalid arguments} -body {
	windetect::detect invalidParam
} -result "invalid value \"invalidParam\" for state" -returnCodes error

test detect-1.3 {return state if no arguments are passed} -body {
	windetect::detect
} -result "off"

test detect-1.4 {activate detection; the callback command is called} -body {
	windetect::detect on
} -cleanup {
	windetect::detect off
} -result "" -output {{} \d+ \d+} -match regexp

#
# END OF TESTS, clean up and show results
#
windetect::exit
tcltest::cleanupTests

# EOF
