1 # Functionality covered: this file contains a collection of tests for the
2 # procedures in tclObj.c that implement Tcl's basic type support and the
3 # type managers for the types boolean, double, and integer.
5 # Sourcing this file into Tcl runs the tests and generates output for
6 # errors. No output means no errors were found.
8 # Copyright (c) 1995-1996 Sun Microsystems, Inc.
9 # Copyright (c) 1998-1999 by Scriptics Corporation.
11 # See the file "license.terms" for information on usage and redistribution
12 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 if {[lsearch [namespace children] ::tcltest] == -1} {
17 package require tcltest
18 namespace import -force ::tcltest::*
21 if {[info commands testobj] == {}} {
22 puts "This application hasn't been compiled with the \"testobj\""
23 puts "command, so I can't test the Tcl type and object support."
24 ::tcltest::cleanupTests
28 test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} {
30 foreach {t} {list boolean cmdName bytecode string int double} {
31 set first [string first $t [testobj types]]
32 set r [expr {$r && ($first != -1)}]
37 test obj-2.1 {Tcl_GetObjType error} {
38 list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
39 } {0 1 {no type foo found}}
40 test obj-2.2 {Tcl_GetObjType and Tcl_ConvertToType} {
42 lappend result [testobj freeallvars]
43 lappend result [testintobj set 1 12]
44 lappend result [testobj convert 1 double]
45 lappend result [testobj type 1]
46 lappend result [testobj refcount 1]
49 test obj-3.1 {Tcl_ConvertToType error} {
50 list [testdoubleobj set 1 12.34] [catch {testobj convert 1 int} msg] $msg
51 } {12.34 1 {expected integer but got "12.34"}}
52 test obj-3.2 {Tcl_ConvertToType error, "empty string" object} {
53 list [testobj newobj 1] [catch {testobj convert 1 int} msg] $msg
54 } {{} 1 {expected integer but got ""}}
56 test obj-4.1 {Tcl_NewObj and AllocateFreeObjects} {
58 lappend result [testobj freeallvars]
59 lappend result [testobj newobj 1]
60 lappend result [testobj type 1]
61 lappend result [testobj refcount 1]
64 test obj-5.1 {Tcl_FreeObj} {
66 lappend result [testintobj set 1 12345]
67 lappend result [testobj freeallvars]
68 lappend result [catch {testintobj get 1} msg]
70 } {12345 {} 1 {variable 1 is unset (NULL)}}
72 test obj-6.1 {Tcl_DuplicateObj, object has internal rep} {
74 lappend result [testobj freeallvars]
75 lappend result [testintobj set 1 47]
76 lappend result [testobj duplicate 1 2]
77 lappend result [testintobj get 2]
78 lappend result [testobj refcount 1]
79 lappend result [testobj refcount 2]
81 test obj-6.2 {Tcl_DuplicateObj, "empty string" object} {
83 lappend result [testobj freeallvars]
84 lappend result [testobj newobj 1]
85 lappend result [testobj duplicate 1 2]
86 lappend result [testintobj get 2]
87 lappend result [testobj refcount 1]
88 lappend result [testobj refcount 2]
91 test obj-7.1 {Tcl_GetString, return existing string rep} {
93 lappend result [testintobj set 1 47]
94 lappend result [testintobj get2 1]
96 test obj-7.2 {Tcl_GetString, "empty string" object} {
98 lappend result [testobj newobj 1]
99 lappend result [teststringobj append 1 abc -1]
100 lappend result [teststringobj get2 1]
102 test obj-7.3 {Tcl_GetString, returns string internal rep (DString)} {
104 lappend result [teststringobj set 1 xyz]
105 lappend result [teststringobj append 1 abc -1]
106 lappend result [teststringobj get2 1]
107 } {xyz xyzabc xyzabc}
108 test obj-7.4 {Tcl_GetString, recompute string rep from internal rep} {
110 lappend result [testintobj set 1 77]
111 lappend result [testintobj mult10 1]
112 lappend result [teststringobj get2 1]
115 test obj-8.1 {Tcl_GetStringFromObj, return existing string rep} {
117 lappend result [testintobj set 1 47]
118 lappend result [testintobj get 1]
120 test obj-8.2 {Tcl_GetStringFromObj, "empty string" object} {
122 lappend result [testobj newobj 1]
123 lappend result [teststringobj append 1 abc -1]
124 lappend result [teststringobj get 1]
126 test obj-8.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} {
128 lappend result [teststringobj set 1 xyz]
129 lappend result [teststringobj append 1 abc -1]
130 lappend result [teststringobj get 1]
131 } {xyz xyzabc xyzabc}
132 test obj-8.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} {
134 lappend result [testintobj set 1 77]
135 lappend result [testintobj mult10 1]
136 lappend result [teststringobj get 1]
139 test obj-9.1 {Tcl_NewBooleanObj} {
141 lappend result [testobj freeallvars]
142 lappend result [testbooleanobj set 1 0]
143 lappend result [testobj type 1]
144 lappend result [testobj refcount 1]
147 test obj-10.1 {Tcl_SetBooleanObj, existing "empty string" object} {
149 lappend result [testobj freeallvars]
150 lappend result [testobj newobj 1]
151 lappend result [testbooleanobj set 1 0] ;# makes existing obj boolean
152 lappend result [testobj type 1]
153 lappend result [testobj refcount 1]
154 } {{} {} 0 boolean 2}
155 test obj-10.2 {Tcl_SetBooleanObj, existing non-"empty string" object} {
157 lappend result [testobj freeallvars]
158 lappend result [testintobj set 1 98765]
159 lappend result [testbooleanobj set 1 1] ;# makes existing obj boolean
160 lappend result [testobj type 1]
161 lappend result [testobj refcount 1]
162 } {{} 98765 1 boolean 2}
164 test obj-11.1 {Tcl_GetBooleanFromObj, existing boolean object} {
166 lappend result [testbooleanobj set 1 1]
167 lappend result [testbooleanobj not 1] ;# gets existing boolean rep
169 test obj-11.2 {Tcl_GetBooleanFromObj, convert to boolean} {
171 lappend result [testintobj set 1 47]
172 lappend result [testbooleanobj not 1] ;# must convert to bool
173 lappend result [testobj type 1]
175 test obj-11.3 {Tcl_GetBooleanFromObj, error converting to boolean} {
177 lappend result [teststringobj set 1 abc]
178 lappend result [catch {testbooleanobj not 1} msg]
180 } {abc 1 {expected boolean value but got "abc"}}
181 test obj-11.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} {
183 lappend result [testobj newobj 1]
184 lappend result [catch {testbooleanobj not 1} msg]
186 } {{} 1 {expected boolean value but got ""}}
188 test obj-12.1 {DupBooleanInternalRep} {
190 lappend result [testbooleanobj set 1 1]
191 lappend result [testobj duplicate 1 2] ;# uses DupBooleanInternalRep
192 lappend result [testbooleanobj get 2]
195 test obj-13.1 {SetBooleanFromAny, int to boolean special case} {
197 lappend result [testintobj set 1 1234]
198 lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
199 lappend result [testobj type 1]
201 test obj-13.2 {SetBooleanFromAny, double to boolean special case} {
203 lappend result [testdoubleobj set 1 3.14159]
204 lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
205 lappend result [testobj type 1]
206 } {3.14159 0 boolean}
207 test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} {
209 foreach s {yes no true false on off} {
210 teststringobj set 1 $s
211 lappend result [testbooleanobj not 1]
213 lappend result [testobj type 1]
214 } {0 1 0 1 0 1 boolean}
215 test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} {
217 lappend result [testintobj set 1 456]
218 lappend result [testintobj div10 1]
219 lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
220 lappend result [testobj type 1]
222 test obj-13.5 {SetBooleanFromAny, error parsing string} {
224 lappend result [teststringobj set 1 abc]
225 lappend result [catch {testbooleanobj not 1} msg]
227 } {abc 1 {expected boolean value but got "abc"}}
228 test obj-13.6 {SetBooleanFromAny, error parsing string} {
230 lappend result [teststringobj set 1 x1.0]
231 lappend result [catch {testbooleanobj not 1} msg]
233 } {x1.0 1 {expected boolean value but got "x1.0"}}
234 test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} {
236 lappend result [testobj newobj 1]
237 lappend result [catch {testbooleanobj not 1} msg]
239 } {{} 1 {expected boolean value but got ""}}
240 test obj-13.8 {SetBooleanFromAny, unicode strings} {
242 lappend result [teststringobj set 1 1\u7777]
243 lappend result [catch {testbooleanobj not 1} msg]
245 } "1\u7777 1 {expected boolean value but got \"1\u7777\"}"
247 test obj-14.1 {UpdateStringOfBoolean} {
249 lappend result [testbooleanobj set 1 0]
250 lappend result [testbooleanobj not 1]
251 lappend result [testbooleanobj get 1] ;# must update string rep
254 test obj-15.1 {Tcl_NewDoubleObj} {
256 lappend result [testobj freeallvars]
257 lappend result [testdoubleobj set 1 3.1459]
258 lappend result [testobj type 1]
259 lappend result [testobj refcount 1]
260 } {{} 3.1459 double 2}
262 test obj-16.1 {Tcl_SetDoubleObj, existing "empty string" object} {
264 lappend result [testobj freeallvars]
265 lappend result [testobj newobj 1]
266 lappend result [testdoubleobj set 1 0.123] ;# makes existing obj boolean
267 lappend result [testobj type 1]
268 lappend result [testobj refcount 1]
269 } {{} {} 0.123 double 2}
270 test obj-16.2 {Tcl_SetDoubleObj, existing non-"empty string" object} {
272 lappend result [testobj freeallvars]
273 lappend result [testintobj set 1 98765]
274 lappend result [testdoubleobj set 1 27.56] ;# makes existing obj double
275 lappend result [testobj type 1]
276 lappend result [testobj refcount 1]
277 } {{} 98765 27.56 double 2}
279 test obj-17.1 {Tcl_GetDoubleFromObj, existing double object} {
281 lappend result [testdoubleobj set 1 16.1]
282 lappend result [testdoubleobj mult10 1] ;# gets existing double rep
284 test obj-17.2 {Tcl_GetDoubleFromObj, convert to double} {
286 lappend result [testintobj set 1 477]
287 lappend result [testdoubleobj div10 1] ;# must convert to bool
288 lappend result [testobj type 1]
290 test obj-17.3 {Tcl_GetDoubleFromObj, error converting to double} {
292 lappend result [teststringobj set 1 abc]
293 lappend result [catch {testdoubleobj mult10 1} msg]
295 } {abc 1 {expected floating-point number but got "abc"}}
296 test obj-17.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} {
298 lappend result [testobj newobj 1]
299 lappend result [catch {testdoubleobj div10 1} msg]
301 } {{} 1 {expected floating-point number but got ""}}
303 test obj-18.1 {DupDoubleInternalRep} {
305 lappend result [testdoubleobj set 1 17.1]
306 lappend result [testobj duplicate 1 2] ;# uses DupDoubleInternalRep
307 lappend result [testdoubleobj get 2]
310 test obj-19.1 {SetDoubleFromAny, int to double special case} {
312 lappend result [testintobj set 1 1234]
313 lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
314 lappend result [testobj type 1]
315 } {1234 12340.0 double}
316 test obj-19.2 {SetDoubleFromAny, boolean to double special case} {
318 lappend result [testbooleanobj set 1 1]
319 lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
320 lappend result [testobj type 1]
322 test obj-19.3 {SetDoubleFromAny, recompute string rep then parse it} {
324 lappend result [testintobj set 1 456]
325 lappend result [testintobj div10 1]
326 lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
327 lappend result [testobj type 1]
328 } {456 45 450.0 double}
329 test obj-19.4 {SetDoubleFromAny, error parsing string} {
331 lappend result [teststringobj set 1 abc]
332 lappend result [catch {testdoubleobj mult10 1} msg]
334 } {abc 1 {expected floating-point number but got "abc"}}
335 test obj-19.5 {SetDoubleFromAny, error parsing string} {
337 lappend result [teststringobj set 1 x1.0]
338 lappend result [catch {testdoubleobj mult10 1} msg]
340 } {x1.0 1 {expected floating-point number but got "x1.0"}}
341 test obj-19.6 {SetDoubleFromAny, error converting from "empty string"} {
343 lappend result [testobj newobj 1]
344 lappend result [catch {testdoubleobj div10 1} msg]
346 } {{} 1 {expected floating-point number but got ""}}
348 test obj-20.1 {UpdateStringOfDouble} {
350 lappend result [testdoubleobj set 1 3.14159]
351 lappend result [testdoubleobj mult10 1]
352 lappend result [testdoubleobj get 1] ;# must update string rep
353 } {3.14159 31.4159 31.4159}
355 test obj-21.1 {Tcl_NewIntObj} {
357 lappend result [testobj freeallvars]
358 lappend result [testintobj set 1 55]
359 lappend result [testobj type 1]
360 lappend result [testobj refcount 1]
363 test obj-22.1 {Tcl_SetIntObj, existing "empty string" object} {
365 lappend result [testobj freeallvars]
366 lappend result [testobj newobj 1]
367 lappend result [testintobj set 1 77] ;# makes existing obj int
368 lappend result [testobj type 1]
369 lappend result [testobj refcount 1]
371 test obj-22.2 {Tcl_SetIntObj, existing non-"empty string" object} {
373 lappend result [testobj freeallvars]
374 lappend result [testdoubleobj set 1 12.34]
375 lappend result [testintobj set 1 77] ;# makes existing obj int
376 lappend result [testobj type 1]
377 lappend result [testobj refcount 1]
378 } {{} 12.34 77 int 2}
380 test obj-23.1 {Tcl_GetIntFromObj, existing int object} {
382 lappend result [testintobj set 1 22]
383 lappend result [testintobj mult10 1] ;# gets existing int rep
385 test obj-23.2 {Tcl_GetIntFromObj, convert to int} {
387 lappend result [testintobj set 1 477]
388 lappend result [testintobj div10 1] ;# must convert to bool
389 lappend result [testobj type 1]
391 test obj-23.3 {Tcl_GetIntFromObj, error converting to int} {
393 lappend result [teststringobj set 1 abc]
394 lappend result [catch {testintobj mult10 1} msg]
396 } {abc 1 {expected integer but got "abc"}}
397 test obj-23.4 {Tcl_GetIntFromObj, error converting from "empty string"} {
399 lappend result [testobj newobj 1]
400 lappend result [catch {testintobj div10 1} msg]
402 } {{} 1 {expected integer but got ""}}
403 test obj-23.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {nonPortable} {
405 lappend result [testobj newobj 1]
406 lappend result [testintobj inttoobigtest 1]
409 test obj-24.1 {DupIntInternalRep} {
411 lappend result [testintobj set 1 23]
412 lappend result [testobj duplicate 1 2] ;# uses DupIntInternalRep
413 lappend result [testintobj get 2]
416 test obj-25.1 {SetIntFromAny, int to int special case} {
418 lappend result [testintobj set 1 1234]
419 lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
420 lappend result [testobj type 1]
422 test obj-25.2 {SetIntFromAny, boolean to int special case} {
424 lappend result [testbooleanobj set 1 1]
425 lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
426 lappend result [testobj type 1]
428 test obj-25.3 {SetIntFromAny, recompute string rep then parse it} {
430 lappend result [testintobj set 1 456]
431 lappend result [testintobj div10 1]
432 lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
433 lappend result [testobj type 1]
435 test obj-25.4 {SetIntFromAny, error parsing string} {
437 lappend result [teststringobj set 1 abc]
438 lappend result [catch {testintobj mult10 1} msg]
440 } {abc 1 {expected integer but got "abc"}}
441 test obj-25.5 {SetIntFromAny, error parsing string} {
443 lappend result [teststringobj set 1 x17]
444 lappend result [catch {testintobj mult10 1} msg]
446 } {x17 1 {expected integer but got "x17"}}
447 test obj-25.6 {SetIntFromAny, integer too large} {nonPortable} {
449 lappend result [teststringobj set 1 123456789012345678901]
450 lappend result [catch {testintobj mult10 1} msg]
452 } {123456789012345678901 1 {integer value too large to represent}}
453 test obj-25.7 {SetIntFromAny, error converting from "empty string"} {
455 lappend result [testobj newobj 1]
456 lappend result [catch {testintobj div10 1} msg]
458 } {{} 1 {expected integer but got ""}}
460 test obj-26.1 {UpdateStringOfInt} {
462 lappend result [testintobj set 1 512]
463 lappend result [testintobj mult10 1]
464 lappend result [testintobj get 1] ;# must update string rep
467 test obj-27.1 {Tcl_NewLongObj} {
469 lappend result [testobj freeallvars]
470 testintobj setmaxlong 1
471 lappend result [testintobj ismaxlong 1]
472 lappend result [testobj type 1]
473 lappend result [testobj refcount 1]
476 test obj-28.1 {Tcl_SetLongObj, existing "empty string" object} {
478 lappend result [testobj freeallvars]
479 lappend result [testobj newobj 1]
480 lappend result [testintobj setlong 1 77] ;# makes existing obj long int
481 lappend result [testobj type 1]
482 lappend result [testobj refcount 1]
484 test obj-28.2 {Tcl_SetLongObj, existing non-"empty string" object} {
486 lappend result [testobj freeallvars]
487 lappend result [testdoubleobj set 1 12.34]
488 lappend result [testintobj setlong 1 77] ;# makes existing obj long int
489 lappend result [testobj type 1]
490 lappend result [testobj refcount 1]
491 } {{} 12.34 77 int 2}
493 test obj-29.1 {Tcl_GetLongFromObj, existing long integer object} {
495 lappend result [testintobj setlong 1 22]
496 lappend result [testintobj mult10 1] ;# gets existing long int rep
498 test obj-29.2 {Tcl_GetLongFromObj, convert to long} {
500 lappend result [testintobj setlong 1 477]
501 lappend result [testintobj div10 1] ;# must convert to bool
502 lappend result [testobj type 1]
504 test obj-29.3 {Tcl_GetLongFromObj, error converting to long integer} {
506 lappend result [teststringobj set 1 abc]
507 lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
509 } {abc 1 {expected integer but got "abc"}}
510 test obj-29.4 {Tcl_GetLongFromObj, error converting from "empty string"} {
512 lappend result [testobj newobj 1]
513 lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
515 } {{} 1 {expected integer but got ""}}
517 test obj-30.1 {Ref counting and object deletion, simple types} {
519 lappend result [testobj freeallvars]
520 lappend result [testintobj set 1 1024]
521 lappend result [testobj assign 1 2] ;# vars 1 and 2 share the int obj
522 lappend result [testobj type 2]
523 lappend result [testobj refcount 1]
524 lappend result [testobj refcount 2]
525 lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
526 lappend result [testobj type 2]
527 lappend result [testobj refcount 1]
528 lappend result [testobj refcount 2]
529 } {{} 1024 1024 int 4 4 0 boolean 3 2}
534 ::tcltest::cleanupTests