sl@0
|
1 |
# This file contains tests for the pkg_mkIndex command.
|
sl@0
|
2 |
# Note that the tests are limited to Tcl scripts only, there are no shared
|
sl@0
|
3 |
# libraries against which to test.
|
sl@0
|
4 |
#
|
sl@0
|
5 |
# Sourcing this file into Tcl runs the tests and generates output for
|
sl@0
|
6 |
# errors. No output means no errors were found.
|
sl@0
|
7 |
#
|
sl@0
|
8 |
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
sl@0
|
9 |
# All rights reserved.
|
sl@0
|
10 |
#
|
sl@0
|
11 |
# RCS: @(#) $Id: pkgMkIndex.test,v 1.23.2.1 2003/07/24 08:23:39 rmax Exp $
|
sl@0
|
12 |
|
sl@0
|
13 |
if {[lsearch [namespace children] ::tcltest] == -1} {
|
sl@0
|
14 |
package require tcltest 2
|
sl@0
|
15 |
namespace import -force ::tcltest::*
|
sl@0
|
16 |
}
|
sl@0
|
17 |
|
sl@0
|
18 |
set fullPkgPath [makeDirectory pkg]
|
sl@0
|
19 |
|
sl@0
|
20 |
|
sl@0
|
21 |
namespace eval pkgtest {
|
sl@0
|
22 |
# Namespace for procs we can discard
|
sl@0
|
23 |
}
|
sl@0
|
24 |
|
sl@0
|
25 |
# pkgtest::parseArgs --
|
sl@0
|
26 |
#
|
sl@0
|
27 |
# Parse an argument list.
|
sl@0
|
28 |
#
|
sl@0
|
29 |
# Arguments:
|
sl@0
|
30 |
# <flags> (optional) arguments starting with a dash are collected
|
sl@0
|
31 |
# as options to pkg_mkIndex and passed to pkg_mkIndex.
|
sl@0
|
32 |
# dirPath the directory to index
|
sl@0
|
33 |
# pattern0 pattern to index
|
sl@0
|
34 |
# ... pattern to index
|
sl@0
|
35 |
# patternN pattern to index
|
sl@0
|
36 |
#
|
sl@0
|
37 |
# Results:
|
sl@0
|
38 |
# Returns a three element list:
|
sl@0
|
39 |
# 0: the options
|
sl@0
|
40 |
# 1: the directory to index
|
sl@0
|
41 |
# 2: the patterns list
|
sl@0
|
42 |
|
sl@0
|
43 |
proc pkgtest::parseArgs { args } {
|
sl@0
|
44 |
set options ""
|
sl@0
|
45 |
|
sl@0
|
46 |
set argc [llength $args]
|
sl@0
|
47 |
for {set iarg 0} {$iarg < $argc} {incr iarg} {
|
sl@0
|
48 |
set a [lindex $args $iarg]
|
sl@0
|
49 |
if {[regexp {^-} $a]} {
|
sl@0
|
50 |
lappend options $a
|
sl@0
|
51 |
if {[string compare -load $a] == 0} {
|
sl@0
|
52 |
incr iarg
|
sl@0
|
53 |
lappend options [lindex $args $iarg]
|
sl@0
|
54 |
}
|
sl@0
|
55 |
} else {
|
sl@0
|
56 |
break
|
sl@0
|
57 |
}
|
sl@0
|
58 |
}
|
sl@0
|
59 |
|
sl@0
|
60 |
set dirPath [lindex $args $iarg]
|
sl@0
|
61 |
incr iarg
|
sl@0
|
62 |
set patternList [lrange $args $iarg end]
|
sl@0
|
63 |
|
sl@0
|
64 |
return [list $options $dirPath $patternList]
|
sl@0
|
65 |
}
|
sl@0
|
66 |
|
sl@0
|
67 |
# pkgtest::parseIndex --
|
sl@0
|
68 |
#
|
sl@0
|
69 |
# Loads a pkgIndex.tcl file, records all the calls to "package ifneeded".
|
sl@0
|
70 |
#
|
sl@0
|
71 |
# Arguments:
|
sl@0
|
72 |
# filePath path to the pkgIndex.tcl file.
|
sl@0
|
73 |
#
|
sl@0
|
74 |
# Results:
|
sl@0
|
75 |
# Returns a list, in "array set/get" format, where the keys are the package
|
sl@0
|
76 |
# name and version (in the form "$name:$version"), and the values the rest
|
sl@0
|
77 |
# of the command line.
|
sl@0
|
78 |
|
sl@0
|
79 |
proc pkgtest::parseIndex { filePath } {
|
sl@0
|
80 |
# create a slave interpreter, where we override "package ifneeded"
|
sl@0
|
81 |
|
sl@0
|
82 |
set slave [interp create]
|
sl@0
|
83 |
if {[catch {
|
sl@0
|
84 |
$slave eval {
|
sl@0
|
85 |
rename package package_original
|
sl@0
|
86 |
proc package { args } {
|
sl@0
|
87 |
if {[string compare [lindex $args 0] ifneeded] == 0} {
|
sl@0
|
88 |
set pkg [lindex $args 1]
|
sl@0
|
89 |
set ver [lindex $args 2]
|
sl@0
|
90 |
set ::PKGS($pkg:$ver) [lindex $args 3]
|
sl@0
|
91 |
} else {
|
sl@0
|
92 |
return [eval package_original $args]
|
sl@0
|
93 |
}
|
sl@0
|
94 |
}
|
sl@0
|
95 |
array set ::PKGS {}
|
sl@0
|
96 |
}
|
sl@0
|
97 |
|
sl@0
|
98 |
set dir [file dirname $filePath]
|
sl@0
|
99 |
$slave eval {set curdir [pwd]}
|
sl@0
|
100 |
$slave eval [list cd $dir]
|
sl@0
|
101 |
$slave eval [list set dir $dir]
|
sl@0
|
102 |
$slave eval [list source [file tail $filePath]]
|
sl@0
|
103 |
$slave eval {cd $curdir}
|
sl@0
|
104 |
|
sl@0
|
105 |
# Create the list in sorted order, so that we don't get spurious
|
sl@0
|
106 |
# errors because the order has changed.
|
sl@0
|
107 |
|
sl@0
|
108 |
array set P {}
|
sl@0
|
109 |
foreach {k v} [$slave eval {array get ::PKGS}] {
|
sl@0
|
110 |
set P($k) $v
|
sl@0
|
111 |
}
|
sl@0
|
112 |
|
sl@0
|
113 |
set PKGS ""
|
sl@0
|
114 |
foreach k [lsort [array names P]] {
|
sl@0
|
115 |
lappend PKGS $k $P($k)
|
sl@0
|
116 |
}
|
sl@0
|
117 |
} err]} {
|
sl@0
|
118 |
set ei $::errorInfo
|
sl@0
|
119 |
set ec $::errorCode
|
sl@0
|
120 |
|
sl@0
|
121 |
catch {interp delete $slave}
|
sl@0
|
122 |
|
sl@0
|
123 |
error $ei $ec
|
sl@0
|
124 |
}
|
sl@0
|
125 |
|
sl@0
|
126 |
interp delete $slave
|
sl@0
|
127 |
|
sl@0
|
128 |
return $PKGS
|
sl@0
|
129 |
}
|
sl@0
|
130 |
|
sl@0
|
131 |
# pkgtest::createIndex --
|
sl@0
|
132 |
#
|
sl@0
|
133 |
# Runs pkg_mkIndex for the given directory and set of patterns.
|
sl@0
|
134 |
# This procedure deletes any pkgIndex.tcl file in the target directory,
|
sl@0
|
135 |
# then runs pkg_mkIndex.
|
sl@0
|
136 |
#
|
sl@0
|
137 |
# Arguments:
|
sl@0
|
138 |
# <flags> (optional) arguments starting with a dash are collected
|
sl@0
|
139 |
# as options to pkg_mkIndex and passed to pkg_mkIndex.
|
sl@0
|
140 |
# dirPath the directory to index
|
sl@0
|
141 |
# pattern0 pattern to index
|
sl@0
|
142 |
# ... pattern to index
|
sl@0
|
143 |
# patternN pattern to index
|
sl@0
|
144 |
#
|
sl@0
|
145 |
# Results:
|
sl@0
|
146 |
# Returns a two element list:
|
sl@0
|
147 |
# 0: 1 if the procedure encountered an error, 0 otherwise.
|
sl@0
|
148 |
# 1: the error result if element 0 was 1
|
sl@0
|
149 |
|
sl@0
|
150 |
proc pkgtest::createIndex { args } {
|
sl@0
|
151 |
set parsed [eval parseArgs $args]
|
sl@0
|
152 |
set options [lindex $parsed 0]
|
sl@0
|
153 |
set dirPath [lindex $parsed 1]
|
sl@0
|
154 |
set patternList [lindex $parsed 2]
|
sl@0
|
155 |
|
sl@0
|
156 |
file mkdir $dirPath
|
sl@0
|
157 |
|
sl@0
|
158 |
if {[catch {
|
sl@0
|
159 |
file delete [file join $dirPath pkgIndex.tcl]
|
sl@0
|
160 |
eval pkg_mkIndex $options [list $dirPath] $patternList
|
sl@0
|
161 |
} err]} {
|
sl@0
|
162 |
return [list 1 $err]
|
sl@0
|
163 |
}
|
sl@0
|
164 |
|
sl@0
|
165 |
return [list 0 {}]
|
sl@0
|
166 |
}
|
sl@0
|
167 |
|
sl@0
|
168 |
# makePkgList --
|
sl@0
|
169 |
#
|
sl@0
|
170 |
# Takes the output of a pkgtest::parseIndex call, filters it and returns a
|
sl@0
|
171 |
# cleaned up list of packages and their actions.
|
sl@0
|
172 |
#
|
sl@0
|
173 |
# Arguments:
|
sl@0
|
174 |
# inList output from a pkgtest::parseIndex.
|
sl@0
|
175 |
#
|
sl@0
|
176 |
# Results:
|
sl@0
|
177 |
# Returns a list of two element lists:
|
sl@0
|
178 |
# 0: the name:version
|
sl@0
|
179 |
# 1: a list describing the package.
|
sl@0
|
180 |
# For tclPkgSetup packages it consists of:
|
sl@0
|
181 |
# 0: the keyword tclPkgSetup
|
sl@0
|
182 |
# 1: the first file to source, with its exported procedures
|
sl@0
|
183 |
# 2: the second file ...
|
sl@0
|
184 |
# N: the N-1st file ...
|
sl@0
|
185 |
|
sl@0
|
186 |
proc makePkgList { inList } {
|
sl@0
|
187 |
set pkgList ""
|
sl@0
|
188 |
|
sl@0
|
189 |
foreach {k v} $inList {
|
sl@0
|
190 |
switch [lindex $v 0] {
|
sl@0
|
191 |
tclPkgSetup {
|
sl@0
|
192 |
set l tclPkgSetup
|
sl@0
|
193 |
foreach s [lindex $v 4] {
|
sl@0
|
194 |
lappend l $s
|
sl@0
|
195 |
}
|
sl@0
|
196 |
}
|
sl@0
|
197 |
|
sl@0
|
198 |
source {
|
sl@0
|
199 |
set l $v
|
sl@0
|
200 |
}
|
sl@0
|
201 |
|
sl@0
|
202 |
default {
|
sl@0
|
203 |
error "can't handle $k $v"
|
sl@0
|
204 |
}
|
sl@0
|
205 |
}
|
sl@0
|
206 |
|
sl@0
|
207 |
lappend pkgList [list $k $l]
|
sl@0
|
208 |
}
|
sl@0
|
209 |
|
sl@0
|
210 |
return $pkgList
|
sl@0
|
211 |
}
|
sl@0
|
212 |
|
sl@0
|
213 |
# pkgtest::runIndex --
|
sl@0
|
214 |
#
|
sl@0
|
215 |
# Runs pkg_mkIndex, parses the generated index file.
|
sl@0
|
216 |
#
|
sl@0
|
217 |
# Arguments:
|
sl@0
|
218 |
# <flags> (optional) arguments starting with a dash are collected
|
sl@0
|
219 |
# as options to pkg_mkIndex and passed to pkg_mkIndex.
|
sl@0
|
220 |
# dirPath the directory to index
|
sl@0
|
221 |
# pattern0 pattern to index
|
sl@0
|
222 |
# ... pattern to index
|
sl@0
|
223 |
# patternN pattern to index
|
sl@0
|
224 |
#
|
sl@0
|
225 |
# Results:
|
sl@0
|
226 |
# Returns a two element list:
|
sl@0
|
227 |
# 0: 1 if the procedure encountered an error, 0 otherwise.
|
sl@0
|
228 |
# 1: if no error, this is the parsed generated index file, in the format
|
sl@0
|
229 |
# returned by pkgtest::parseIndex.
|
sl@0
|
230 |
# If error, this is the error result.
|
sl@0
|
231 |
|
sl@0
|
232 |
proc pkgtest::runCreatedIndex {rv args} {
|
sl@0
|
233 |
if {[lindex $rv 0] == 0} {
|
sl@0
|
234 |
set parsed [eval parseArgs $args]
|
sl@0
|
235 |
set dirPath [lindex $parsed 1]
|
sl@0
|
236 |
set idxFile [file join $dirPath pkgIndex.tcl]
|
sl@0
|
237 |
|
sl@0
|
238 |
if {[catch {
|
sl@0
|
239 |
set result [list 0 [makePkgList [parseIndex $idxFile]]]
|
sl@0
|
240 |
} err]} {
|
sl@0
|
241 |
set result [list 1 $err]
|
sl@0
|
242 |
}
|
sl@0
|
243 |
file delete $idxFile
|
sl@0
|
244 |
} else {
|
sl@0
|
245 |
set result $rv
|
sl@0
|
246 |
}
|
sl@0
|
247 |
|
sl@0
|
248 |
return $result
|
sl@0
|
249 |
}
|
sl@0
|
250 |
proc pkgtest::runIndex { args } {
|
sl@0
|
251 |
set rv [eval createIndex $args]
|
sl@0
|
252 |
return [eval [list runCreatedIndex $rv] $args]
|
sl@0
|
253 |
}
|
sl@0
|
254 |
|
sl@0
|
255 |
# If there is no match to the patterns, make sure the directory hasn't
|
sl@0
|
256 |
# changed on us
|
sl@0
|
257 |
|
sl@0
|
258 |
test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} {
|
sl@0
|
259 |
list [pkgtest::runIndex -lazy $fullPkgPath nomatch.tcl] [pwd]
|
sl@0
|
260 |
} [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]]
|
sl@0
|
261 |
|
sl@0
|
262 |
makeFile {
|
sl@0
|
263 |
# This is a simple package, just to check basic functionality.
|
sl@0
|
264 |
package provide simple 1.0
|
sl@0
|
265 |
namespace eval simple {
|
sl@0
|
266 |
namespace export lower upper
|
sl@0
|
267 |
}
|
sl@0
|
268 |
proc simple::lower { stg } {
|
sl@0
|
269 |
return [string tolower $stg]
|
sl@0
|
270 |
}
|
sl@0
|
271 |
proc simple::upper { stg } {
|
sl@0
|
272 |
return [string toupper $stg]
|
sl@0
|
273 |
}
|
sl@0
|
274 |
} [file join pkg simple.tcl]
|
sl@0
|
275 |
|
sl@0
|
276 |
test pkgMkIndex-2.1 {simple package} {
|
sl@0
|
277 |
pkgtest::runIndex -lazy $fullPkgPath simple.tcl
|
sl@0
|
278 |
} {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}}
|
sl@0
|
279 |
|
sl@0
|
280 |
test pkgMkIndex-2.2 {simple package - use -direct} {
|
sl@0
|
281 |
pkgtest::runIndex -direct $fullPkgPath simple.tcl
|
sl@0
|
282 |
} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
|
sl@0
|
283 |
|
sl@0
|
284 |
test pkgMkIndex-2.3 {simple package - direct loading is default} {
|
sl@0
|
285 |
pkgtest::runIndex $fullPkgPath simple.tcl
|
sl@0
|
286 |
} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
|
sl@0
|
287 |
|
sl@0
|
288 |
test pkgMkIndex-2.4 {simple package - use -verbose} -body {
|
sl@0
|
289 |
pkgtest::runIndex -verbose $fullPkgPath simple.tcl
|
sl@0
|
290 |
} -result "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" \
|
sl@0
|
291 |
-errorOutput {successful sourcing of simple.tcl
|
sl@0
|
292 |
packages provided were {simple 1.0}
|
sl@0
|
293 |
processed simple.tcl
|
sl@0
|
294 |
}
|
sl@0
|
295 |
|
sl@0
|
296 |
removeFile [file join pkg simple.tcl]
|
sl@0
|
297 |
|
sl@0
|
298 |
makeFile {
|
sl@0
|
299 |
# Contains global symbols, used to check that they don't have a leading ::
|
sl@0
|
300 |
package provide global 1.0
|
sl@0
|
301 |
proc global_lower { stg } {
|
sl@0
|
302 |
return [string tolower $stg]
|
sl@0
|
303 |
}
|
sl@0
|
304 |
proc global_upper { stg } {
|
sl@0
|
305 |
return [string toupper $stg]
|
sl@0
|
306 |
}
|
sl@0
|
307 |
} [file join pkg global.tcl]
|
sl@0
|
308 |
|
sl@0
|
309 |
test pkgMkIndex-3.1 {simple package with global symbols} {
|
sl@0
|
310 |
pkgtest::runIndex -lazy $fullPkgPath global.tcl
|
sl@0
|
311 |
} {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}}
|
sl@0
|
312 |
|
sl@0
|
313 |
removeFile [file join pkg global.tcl]
|
sl@0
|
314 |
|
sl@0
|
315 |
makeFile {
|
sl@0
|
316 |
# This package is required by pkg1.
|
sl@0
|
317 |
# This package is split into two files, to test packages that are split
|
sl@0
|
318 |
# over multiple files.
|
sl@0
|
319 |
package provide pkg2 1.0
|
sl@0
|
320 |
namespace eval pkg2 {
|
sl@0
|
321 |
namespace export p2-1
|
sl@0
|
322 |
}
|
sl@0
|
323 |
proc pkg2::p2-1 { num } {
|
sl@0
|
324 |
return [expr $num * 2]
|
sl@0
|
325 |
}
|
sl@0
|
326 |
} [file join pkg pkg2_a.tcl]
|
sl@0
|
327 |
|
sl@0
|
328 |
makeFile {
|
sl@0
|
329 |
# This package is required by pkg1.
|
sl@0
|
330 |
# This package is split into two files, to test packages that are split
|
sl@0
|
331 |
# over multiple files.
|
sl@0
|
332 |
package provide pkg2 1.0
|
sl@0
|
333 |
namespace eval pkg2 {
|
sl@0
|
334 |
namespace export p2-2
|
sl@0
|
335 |
}
|
sl@0
|
336 |
proc pkg2::p2-2 { num } {
|
sl@0
|
337 |
return [expr $num * 3]
|
sl@0
|
338 |
}
|
sl@0
|
339 |
} [file join pkg pkg2_b.tcl]
|
sl@0
|
340 |
|
sl@0
|
341 |
test pkgMkIndex-4.1 {split package} {
|
sl@0
|
342 |
pkgtest::runIndex -lazy $fullPkgPath pkg2_a.tcl pkg2_b.tcl
|
sl@0
|
343 |
} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}}
|
sl@0
|
344 |
|
sl@0
|
345 |
test pkgMkIndex-4.2 {split package - direct loading} {
|
sl@0
|
346 |
pkgtest::runIndex -direct $fullPkgPath pkg2_a.tcl pkg2_b.tcl
|
sl@0
|
347 |
} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
|
sl@0
|
348 |
[list source [file join $fullPkgPath pkg2_b.tcl]]}}}"
|
sl@0
|
349 |
|
sl@0
|
350 |
# Add the direct1 directory to auto_path, so that the direct1 package
|
sl@0
|
351 |
# can be found.
|
sl@0
|
352 |
set direct1 [makeDirectory direct1]
|
sl@0
|
353 |
lappend auto_path $direct1
|
sl@0
|
354 |
makeFile {
|
sl@0
|
355 |
# This is referenced by pkgIndex.tcl as a -direct script.
|
sl@0
|
356 |
package provide direct1 1.0
|
sl@0
|
357 |
namespace eval direct1 {
|
sl@0
|
358 |
namespace export pd1 pd2
|
sl@0
|
359 |
}
|
sl@0
|
360 |
proc direct1::pd1 { stg } {
|
sl@0
|
361 |
return [string tolower $stg]
|
sl@0
|
362 |
}
|
sl@0
|
363 |
proc direct1::pd2 { stg } {
|
sl@0
|
364 |
return [string toupper $stg]
|
sl@0
|
365 |
}
|
sl@0
|
366 |
} [file join direct1 direct1.tcl]
|
sl@0
|
367 |
pkg_mkIndex -direct $direct1 direct1.tcl
|
sl@0
|
368 |
|
sl@0
|
369 |
makeFile {
|
sl@0
|
370 |
# Does a package require of direct1, whose pkgIndex.tcl entry
|
sl@0
|
371 |
# is created above with option -direct. This tests that pkg_mkIndex
|
sl@0
|
372 |
# can handle code that is sourced in pkgIndex.tcl files.
|
sl@0
|
373 |
package require direct1
|
sl@0
|
374 |
package provide std 1.0
|
sl@0
|
375 |
namespace eval std {
|
sl@0
|
376 |
namespace export p1 p2
|
sl@0
|
377 |
}
|
sl@0
|
378 |
proc std::p1 { stg } {
|
sl@0
|
379 |
return [string tolower $stg]
|
sl@0
|
380 |
}
|
sl@0
|
381 |
proc std::p2 { stg } {
|
sl@0
|
382 |
return [string toupper $stg]
|
sl@0
|
383 |
}
|
sl@0
|
384 |
} [file join pkg std.tcl]
|
sl@0
|
385 |
|
sl@0
|
386 |
test pkgMkIndex-5.1 {requires -direct package} {
|
sl@0
|
387 |
pkgtest::runIndex -lazy $fullPkgPath std.tcl
|
sl@0
|
388 |
} {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}}
|
sl@0
|
389 |
|
sl@0
|
390 |
removeFile [file join direct1 direct1.tcl]
|
sl@0
|
391 |
file delete [file join $direct1 pkgIndex.tcl]
|
sl@0
|
392 |
removeDirectory direct1
|
sl@0
|
393 |
removeFile [file join pkg std.tcl]
|
sl@0
|
394 |
|
sl@0
|
395 |
makeFile {
|
sl@0
|
396 |
# This package requires pkg3, but it does
|
sl@0
|
397 |
# not use any of pkg3's procs in the code that is executed by the file
|
sl@0
|
398 |
# (i.e. references to pkg3's procs are in the proc bodies only).
|
sl@0
|
399 |
package require pkg3 1.0
|
sl@0
|
400 |
package provide pkg1 1.0
|
sl@0
|
401 |
namespace eval pkg1 {
|
sl@0
|
402 |
namespace export p1-1 p1-2
|
sl@0
|
403 |
}
|
sl@0
|
404 |
proc pkg1::p1-1 { num } {
|
sl@0
|
405 |
return [pkg3::p3-1 $num]
|
sl@0
|
406 |
}
|
sl@0
|
407 |
proc pkg1::p1-2 { num } {
|
sl@0
|
408 |
return [pkg3::p3-2 $num]
|
sl@0
|
409 |
}
|
sl@0
|
410 |
} [file join pkg pkg1.tcl]
|
sl@0
|
411 |
|
sl@0
|
412 |
makeFile {
|
sl@0
|
413 |
package provide pkg3 1.0
|
sl@0
|
414 |
namespace eval pkg3 {
|
sl@0
|
415 |
namespace export p3-1 p3-2
|
sl@0
|
416 |
}
|
sl@0
|
417 |
proc pkg3::p3-1 { num } {
|
sl@0
|
418 |
return {[expr $num * 2]}
|
sl@0
|
419 |
}
|
sl@0
|
420 |
proc pkg3::p3-2 { num } {
|
sl@0
|
421 |
return {[expr $num * 3]}
|
sl@0
|
422 |
}
|
sl@0
|
423 |
} [file join pkg pkg3.tcl]
|
sl@0
|
424 |
|
sl@0
|
425 |
test pkgMkIndex-6.1 {pkg1 requires pkg3} {
|
sl@0
|
426 |
pkgtest::runIndex -lazy $fullPkgPath pkg1.tcl pkg3.tcl
|
sl@0
|
427 |
} {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
|
428 |
|
sl@0
|
429 |
test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} {
|
sl@0
|
430 |
pkgtest::runIndex -direct $fullPkgPath pkg1.tcl pkg3.tcl
|
sl@0
|
431 |
} "0 {{pkg1:1.0 {[list source [file join $fullPkgPath pkg1.tcl]]}} {pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}}}"
|
sl@0
|
432 |
|
sl@0
|
433 |
removeFile [file join pkg pkg1.tcl]
|
sl@0
|
434 |
|
sl@0
|
435 |
makeFile {
|
sl@0
|
436 |
# This package requires pkg3, and it calls
|
sl@0
|
437 |
# a pkg3 proc in the code that is executed by the file
|
sl@0
|
438 |
package require pkg3 1.0
|
sl@0
|
439 |
package provide pkg4 1.0
|
sl@0
|
440 |
namespace eval pkg4 {
|
sl@0
|
441 |
namespace export p4-1 p4-2
|
sl@0
|
442 |
variable m2 [pkg3::p3-1 10]
|
sl@0
|
443 |
}
|
sl@0
|
444 |
proc pkg4::p4-1 { num } {
|
sl@0
|
445 |
variable m2
|
sl@0
|
446 |
return [expr {$m2 * $num}]
|
sl@0
|
447 |
}
|
sl@0
|
448 |
proc pkg4::p4-2 { num } {
|
sl@0
|
449 |
return [pkg3::p3-2 $num]
|
sl@0
|
450 |
}
|
sl@0
|
451 |
} [file join pkg pkg4.tcl]
|
sl@0
|
452 |
|
sl@0
|
453 |
test pkgMkIndex-7.1 {pkg4 uses pkg3} {
|
sl@0
|
454 |
pkgtest::runIndex -lazy $fullPkgPath pkg4.tcl pkg3.tcl
|
sl@0
|
455 |
} {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
|
456 |
|
sl@0
|
457 |
test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} {
|
sl@0
|
458 |
pkgtest::runIndex -direct $fullPkgPath pkg4.tcl pkg3.tcl
|
sl@0
|
459 |
} "0 {{pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}} {pkg4:1.0 {[list source [file join $fullPkgPath pkg4.tcl]]}}}"
|
sl@0
|
460 |
|
sl@0
|
461 |
removeFile [file join pkg pkg4.tcl]
|
sl@0
|
462 |
removeFile [file join pkg pkg3.tcl]
|
sl@0
|
463 |
|
sl@0
|
464 |
makeFile {
|
sl@0
|
465 |
# This package requires pkg2, and it calls
|
sl@0
|
466 |
# a pkg2 proc in the code that is executed by the file.
|
sl@0
|
467 |
# Pkg2 is a split package.
|
sl@0
|
468 |
package require pkg2 1.0
|
sl@0
|
469 |
package provide pkg5 1.0
|
sl@0
|
470 |
namespace eval pkg5 {
|
sl@0
|
471 |
namespace export p5-1 p5-2
|
sl@0
|
472 |
variable m2 [pkg2::p2-1 10]
|
sl@0
|
473 |
variable m3 [pkg2::p2-2 10]
|
sl@0
|
474 |
}
|
sl@0
|
475 |
proc pkg5::p5-1 { num } {
|
sl@0
|
476 |
variable m2
|
sl@0
|
477 |
return [expr {$m2 * $num}]
|
sl@0
|
478 |
}
|
sl@0
|
479 |
proc pkg5::p5-2 { num } {
|
sl@0
|
480 |
variable m2
|
sl@0
|
481 |
return [expr {$m2 * $num}]
|
sl@0
|
482 |
}
|
sl@0
|
483 |
} [file join pkg pkg5.tcl]
|
sl@0
|
484 |
|
sl@0
|
485 |
test pkgMkIndex-8.1 {pkg5 uses pkg2} {
|
sl@0
|
486 |
pkgtest::runIndex -lazy $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
|
sl@0
|
487 |
} {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
|
488 |
|
sl@0
|
489 |
test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} {
|
sl@0
|
490 |
pkgtest::runIndex -direct $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
|
sl@0
|
491 |
} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
|
sl@0
|
492 |
[list source [file join $fullPkgPath pkg2_b.tcl]]}} {pkg5:1.0 {[list source [file join $fullPkgPath pkg5.tcl]]}}}"
|
sl@0
|
493 |
|
sl@0
|
494 |
removeFile [file join pkg pkg5.tcl]
|
sl@0
|
495 |
removeFile [file join pkg pkg2_a.tcl]
|
sl@0
|
496 |
removeFile [file join pkg pkg2_b.tcl]
|
sl@0
|
497 |
|
sl@0
|
498 |
makeFile {
|
sl@0
|
499 |
# This package requires circ2, and circ2
|
sl@0
|
500 |
# requires circ3, which in turn requires circ1.
|
sl@0
|
501 |
# In case of cirularities, pkg_mkIndex should give up when it gets stuck.
|
sl@0
|
502 |
package require circ2 1.0
|
sl@0
|
503 |
package provide circ1 1.0
|
sl@0
|
504 |
namespace eval circ1 {
|
sl@0
|
505 |
namespace export c1-1 c1-2 c1-3 c1-4
|
sl@0
|
506 |
}
|
sl@0
|
507 |
proc circ1::c1-1 { num } {
|
sl@0
|
508 |
return [circ2::c2-1 $num]
|
sl@0
|
509 |
}
|
sl@0
|
510 |
proc circ1::c1-2 { num } {
|
sl@0
|
511 |
return [circ2::c2-2 $num]
|
sl@0
|
512 |
}
|
sl@0
|
513 |
proc circ1::c1-3 {} {
|
sl@0
|
514 |
return 10
|
sl@0
|
515 |
}
|
sl@0
|
516 |
proc circ1::c1-4 {} {
|
sl@0
|
517 |
return 20
|
sl@0
|
518 |
}
|
sl@0
|
519 |
} [file join pkg circ1.tcl]
|
sl@0
|
520 |
|
sl@0
|
521 |
makeFile {
|
sl@0
|
522 |
# This package is required by circ1, and
|
sl@0
|
523 |
# requires circ3. Circ3, in turn, requires circ1 to give us a circularity.
|
sl@0
|
524 |
package require circ3 1.0
|
sl@0
|
525 |
package provide circ2 1.0
|
sl@0
|
526 |
namespace eval circ2 {
|
sl@0
|
527 |
namespace export c2-1 c2-2
|
sl@0
|
528 |
}
|
sl@0
|
529 |
proc circ2::c2-1 { num } {
|
sl@0
|
530 |
return [expr $num * [circ3::c3-1]]
|
sl@0
|
531 |
}
|
sl@0
|
532 |
proc circ2::c2-2 { num } {
|
sl@0
|
533 |
return [expr $num * [circ3::c3-2]]
|
sl@0
|
534 |
}
|
sl@0
|
535 |
} [file join pkg circ2.tcl]
|
sl@0
|
536 |
|
sl@0
|
537 |
makeFile {
|
sl@0
|
538 |
# This package is required by circ2, and in
|
sl@0
|
539 |
# turn requires circ1. This closes the circularity.
|
sl@0
|
540 |
package require circ1 1.0
|
sl@0
|
541 |
package provide circ3 1.0
|
sl@0
|
542 |
namespace eval circ3 {
|
sl@0
|
543 |
namespace export c3-1 c3-4
|
sl@0
|
544 |
}
|
sl@0
|
545 |
proc circ3::c3-1 {} {
|
sl@0
|
546 |
return [circ1::c1-3]
|
sl@0
|
547 |
}
|
sl@0
|
548 |
proc circ3::c3-2 {} {
|
sl@0
|
549 |
return [circ1::c1-4]
|
sl@0
|
550 |
}
|
sl@0
|
551 |
} [file join pkg circ3.tcl]
|
sl@0
|
552 |
|
sl@0
|
553 |
test pkgMkIndex-9.1 {circular packages} {
|
sl@0
|
554 |
pkgtest::runIndex -lazy $fullPkgPath circ1.tcl circ2.tcl circ3.tcl
|
sl@0
|
555 |
} {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
|
556 |
|
sl@0
|
557 |
removeFile [file join pkg circ1.tcl]
|
sl@0
|
558 |
removeFile [file join pkg circ2.tcl]
|
sl@0
|
559 |
removeFile [file join pkg circ3.tcl]
|
sl@0
|
560 |
|
sl@0
|
561 |
# Some tests require the existence of one of the DLLs in the dltest directory
|
sl@0
|
562 |
set x [file join [file dirname [info nameofexecutable]] dltest \
|
sl@0
|
563 |
pkga[info sharedlibextension]]
|
sl@0
|
564 |
set dll "[file tail $x]Required"
|
sl@0
|
565 |
::tcltest::testConstraint $dll [file exists $x]
|
sl@0
|
566 |
|
sl@0
|
567 |
if {[testConstraint $dll]} {
|
sl@0
|
568 |
makeFile {
|
sl@0
|
569 |
# This package provides Pkga, which is also provided by a DLL.
|
sl@0
|
570 |
package provide Pkga 1.0
|
sl@0
|
571 |
proc pkga_neq { x } {
|
sl@0
|
572 |
return [expr {! [pkgq_eq $x]}]
|
sl@0
|
573 |
}
|
sl@0
|
574 |
} [file join pkg pkga.tcl]
|
sl@0
|
575 |
file copy -force $x $fullPkgPath
|
sl@0
|
576 |
}
|
sl@0
|
577 |
testConstraint exec [llength [info commands ::exec]]
|
sl@0
|
578 |
|
sl@0
|
579 |
test pkgMkIndex-10.1 {package in DLL and script} [list exec $dll] {
|
sl@0
|
580 |
# Do all [load]ing of shared libraries in another process, so
|
sl@0
|
581 |
# we can delete the file and not get stuck because we're holding
|
sl@0
|
582 |
# a reference to it.
|
sl@0
|
583 |
set cmd [list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]
|
sl@0
|
584 |
exec [interpreter] << $cmd
|
sl@0
|
585 |
pkgtest::runCreatedIndex {0 {}} -lazy $fullPkgPath pkga[info sharedlibextension] pkga.tcl
|
sl@0
|
586 |
} "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}"
|
sl@0
|
587 |
test pkgMkIndex-10.2 {package in DLL hidden by -load} [list exec $dll] {
|
sl@0
|
588 |
# Do all [load]ing of shared libraries in another process, so
|
sl@0
|
589 |
# we can delete the file and not get stuck because we're holding
|
sl@0
|
590 |
# a reference to it.
|
sl@0
|
591 |
#
|
sl@0
|
592 |
# This test depends on context from prior test, so repeat it.
|
sl@0
|
593 |
set script "[list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]\n"
|
sl@0
|
594 |
append script \
|
sl@0
|
595 |
"[list pkg_mkIndex -lazy -load Pkg* $fullPkgPath [file tail $x]]"
|
sl@0
|
596 |
exec [interpreter] << $script
|
sl@0
|
597 |
pkgtest::runCreatedIndex {0 {}} -lazy -load Pkg* -- $fullPkgPath pkga[info sharedlibextension]
|
sl@0
|
598 |
} {0 {}}
|
sl@0
|
599 |
|
sl@0
|
600 |
if {[testConstraint $dll]} {
|
sl@0
|
601 |
file delete -force [file join $fullPkgPath [file tail $x]]
|
sl@0
|
602 |
removeFile [file join pkg pkga.tcl]
|
sl@0
|
603 |
}
|
sl@0
|
604 |
|
sl@0
|
605 |
# Tolerate "namespace import" at the global scope
|
sl@0
|
606 |
|
sl@0
|
607 |
makeFile {
|
sl@0
|
608 |
package provide fubar 1.0
|
sl@0
|
609 |
namespace eval ::fubar:: {
|
sl@0
|
610 |
#
|
sl@0
|
611 |
# export only public functions.
|
sl@0
|
612 |
#
|
sl@0
|
613 |
namespace export {[a-z]*}
|
sl@0
|
614 |
}
|
sl@0
|
615 |
proc ::fubar::foo {bar} {
|
sl@0
|
616 |
puts "$bar"
|
sl@0
|
617 |
return true
|
sl@0
|
618 |
}
|
sl@0
|
619 |
namespace import ::fubar::foo
|
sl@0
|
620 |
} [file join pkg import.tcl]
|
sl@0
|
621 |
|
sl@0
|
622 |
test pkgMkIndex-11.1 {conflicting namespace imports} {
|
sl@0
|
623 |
pkgtest::runIndex -lazy $fullPkgPath import.tcl
|
sl@0
|
624 |
} {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}}
|
sl@0
|
625 |
|
sl@0
|
626 |
removeFile [file join pkg import.tcl]
|
sl@0
|
627 |
|
sl@0
|
628 |
# Verify that the auto load list generated is correct even when there
|
sl@0
|
629 |
# is a proc name conflict between two namespaces (ie, ::foo::baz and
|
sl@0
|
630 |
# ::bar::baz)
|
sl@0
|
631 |
|
sl@0
|
632 |
makeFile {
|
sl@0
|
633 |
package provide football 1.0
|
sl@0
|
634 |
namespace eval ::pro:: {
|
sl@0
|
635 |
#
|
sl@0
|
636 |
# export only public functions.
|
sl@0
|
637 |
#
|
sl@0
|
638 |
namespace export {[a-z]*}
|
sl@0
|
639 |
}
|
sl@0
|
640 |
namespace eval ::college:: {
|
sl@0
|
641 |
#
|
sl@0
|
642 |
# export only public functions.
|
sl@0
|
643 |
#
|
sl@0
|
644 |
namespace export {[a-z]*}
|
sl@0
|
645 |
}
|
sl@0
|
646 |
proc ::pro::team {} {
|
sl@0
|
647 |
puts "go packers!"
|
sl@0
|
648 |
return true
|
sl@0
|
649 |
}
|
sl@0
|
650 |
proc ::college::team {} {
|
sl@0
|
651 |
puts "go badgers!"
|
sl@0
|
652 |
return true
|
sl@0
|
653 |
}
|
sl@0
|
654 |
} [file join pkg samename.tcl]
|
sl@0
|
655 |
|
sl@0
|
656 |
test pkgMkIndex-12.1 {same name procs in different namespace} {
|
sl@0
|
657 |
pkgtest::runIndex -lazy $fullPkgPath samename.tcl
|
sl@0
|
658 |
} {0 {{football:1.0 {tclPkgSetup {samename.tcl source {::college::team ::pro::team}}}}}}
|
sl@0
|
659 |
|
sl@0
|
660 |
removeFile [file join pkg samename.tcl]
|
sl@0
|
661 |
|
sl@0
|
662 |
# Proc names with embedded spaces are properly listed (ie, correct number of
|
sl@0
|
663 |
# braces) in result
|
sl@0
|
664 |
makeFile {
|
sl@0
|
665 |
package provide spacename 1.0
|
sl@0
|
666 |
proc {a b} {} {}
|
sl@0
|
667 |
proc {c d} {} {}
|
sl@0
|
668 |
} [file join pkg spacename.tcl]
|
sl@0
|
669 |
|
sl@0
|
670 |
test pkgMkIndex-13.1 {proc names with embedded spaces} {
|
sl@0
|
671 |
pkgtest::runIndex -lazy $fullPkgPath spacename.tcl
|
sl@0
|
672 |
} {0 {{spacename:1.0 {tclPkgSetup {spacename.tcl source {{a b} {c d}}}}}}}
|
sl@0
|
673 |
|
sl@0
|
674 |
removeFile [file join pkg spacename.tcl]
|
sl@0
|
675 |
|
sl@0
|
676 |
# Test the pkg_compareExtension helper function
|
sl@0
|
677 |
test pkgMkIndex-14.1 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
678 |
pkg_compareExtension foo.so .so
|
sl@0
|
679 |
} 1
|
sl@0
|
680 |
test pkgMkIndex-14.2 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
681 |
pkg_compareExtension foo.so.bar .so
|
sl@0
|
682 |
} 0
|
sl@0
|
683 |
test pkgMkIndex-14.3 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
684 |
pkg_compareExtension foo.so.1 .so
|
sl@0
|
685 |
} 1
|
sl@0
|
686 |
test pkgMkIndex-14.4 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
687 |
pkg_compareExtension foo.so.1.2 .so
|
sl@0
|
688 |
} 1
|
sl@0
|
689 |
test pkgMkIndex-14.5 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
690 |
pkg_compareExtension foo .so
|
sl@0
|
691 |
} 0
|
sl@0
|
692 |
test pkgMkIndex-14.6 {pkg_compareExtension} {unixOnly} {
|
sl@0
|
693 |
pkg_compareExtension foo.so.1.2.bar .so
|
sl@0
|
694 |
} 0
|
sl@0
|
695 |
|
sl@0
|
696 |
# cleanup
|
sl@0
|
697 |
|
sl@0
|
698 |
removeDirectory pkg
|
sl@0
|
699 |
|
sl@0
|
700 |
namespace delete pkgtest
|
sl@0
|
701 |
::tcltest::cleanupTests
|
sl@0
|
702 |
return
|
sl@0
|
703 |
|