sl@0: # This file contains tests for the pkg_mkIndex command. sl@0: # Note that the tests are limited to Tcl scripts only, there are no shared sl@0: # libraries against which to test. sl@0: # sl@0: # Sourcing this file into Tcl runs the tests and generates output for sl@0: # errors. No output means no errors were found. sl@0: # sl@0: # Copyright (c) 1998-1999 by Scriptics Corporation. sl@0: # All rights reserved. sl@0: # sl@0: # RCS: @(#) $Id: pkgMkIndex.test,v 1.23.2.1 2003/07/24 08:23:39 rmax Exp $ sl@0: sl@0: if {[lsearch [namespace children] ::tcltest] == -1} { sl@0: package require tcltest 2 sl@0: namespace import -force ::tcltest::* sl@0: } sl@0: sl@0: set fullPkgPath [makeDirectory pkg] sl@0: sl@0: sl@0: namespace eval pkgtest { sl@0: # Namespace for procs we can discard sl@0: } sl@0: sl@0: # pkgtest::parseArgs -- sl@0: # sl@0: # Parse an argument list. sl@0: # sl@0: # Arguments: sl@0: # (optional) arguments starting with a dash are collected sl@0: # as options to pkg_mkIndex and passed to pkg_mkIndex. sl@0: # dirPath the directory to index sl@0: # pattern0 pattern to index sl@0: # ... pattern to index sl@0: # patternN pattern to index sl@0: # sl@0: # Results: sl@0: # Returns a three element list: sl@0: # 0: the options sl@0: # 1: the directory to index sl@0: # 2: the patterns list sl@0: sl@0: proc pkgtest::parseArgs { args } { sl@0: set options "" sl@0: sl@0: set argc [llength $args] sl@0: for {set iarg 0} {$iarg < $argc} {incr iarg} { sl@0: set a [lindex $args $iarg] sl@0: if {[regexp {^-} $a]} { sl@0: lappend options $a sl@0: if {[string compare -load $a] == 0} { sl@0: incr iarg sl@0: lappend options [lindex $args $iarg] sl@0: } sl@0: } else { sl@0: break sl@0: } sl@0: } sl@0: sl@0: set dirPath [lindex $args $iarg] sl@0: incr iarg sl@0: set patternList [lrange $args $iarg end] sl@0: sl@0: return [list $options $dirPath $patternList] sl@0: } sl@0: sl@0: # pkgtest::parseIndex -- sl@0: # sl@0: # Loads a pkgIndex.tcl file, records all the calls to "package ifneeded". sl@0: # sl@0: # Arguments: sl@0: # filePath path to the pkgIndex.tcl file. sl@0: # sl@0: # Results: sl@0: # Returns a list, in "array set/get" format, where the keys are the package sl@0: # name and version (in the form "$name:$version"), and the values the rest sl@0: # of the command line. sl@0: sl@0: proc pkgtest::parseIndex { filePath } { sl@0: # create a slave interpreter, where we override "package ifneeded" sl@0: sl@0: set slave [interp create] sl@0: if {[catch { sl@0: $slave eval { sl@0: rename package package_original sl@0: proc package { args } { sl@0: if {[string compare [lindex $args 0] ifneeded] == 0} { sl@0: set pkg [lindex $args 1] sl@0: set ver [lindex $args 2] sl@0: set ::PKGS($pkg:$ver) [lindex $args 3] sl@0: } else { sl@0: return [eval package_original $args] sl@0: } sl@0: } sl@0: array set ::PKGS {} sl@0: } sl@0: sl@0: set dir [file dirname $filePath] sl@0: $slave eval {set curdir [pwd]} sl@0: $slave eval [list cd $dir] sl@0: $slave eval [list set dir $dir] sl@0: $slave eval [list source [file tail $filePath]] sl@0: $slave eval {cd $curdir} sl@0: sl@0: # Create the list in sorted order, so that we don't get spurious sl@0: # errors because the order has changed. sl@0: sl@0: array set P {} sl@0: foreach {k v} [$slave eval {array get ::PKGS}] { sl@0: set P($k) $v sl@0: } sl@0: sl@0: set PKGS "" sl@0: foreach k [lsort [array names P]] { sl@0: lappend PKGS $k $P($k) sl@0: } sl@0: } err]} { sl@0: set ei $::errorInfo sl@0: set ec $::errorCode sl@0: sl@0: catch {interp delete $slave} sl@0: sl@0: error $ei $ec sl@0: } sl@0: sl@0: interp delete $slave sl@0: sl@0: return $PKGS sl@0: } sl@0: sl@0: # pkgtest::createIndex -- sl@0: # sl@0: # Runs pkg_mkIndex for the given directory and set of patterns. sl@0: # This procedure deletes any pkgIndex.tcl file in the target directory, sl@0: # then runs pkg_mkIndex. sl@0: # sl@0: # Arguments: sl@0: # (optional) arguments starting with a dash are collected sl@0: # as options to pkg_mkIndex and passed to pkg_mkIndex. sl@0: # dirPath the directory to index sl@0: # pattern0 pattern to index sl@0: # ... pattern to index sl@0: # patternN pattern to index sl@0: # sl@0: # Results: sl@0: # Returns a two element list: sl@0: # 0: 1 if the procedure encountered an error, 0 otherwise. sl@0: # 1: the error result if element 0 was 1 sl@0: sl@0: proc pkgtest::createIndex { args } { sl@0: set parsed [eval parseArgs $args] sl@0: set options [lindex $parsed 0] sl@0: set dirPath [lindex $parsed 1] sl@0: set patternList [lindex $parsed 2] sl@0: sl@0: file mkdir $dirPath sl@0: sl@0: if {[catch { sl@0: file delete [file join $dirPath pkgIndex.tcl] sl@0: eval pkg_mkIndex $options [list $dirPath] $patternList sl@0: } err]} { sl@0: return [list 1 $err] sl@0: } sl@0: sl@0: return [list 0 {}] sl@0: } sl@0: sl@0: # makePkgList -- sl@0: # sl@0: # Takes the output of a pkgtest::parseIndex call, filters it and returns a sl@0: # cleaned up list of packages and their actions. sl@0: # sl@0: # Arguments: sl@0: # inList output from a pkgtest::parseIndex. sl@0: # sl@0: # Results: sl@0: # Returns a list of two element lists: sl@0: # 0: the name:version sl@0: # 1: a list describing the package. sl@0: # For tclPkgSetup packages it consists of: sl@0: # 0: the keyword tclPkgSetup sl@0: # 1: the first file to source, with its exported procedures sl@0: # 2: the second file ... sl@0: # N: the N-1st file ... sl@0: sl@0: proc makePkgList { inList } { sl@0: set pkgList "" sl@0: sl@0: foreach {k v} $inList { sl@0: switch [lindex $v 0] { sl@0: tclPkgSetup { sl@0: set l tclPkgSetup sl@0: foreach s [lindex $v 4] { sl@0: lappend l $s sl@0: } sl@0: } sl@0: sl@0: source { sl@0: set l $v sl@0: } sl@0: sl@0: default { sl@0: error "can't handle $k $v" sl@0: } sl@0: } sl@0: sl@0: lappend pkgList [list $k $l] sl@0: } sl@0: sl@0: return $pkgList sl@0: } sl@0: sl@0: # pkgtest::runIndex -- sl@0: # sl@0: # Runs pkg_mkIndex, parses the generated index file. sl@0: # sl@0: # Arguments: sl@0: # (optional) arguments starting with a dash are collected sl@0: # as options to pkg_mkIndex and passed to pkg_mkIndex. sl@0: # dirPath the directory to index sl@0: # pattern0 pattern to index sl@0: # ... pattern to index sl@0: # patternN pattern to index sl@0: # sl@0: # Results: sl@0: # Returns a two element list: sl@0: # 0: 1 if the procedure encountered an error, 0 otherwise. sl@0: # 1: if no error, this is the parsed generated index file, in the format sl@0: # returned by pkgtest::parseIndex. sl@0: # If error, this is the error result. sl@0: sl@0: proc pkgtest::runCreatedIndex {rv args} { sl@0: if {[lindex $rv 0] == 0} { sl@0: set parsed [eval parseArgs $args] sl@0: set dirPath [lindex $parsed 1] sl@0: set idxFile [file join $dirPath pkgIndex.tcl] sl@0: sl@0: if {[catch { sl@0: set result [list 0 [makePkgList [parseIndex $idxFile]]] sl@0: } err]} { sl@0: set result [list 1 $err] sl@0: } sl@0: file delete $idxFile sl@0: } else { sl@0: set result $rv sl@0: } sl@0: sl@0: return $result sl@0: } sl@0: proc pkgtest::runIndex { args } { sl@0: set rv [eval createIndex $args] sl@0: return [eval [list runCreatedIndex $rv] $args] sl@0: } sl@0: sl@0: # If there is no match to the patterns, make sure the directory hasn't sl@0: # changed on us sl@0: sl@0: test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} { sl@0: list [pkgtest::runIndex -lazy $fullPkgPath nomatch.tcl] [pwd] sl@0: } [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]] sl@0: sl@0: makeFile { sl@0: # This is a simple package, just to check basic functionality. sl@0: package provide simple 1.0 sl@0: namespace eval simple { sl@0: namespace export lower upper sl@0: } sl@0: proc simple::lower { stg } { sl@0: return [string tolower $stg] sl@0: } sl@0: proc simple::upper { stg } { sl@0: return [string toupper $stg] sl@0: } sl@0: } [file join pkg simple.tcl] sl@0: sl@0: test pkgMkIndex-2.1 {simple package} { sl@0: pkgtest::runIndex -lazy $fullPkgPath simple.tcl sl@0: } {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}} sl@0: sl@0: test pkgMkIndex-2.2 {simple package - use -direct} { sl@0: pkgtest::runIndex -direct $fullPkgPath simple.tcl sl@0: } "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" sl@0: sl@0: test pkgMkIndex-2.3 {simple package - direct loading is default} { sl@0: pkgtest::runIndex $fullPkgPath simple.tcl sl@0: } "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" sl@0: sl@0: test pkgMkIndex-2.4 {simple package - use -verbose} -body { sl@0: pkgtest::runIndex -verbose $fullPkgPath simple.tcl sl@0: } -result "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" \ sl@0: -errorOutput {successful sourcing of simple.tcl sl@0: packages provided were {simple 1.0} sl@0: processed simple.tcl sl@0: } sl@0: sl@0: removeFile [file join pkg simple.tcl] sl@0: sl@0: makeFile { sl@0: # Contains global symbols, used to check that they don't have a leading :: sl@0: package provide global 1.0 sl@0: proc global_lower { stg } { sl@0: return [string tolower $stg] sl@0: } sl@0: proc global_upper { stg } { sl@0: return [string toupper $stg] sl@0: } sl@0: } [file join pkg global.tcl] sl@0: sl@0: test pkgMkIndex-3.1 {simple package with global symbols} { sl@0: pkgtest::runIndex -lazy $fullPkgPath global.tcl sl@0: } {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}} sl@0: sl@0: removeFile [file join pkg global.tcl] sl@0: sl@0: makeFile { sl@0: # This package is required by pkg1. sl@0: # This package is split into two files, to test packages that are split sl@0: # over multiple files. sl@0: package provide pkg2 1.0 sl@0: namespace eval pkg2 { sl@0: namespace export p2-1 sl@0: } sl@0: proc pkg2::p2-1 { num } { sl@0: return [expr $num * 2] sl@0: } sl@0: } [file join pkg pkg2_a.tcl] sl@0: sl@0: makeFile { sl@0: # This package is required by pkg1. sl@0: # This package is split into two files, to test packages that are split sl@0: # over multiple files. sl@0: package provide pkg2 1.0 sl@0: namespace eval pkg2 { sl@0: namespace export p2-2 sl@0: } sl@0: proc pkg2::p2-2 { num } { sl@0: return [expr $num * 3] sl@0: } sl@0: } [file join pkg pkg2_b.tcl] sl@0: sl@0: test pkgMkIndex-4.1 {split package} { sl@0: pkgtest::runIndex -lazy $fullPkgPath pkg2_a.tcl pkg2_b.tcl sl@0: } {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}} sl@0: sl@0: test pkgMkIndex-4.2 {split package - direct loading} { sl@0: pkgtest::runIndex -direct $fullPkgPath pkg2_a.tcl pkg2_b.tcl sl@0: } "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]] sl@0: [list source [file join $fullPkgPath pkg2_b.tcl]]}}}" sl@0: sl@0: # Add the direct1 directory to auto_path, so that the direct1 package sl@0: # can be found. sl@0: set direct1 [makeDirectory direct1] sl@0: lappend auto_path $direct1 sl@0: makeFile { sl@0: # This is referenced by pkgIndex.tcl as a -direct script. sl@0: package provide direct1 1.0 sl@0: namespace eval direct1 { sl@0: namespace export pd1 pd2 sl@0: } sl@0: proc direct1::pd1 { stg } { sl@0: return [string tolower $stg] sl@0: } sl@0: proc direct1::pd2 { stg } { sl@0: return [string toupper $stg] sl@0: } sl@0: } [file join direct1 direct1.tcl] sl@0: pkg_mkIndex -direct $direct1 direct1.tcl sl@0: sl@0: makeFile { sl@0: # Does a package require of direct1, whose pkgIndex.tcl entry sl@0: # is created above with option -direct. This tests that pkg_mkIndex sl@0: # can handle code that is sourced in pkgIndex.tcl files. sl@0: package require direct1 sl@0: package provide std 1.0 sl@0: namespace eval std { sl@0: namespace export p1 p2 sl@0: } sl@0: proc std::p1 { stg } { sl@0: return [string tolower $stg] sl@0: } sl@0: proc std::p2 { stg } { sl@0: return [string toupper $stg] sl@0: } sl@0: } [file join pkg std.tcl] sl@0: sl@0: test pkgMkIndex-5.1 {requires -direct package} { sl@0: pkgtest::runIndex -lazy $fullPkgPath std.tcl sl@0: } {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}} sl@0: sl@0: removeFile [file join direct1 direct1.tcl] sl@0: file delete [file join $direct1 pkgIndex.tcl] sl@0: removeDirectory direct1 sl@0: removeFile [file join pkg std.tcl] sl@0: sl@0: makeFile { sl@0: # This package requires pkg3, but it does sl@0: # not use any of pkg3's procs in the code that is executed by the file sl@0: # (i.e. references to pkg3's procs are in the proc bodies only). sl@0: package require pkg3 1.0 sl@0: package provide pkg1 1.0 sl@0: namespace eval pkg1 { sl@0: namespace export p1-1 p1-2 sl@0: } sl@0: proc pkg1::p1-1 { num } { sl@0: return [pkg3::p3-1 $num] sl@0: } sl@0: proc pkg1::p1-2 { num } { sl@0: return [pkg3::p3-2 $num] sl@0: } sl@0: } [file join pkg pkg1.tcl] sl@0: sl@0: makeFile { sl@0: package provide pkg3 1.0 sl@0: namespace eval pkg3 { sl@0: namespace export p3-1 p3-2 sl@0: } sl@0: proc pkg3::p3-1 { num } { sl@0: return {[expr $num * 2]} sl@0: } sl@0: proc pkg3::p3-2 { num } { sl@0: return {[expr $num * 3]} sl@0: } sl@0: } [file join pkg pkg3.tcl] sl@0: sl@0: test pkgMkIndex-6.1 {pkg1 requires pkg3} { sl@0: pkgtest::runIndex -lazy $fullPkgPath pkg1.tcl pkg3.tcl sl@0: } {0 {{pkg1:1.0 {tclPkgSetup {pkg1.tcl source {::pkg1::p1-1 ::pkg1::p1-2}}}} {pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}}}} sl@0: sl@0: test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} { sl@0: pkgtest::runIndex -direct $fullPkgPath pkg1.tcl pkg3.tcl sl@0: } "0 {{pkg1:1.0 {[list source [file join $fullPkgPath pkg1.tcl]]}} {pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}}}" sl@0: sl@0: removeFile [file join pkg pkg1.tcl] sl@0: sl@0: makeFile { sl@0: # This package requires pkg3, and it calls sl@0: # a pkg3 proc in the code that is executed by the file sl@0: package require pkg3 1.0 sl@0: package provide pkg4 1.0 sl@0: namespace eval pkg4 { sl@0: namespace export p4-1 p4-2 sl@0: variable m2 [pkg3::p3-1 10] sl@0: } sl@0: proc pkg4::p4-1 { num } { sl@0: variable m2 sl@0: return [expr {$m2 * $num}] sl@0: } sl@0: proc pkg4::p4-2 { num } { sl@0: return [pkg3::p3-2 $num] sl@0: } sl@0: } [file join pkg pkg4.tcl] sl@0: sl@0: test pkgMkIndex-7.1 {pkg4 uses pkg3} { sl@0: pkgtest::runIndex -lazy $fullPkgPath pkg4.tcl pkg3.tcl sl@0: } {0 {{pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}} {pkg4:1.0 {tclPkgSetup {pkg4.tcl source {::pkg4::p4-1 ::pkg4::p4-2}}}}}} sl@0: sl@0: test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} { sl@0: pkgtest::runIndex -direct $fullPkgPath pkg4.tcl pkg3.tcl sl@0: } "0 {{pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}} {pkg4:1.0 {[list source [file join $fullPkgPath pkg4.tcl]]}}}" sl@0: sl@0: removeFile [file join pkg pkg4.tcl] sl@0: removeFile [file join pkg pkg3.tcl] sl@0: sl@0: makeFile { sl@0: # This package requires pkg2, and it calls sl@0: # a pkg2 proc in the code that is executed by the file. sl@0: # Pkg2 is a split package. sl@0: package require pkg2 1.0 sl@0: package provide pkg5 1.0 sl@0: namespace eval pkg5 { sl@0: namespace export p5-1 p5-2 sl@0: variable m2 [pkg2::p2-1 10] sl@0: variable m3 [pkg2::p2-2 10] sl@0: } sl@0: proc pkg5::p5-1 { num } { sl@0: variable m2 sl@0: return [expr {$m2 * $num}] sl@0: } sl@0: proc pkg5::p5-2 { num } { sl@0: variable m2 sl@0: return [expr {$m2 * $num}] sl@0: } sl@0: } [file join pkg pkg5.tcl] sl@0: sl@0: test pkgMkIndex-8.1 {pkg5 uses pkg2} { sl@0: pkgtest::runIndex -lazy $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl sl@0: } {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}} {pkg5:1.0 {tclPkgSetup {pkg5.tcl source {::pkg5::p5-1 ::pkg5::p5-2}}}}}} sl@0: sl@0: test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} { sl@0: pkgtest::runIndex -direct $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl sl@0: } "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]] sl@0: [list source [file join $fullPkgPath pkg2_b.tcl]]}} {pkg5:1.0 {[list source [file join $fullPkgPath pkg5.tcl]]}}}" sl@0: sl@0: removeFile [file join pkg pkg5.tcl] sl@0: removeFile [file join pkg pkg2_a.tcl] sl@0: removeFile [file join pkg pkg2_b.tcl] sl@0: sl@0: makeFile { sl@0: # This package requires circ2, and circ2 sl@0: # requires circ3, which in turn requires circ1. sl@0: # In case of cirularities, pkg_mkIndex should give up when it gets stuck. sl@0: package require circ2 1.0 sl@0: package provide circ1 1.0 sl@0: namespace eval circ1 { sl@0: namespace export c1-1 c1-2 c1-3 c1-4 sl@0: } sl@0: proc circ1::c1-1 { num } { sl@0: return [circ2::c2-1 $num] sl@0: } sl@0: proc circ1::c1-2 { num } { sl@0: return [circ2::c2-2 $num] sl@0: } sl@0: proc circ1::c1-3 {} { sl@0: return 10 sl@0: } sl@0: proc circ1::c1-4 {} { sl@0: return 20 sl@0: } sl@0: } [file join pkg circ1.tcl] sl@0: sl@0: makeFile { sl@0: # This package is required by circ1, and sl@0: # requires circ3. Circ3, in turn, requires circ1 to give us a circularity. sl@0: package require circ3 1.0 sl@0: package provide circ2 1.0 sl@0: namespace eval circ2 { sl@0: namespace export c2-1 c2-2 sl@0: } sl@0: proc circ2::c2-1 { num } { sl@0: return [expr $num * [circ3::c3-1]] sl@0: } sl@0: proc circ2::c2-2 { num } { sl@0: return [expr $num * [circ3::c3-2]] sl@0: } sl@0: } [file join pkg circ2.tcl] sl@0: sl@0: makeFile { sl@0: # This package is required by circ2, and in sl@0: # turn requires circ1. This closes the circularity. sl@0: package require circ1 1.0 sl@0: package provide circ3 1.0 sl@0: namespace eval circ3 { sl@0: namespace export c3-1 c3-4 sl@0: } sl@0: proc circ3::c3-1 {} { sl@0: return [circ1::c1-3] sl@0: } sl@0: proc circ3::c3-2 {} { sl@0: return [circ1::c1-4] sl@0: } sl@0: } [file join pkg circ3.tcl] sl@0: sl@0: test pkgMkIndex-9.1 {circular packages} { sl@0: pkgtest::runIndex -lazy $fullPkgPath circ1.tcl circ2.tcl circ3.tcl sl@0: } {0 {{circ1:1.0 {tclPkgSetup {circ1.tcl source {::circ1::c1-1 ::circ1::c1-2 ::circ1::c1-3 ::circ1::c1-4}}}} {circ2:1.0 {tclPkgSetup {circ2.tcl source {::circ2::c2-1 ::circ2::c2-2}}}} {circ3:1.0 {tclPkgSetup {circ3.tcl source ::circ3::c3-1}}}}} sl@0: sl@0: removeFile [file join pkg circ1.tcl] sl@0: removeFile [file join pkg circ2.tcl] sl@0: removeFile [file join pkg circ3.tcl] sl@0: sl@0: # Some tests require the existence of one of the DLLs in the dltest directory sl@0: set x [file join [file dirname [info nameofexecutable]] dltest \ sl@0: pkga[info sharedlibextension]] sl@0: set dll "[file tail $x]Required" sl@0: ::tcltest::testConstraint $dll [file exists $x] sl@0: sl@0: if {[testConstraint $dll]} { sl@0: makeFile { sl@0: # This package provides Pkga, which is also provided by a DLL. sl@0: package provide Pkga 1.0 sl@0: proc pkga_neq { x } { sl@0: return [expr {! [pkgq_eq $x]}] sl@0: } sl@0: } [file join pkg pkga.tcl] sl@0: file copy -force $x $fullPkgPath sl@0: } sl@0: testConstraint exec [llength [info commands ::exec]] sl@0: sl@0: test pkgMkIndex-10.1 {package in DLL and script} [list exec $dll] { sl@0: # Do all [load]ing of shared libraries in another process, so sl@0: # we can delete the file and not get stuck because we're holding sl@0: # a reference to it. sl@0: set cmd [list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl] sl@0: exec [interpreter] << $cmd sl@0: pkgtest::runCreatedIndex {0 {}} -lazy $fullPkgPath pkga[info sharedlibextension] pkga.tcl sl@0: } "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}" sl@0: test pkgMkIndex-10.2 {package in DLL hidden by -load} [list exec $dll] { sl@0: # Do all [load]ing of shared libraries in another process, so sl@0: # we can delete the file and not get stuck because we're holding sl@0: # a reference to it. sl@0: # sl@0: # This test depends on context from prior test, so repeat it. sl@0: set script "[list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]\n" sl@0: append script \ sl@0: "[list pkg_mkIndex -lazy -load Pkg* $fullPkgPath [file tail $x]]" sl@0: exec [interpreter] << $script sl@0: pkgtest::runCreatedIndex {0 {}} -lazy -load Pkg* -- $fullPkgPath pkga[info sharedlibextension] sl@0: } {0 {}} sl@0: sl@0: if {[testConstraint $dll]} { sl@0: file delete -force [file join $fullPkgPath [file tail $x]] sl@0: removeFile [file join pkg pkga.tcl] sl@0: } sl@0: sl@0: # Tolerate "namespace import" at the global scope sl@0: sl@0: makeFile { sl@0: package provide fubar 1.0 sl@0: namespace eval ::fubar:: { sl@0: # sl@0: # export only public functions. sl@0: # sl@0: namespace export {[a-z]*} sl@0: } sl@0: proc ::fubar::foo {bar} { sl@0: puts "$bar" sl@0: return true sl@0: } sl@0: namespace import ::fubar::foo sl@0: } [file join pkg import.tcl] sl@0: sl@0: test pkgMkIndex-11.1 {conflicting namespace imports} { sl@0: pkgtest::runIndex -lazy $fullPkgPath import.tcl sl@0: } {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}} sl@0: sl@0: removeFile [file join pkg import.tcl] sl@0: sl@0: # Verify that the auto load list generated is correct even when there sl@0: # is a proc name conflict between two namespaces (ie, ::foo::baz and sl@0: # ::bar::baz) sl@0: sl@0: makeFile { sl@0: package provide football 1.0 sl@0: namespace eval ::pro:: { sl@0: # sl@0: # export only public functions. sl@0: # sl@0: namespace export {[a-z]*} sl@0: } sl@0: namespace eval ::college:: { sl@0: # sl@0: # export only public functions. sl@0: # sl@0: namespace export {[a-z]*} sl@0: } sl@0: proc ::pro::team {} { sl@0: puts "go packers!" sl@0: return true sl@0: } sl@0: proc ::college::team {} { sl@0: puts "go badgers!" sl@0: return true sl@0: } sl@0: } [file join pkg samename.tcl] sl@0: sl@0: test pkgMkIndex-12.1 {same name procs in different namespace} { sl@0: pkgtest::runIndex -lazy $fullPkgPath samename.tcl sl@0: } {0 {{football:1.0 {tclPkgSetup {samename.tcl source {::college::team ::pro::team}}}}}} sl@0: sl@0: removeFile [file join pkg samename.tcl] sl@0: sl@0: # Proc names with embedded spaces are properly listed (ie, correct number of sl@0: # braces) in result sl@0: makeFile { sl@0: package provide spacename 1.0 sl@0: proc {a b} {} {} sl@0: proc {c d} {} {} sl@0: } [file join pkg spacename.tcl] sl@0: sl@0: test pkgMkIndex-13.1 {proc names with embedded spaces} { sl@0: pkgtest::runIndex -lazy $fullPkgPath spacename.tcl sl@0: } {0 {{spacename:1.0 {tclPkgSetup {spacename.tcl source {{a b} {c d}}}}}}} sl@0: sl@0: removeFile [file join pkg spacename.tcl] sl@0: sl@0: # Test the pkg_compareExtension helper function sl@0: test pkgMkIndex-14.1 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo.so .so sl@0: } 1 sl@0: test pkgMkIndex-14.2 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo.so.bar .so sl@0: } 0 sl@0: test pkgMkIndex-14.3 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo.so.1 .so sl@0: } 1 sl@0: test pkgMkIndex-14.4 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo.so.1.2 .so sl@0: } 1 sl@0: test pkgMkIndex-14.5 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo .so sl@0: } 0 sl@0: test pkgMkIndex-14.6 {pkg_compareExtension} {unixOnly} { sl@0: pkg_compareExtension foo.so.1.2.bar .so sl@0: } 0 sl@0: sl@0: # cleanup sl@0: sl@0: removeDirectory pkg sl@0: sl@0: namespace delete pkgtest sl@0: ::tcltest::cleanupTests sl@0: return sl@0: