sl@0: # Commands covered: none sl@0: # sl@0: # This file contains tests for the procedures in tclStringObj.c sl@0: # that implement the Tcl type manager for the string type. 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) 1995-1997 Sun Microsystems, Inc. sl@0: # Copyright (c) 1998-1999 by Scriptics Corporation. sl@0: # sl@0: # See the file "license.terms" for information on usage and redistribution sl@0: # of this file, and for a DISCLAIMER OF ALL WARRANTIES. sl@0: # sl@0: # RCS: @(#) $Id: stringObj.test,v 1.15 2003/02/11 18:46:33 hobbs Exp $ sl@0: sl@0: if {[lsearch [namespace children] ::tcltest] == -1} { sl@0: package require tcltest sl@0: namespace import -force ::tcltest::* sl@0: } sl@0: sl@0: if {[info commands testobj] == {}} { sl@0: puts "This application hasn't been compiled with the \"testobj\"" sl@0: puts "command, so I can't test the Tcl type and object support." sl@0: ::tcltest::cleanupTests sl@0: return sl@0: } sl@0: sl@0: test stringObj-1.1 {string type registration} { sl@0: set t [testobj types] sl@0: set first [string first "string" $t] sl@0: set result [expr {$first != -1}] sl@0: } {1} sl@0: sl@0: test stringObj-2.1 {Tcl_NewStringObj} { sl@0: set result "" sl@0: lappend result [testobj freeallvars] sl@0: lappend result [teststringobj set 1 abcd] sl@0: lappend result [testobj type 1] sl@0: lappend result [testobj refcount 1] sl@0: } {{} abcd string 2} sl@0: sl@0: test stringObj-3.1 {Tcl_SetStringObj, existing "empty string" object} { sl@0: set result "" sl@0: lappend result [testobj freeallvars] sl@0: lappend result [testobj newobj 1] sl@0: lappend result [teststringobj set 1 xyz] ;# makes existing obj a string sl@0: lappend result [testobj type 1] sl@0: lappend result [testobj refcount 1] sl@0: } {{} {} xyz string 2} sl@0: test stringObj-3.2 {Tcl_SetStringObj, existing non-"empty string" object} { sl@0: set result "" sl@0: lappend result [testobj freeallvars] sl@0: lappend result [testintobj set 1 512] sl@0: lappend result [teststringobj set 1 foo] ;# makes existing obj a string sl@0: lappend result [testobj type 1] sl@0: lappend result [testobj refcount 1] sl@0: } {{} 512 foo string 2} sl@0: sl@0: test stringObj-4.1 {Tcl_SetObjLength procedure, string gets shorter} { sl@0: testobj freeallvars sl@0: teststringobj set 1 test sl@0: teststringobj setlength 1 3 sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {3 4 tes} sl@0: test stringObj-4.2 {Tcl_SetObjLength procedure, string gets longer} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abcdef sl@0: teststringobj setlength 1 10 sl@0: list [teststringobj length 1] [teststringobj length2 1] sl@0: } {10 10} sl@0: test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abcdef sl@0: teststringobj append 1 xyzq -1 sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {10 20 abcdefxyzq} sl@0: test stringObj-4.4 {Tcl_SetObjLength procedure, "expty string", length 0} { sl@0: testobj freeallvars sl@0: testobj newobj 1 sl@0: teststringobj setlength 1 0 sl@0: list [teststringobj length2 1] [teststringobj get 1] sl@0: } {0 {}} sl@0: sl@0: test stringObj-5.1 {Tcl_AppendToObj procedure, type conversion} { sl@0: testobj freeallvars sl@0: testintobj set2 1 43 sl@0: teststringobj append 1 xyz -1 sl@0: teststringobj get 1 sl@0: } {43xyz} sl@0: test stringObj-5.2 {Tcl_AppendToObj procedure, length calculation} { sl@0: testobj freeallvars sl@0: teststringobj set 1 {x y } sl@0: teststringobj append 1 bbCCddEE 4 sl@0: teststringobj append 1 123 -1 sl@0: teststringobj get 1 sl@0: } {x y bbCC123} sl@0: test stringObj-5.3 {Tcl_AppendToObj procedure, reallocating space} { sl@0: testobj freeallvars sl@0: teststringobj set 1 xyz sl@0: teststringobj setlength 1 15 sl@0: teststringobj setlength 1 2 sl@0: set result {} sl@0: teststringobj append 1 1234567890123 -1 sl@0: lappend result [teststringobj length 1] [teststringobj length2 1] sl@0: teststringobj setlength 1 10 sl@0: teststringobj append 1 abcdef -1 sl@0: lappend result [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {15 15 16 32 xy12345678abcdef} sl@0: sl@0: test stringObj-6.1 {Tcl_AppendStringsToObj procedure, type conversion} { sl@0: testobj freeallvars sl@0: teststringobj set2 1 [list a b] sl@0: teststringobj appendstrings 1 xyz { 1234 } foo sl@0: teststringobj get 1 sl@0: } {a bxyz 1234 foo} sl@0: test stringObj-6.2 {Tcl_AppendStringsToObj procedure, counting space} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abc sl@0: teststringobj appendstrings 1 sl@0: list [teststringobj length 1] [teststringobj get 1] sl@0: } {3 abc} sl@0: test stringObj-6.3 {Tcl_AppendStringsToObj procedure, counting space} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abc sl@0: teststringobj appendstrings 1 {} {} {} {} sl@0: list [teststringobj length 1] [teststringobj get 1] sl@0: } {3 abc} sl@0: test stringObj-6.4 {Tcl_AppendStringsToObj procedure, counting space} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abc sl@0: teststringobj appendstrings 1 { 123 } abcdefg sl@0: list [teststringobj length 1] [teststringobj get 1] sl@0: } {15 {abc 123 abcdefg}} sl@0: test stringObj-6.5 {Tcl_AppendStringsToObj procedure, don't double space if initial string empty} { sl@0: testobj freeallvars sl@0: testobj newobj 1 sl@0: teststringobj appendstrings 1 123 abcdefg sl@0: list [teststringobj length 1] [teststringobj length2 1] [teststringobj get 1] sl@0: } {10 10 123abcdefg} sl@0: test stringObj-6.6 {Tcl_AppendStringsToObj procedure, space reallocation} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abc sl@0: teststringobj setlength 1 10 sl@0: teststringobj setlength 1 2 sl@0: teststringobj appendstrings 1 34567890 sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {10 10 ab34567890} sl@0: test stringObj-6.7 {Tcl_AppendStringsToObj procedure, space reallocation} { sl@0: testobj freeallvars sl@0: teststringobj set 1 abc sl@0: teststringobj setlength 1 10 sl@0: teststringobj setlength 1 2 sl@0: teststringobj appendstrings 1 34567890x sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {11 22 ab34567890x} sl@0: test stringObj-6.8 {Tcl_AppendStringsToObj procedure, object totally empty} { sl@0: testobj freeallvars sl@0: testobj newobj 1 sl@0: teststringobj appendstrings 1 {} sl@0: list [teststringobj length2 1] [teststringobj get 1] sl@0: } {0 {}} sl@0: sl@0: test stringObj-7.1 {SetStringFromAny procedure} { sl@0: testobj freeallvars sl@0: teststringobj set2 1 [list a b] sl@0: teststringobj append 1 x -1 sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {4 8 {a bx}} sl@0: test stringObj-7.2 {SetStringFromAny procedure, null object} { sl@0: testobj freeallvars sl@0: testobj newobj 1 sl@0: teststringobj appendstrings 1 {} sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj get 1] sl@0: } {0 0 {}} sl@0: test stringObj-7.3 {SetStringFromAny called with non-string obj} { sl@0: set x 2345 sl@0: list [incr x] [testobj objtype $x] [string index $x end] \ sl@0: [testobj objtype $x] sl@0: } {2346 int 6 string} sl@0: test stringObj-7.4 {SetStringFromAny called with string obj} { sl@0: set x "abcdef" sl@0: list [string length $x] [testobj objtype $x] \ sl@0: [string length $x] [testobj objtype $x] sl@0: } {6 string 6 string} sl@0: sl@0: test stringObj-8.1 {DupStringInternalRep procedure} { sl@0: testobj freeallvars sl@0: teststringobj set 1 {} sl@0: teststringobj append 1 abcde -1 sl@0: testobj duplicate 1 2 sl@0: list [teststringobj length 1] [teststringobj length2 1] \ sl@0: [teststringobj ualloc 1] [teststringobj get 1] \ sl@0: [teststringobj length 2] [teststringobj length2 2] \ sl@0: [teststringobj ualloc 2] [teststringobj get 2] sl@0: } {5 10 0 abcde 5 5 0 abcde} sl@0: test stringObj-8.2 {DupUnicodeInternalRep, mixed width chars} { sl@0: set x abcï¿®ghi sl@0: string length $x sl@0: set y $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x "®¿ï"] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string string abcï¿®ghi®¿ï abcï¿®ghi string string} sl@0: test stringObj-8.3 {DupUnicodeInternalRep, mixed width chars} { sl@0: set x abcï¿®ghi sl@0: set y $x sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x "®¿ï"] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string string abcï¿®ghi®¿ï abcï¿®ghi string string} sl@0: test stringObj-8.4 {DupUnicodeInternalRep, all byte-size chars} { sl@0: set x abcdefghi sl@0: string length $x sl@0: set y $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x jkl] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string string abcdefghijkl abcdefghi string string} sl@0: test stringObj-8.5 {DupUnicodeInternalRep, all byte-size chars} { sl@0: set x abcdefghi sl@0: set y $x sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x jkl] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string string abcdefghijkl abcdefghi string string} sl@0: sl@0: test stringObj-9.1 {TclAppendObjToObj, mixed src & dest} { sl@0: set x abcï¿®ghi sl@0: set y ®¿ï sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string none abcï¿®ghi®¿ï ®¿ï string none} sl@0: test stringObj-9.2 {TclAppendObjToObj, mixed src & dest} { sl@0: set x abcï¿®ghi sl@0: string length $x sl@0: list [testobj objtype $x] [append x $x] [testobj objtype $x] \ sl@0: [append x $x] [testobj objtype $x] sl@0: } {string abcï¿®ghiabcï¿®ghi string\ sl@0: abcï¿®ghiabcï¿®ghiabcï¿®ghiabcï¿®ghi\ sl@0: string} sl@0: test stringObj-9.3 {TclAppendObjToObj, mixed src & 1-byte dest} { sl@0: set x abcdefghi sl@0: set y ®¿ï sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string none abcdefghi®¿ï ®¿ï string none} sl@0: test stringObj-9.4 {TclAppendObjToObj, 1-byte src & dest} { sl@0: set x abcdefghi sl@0: set y jkl sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string none abcdefghijkl jkl string none} sl@0: test stringObj-9.5 {TclAppendObjToObj, 1-byte src & dest} { sl@0: set x abcdefghi sl@0: string length $x sl@0: list [testobj objtype $x] [append x $x] [testobj objtype $x] \ sl@0: [append x $x] [testobj objtype $x] sl@0: } {string abcdefghiabcdefghi string abcdefghiabcdefghiabcdefghiabcdefghi\ sl@0: string} sl@0: test stringObj-9.6 {TclAppendObjToObj, 1-byte src & mixed dest} { sl@0: set x abcï¿®ghi sl@0: set y jkl sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string none abcï¿®ghijkl jkl string none} sl@0: test stringObj-9.7 {TclAppendObjToObj, integer src & dest} { sl@0: set x [expr {4 * 5}] sl@0: set y [expr {4 + 5}] sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [testobj objtype $x] [append x $y] [testobj objtype $x] \ sl@0: [testobj objtype $y] sl@0: } {int int 209 string 2099 string int} sl@0: test stringObj-9.8 {TclAppendObjToObj, integer src & dest} { sl@0: set x [expr {4 * 5}] sl@0: list [testobj objtype $x] [append x $x] [testobj objtype $x] \ sl@0: [append x $x] [testobj objtype $x] sl@0: } {int 2020 string 20202020 string} sl@0: test stringObj-9.9 {TclAppendObjToObj, integer src & 1-byte dest} { sl@0: set x abcdefghi sl@0: set y [expr {4 + 5}] sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string int abcdefghi9 9 string int} sl@0: test stringObj-9.10 {TclAppendObjToObj, integer src & mixed dest} { sl@0: set x abcï¿®ghi sl@0: set y [expr {4 + 5}] sl@0: string length $x sl@0: list [testobj objtype $x] [testobj objtype $y] [append x $y] \ sl@0: [set y] [testobj objtype $x] [testobj objtype $y] sl@0: } {string int abcï¿®ghi9 9 string int} sl@0: test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} { sl@0: # bug 2678, in <=8.2.0, the second obj (the one to append) in sl@0: # Tcl_AppendObjToObj was not correctly checked to see if it was sl@0: # all one byte chars, so a unicode string would be added as one sl@0: # byte chars. sl@0: set x abcdef sl@0: set len [string length $x] sl@0: set y aübåcï sl@0: set len [string length $y] sl@0: append x $y sl@0: string length $x sl@0: set q {} sl@0: for {set i 0} {$i < 12} {incr i} { sl@0: lappend q [string index $x $i] sl@0: } sl@0: set q sl@0: } {a b c d e f a ü b å c ï} sl@0: sl@0: test stringObj-10.1 {Tcl_GetRange with all byte-size chars} { sl@0: set x "abcdef" sl@0: list [testobj objtype $x] [set y [string range $x 1 end-1]] \ sl@0: [testobj objtype $x] [testobj objtype $y] sl@0: } [list none bcde string string] sl@0: test stringObj-10.2 {Tcl_GetRange with some mixed width chars} { sl@0: # Because this test does not use \uXXXX notation below instead of sl@0: # hardcoding the values, it may fail in multibyte locales. However, sl@0: # we need to test that the parser produces untyped objects even when there sl@0: # are high-ASCII characters in the input (like "ï"). I don't know what sl@0: # else to do but inline those characters here. sl@0: set x "abcïïdef" sl@0: list [testobj objtype $x] [set y [string range $x 1 end-1]] \ sl@0: [testobj objtype $x] [testobj objtype $y] sl@0: } [list none "bc\u00EF\u00EFde" string string] sl@0: test stringObj-10.3 {Tcl_GetRange with some mixed width chars} { sl@0: # set x "abcïïdef" sl@0: # Use \uXXXX notation below instead of hardcoding the values, otherwise sl@0: # the test will fail in multibyte locales. sl@0: set x "abc\u00EF\u00EFdef" sl@0: string length $x sl@0: list [testobj objtype $x] [set y [string range $x 1 end-1]] \ sl@0: [testobj objtype $x] [testobj objtype $y] sl@0: } [list string "bc\u00EF\u00EFde" string string] sl@0: test stringObj-10.4 {Tcl_GetRange with some mixed width chars} { sl@0: # set a "ïa¿b®cï¿d®" sl@0: # Use \uXXXX notation below instead of hardcoding the values, otherwise sl@0: # the test will fail in multibyte locales. sl@0: set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" sl@0: set result [list] sl@0: while {[string length $a] > 0} { sl@0: set a [string range $a 1 end-1] sl@0: lappend result $a sl@0: } sl@0: set result sl@0: } [list a\u00BFb\u00AEc\u00EF\u00BFd \ sl@0: \u00BFb\u00AEc\u00EF\u00BF \ sl@0: b\u00AEc\u00EF \ sl@0: \u00AEc \ sl@0: {}] sl@0: sl@0: test stringObj-11.1 {UpdateStringOfString} { sl@0: set x 2345 sl@0: list [string index $x end] [testobj objtype $x] [incr x] \ sl@0: [testobj objtype $x] sl@0: } {5 string 2346 int} sl@0: sl@0: test stringObj-12.1 {Tcl_GetUniChar with byte-size chars} { sl@0: set x "abcdefghi" sl@0: list [string index $x 0] [string index $x 1] sl@0: } {a b} sl@0: test stringObj-12.2 {Tcl_GetUniChar with byte-size chars} { sl@0: set x "abcdefghi" sl@0: list [string index $x 3] [string index $x end] sl@0: } {d i} sl@0: test stringObj-12.3 {Tcl_GetUniChar with byte-size chars} { sl@0: set x "abcdefghi" sl@0: list [string index $x end] [string index $x end-1] sl@0: } {i h} sl@0: test stringObj-12.4 {Tcl_GetUniChar with mixed width chars} { sl@0: string index "ïa¿b®c®¿dï" 0 sl@0: } "ï" sl@0: test stringObj-12.5 {Tcl_GetUniChar} { sl@0: set x "ïa¿b®c®¿dï" sl@0: list [string index $x 4] [string index $x 0] sl@0: } {® ï} sl@0: test stringObj-12.6 {Tcl_GetUniChar} { sl@0: string index "ïa¿b®cï¿d®" end sl@0: } "®" sl@0: sl@0: test stringObj-13.1 {Tcl_GetCharLength with byte-size chars} { sl@0: set a "" sl@0: list [string length $a] [string length $a] sl@0: } {0 0} sl@0: test stringObj-13.2 {Tcl_GetCharLength with byte-size chars} { sl@0: string length "a" sl@0: } 1 sl@0: test stringObj-13.3 {Tcl_GetCharLength with byte-size chars} { sl@0: set a "abcdef" sl@0: list [string length $a] [string length $a] sl@0: } {6 6} sl@0: test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} { sl@0: string length "®" sl@0: } 1 sl@0: test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} { sl@0: # string length "○○" sl@0: # Use \uXXXX notation below instead of hardcoding the values, otherwise sl@0: # the test will fail in multibyte locales. sl@0: string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE" sl@0: } 6 sl@0: test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} { sl@0: # set a "ïa¿b®cï¿d®" sl@0: # Use \uXXXX notation below instead of hardcoding the values, otherwise sl@0: # the test will fail in multibyte locales. sl@0: set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" sl@0: list [string length $a] [string length $a] sl@0: } {10 10} sl@0: test stringObj-13.7 {Tcl_GetCharLength with identity nulls} { sl@0: # SF bug #684699 sl@0: string length [encoding convertfrom identity \x00] sl@0: } 1 sl@0: test stringObj-13.8 {Tcl_GetCharLength with identity nulls} { sl@0: string length [encoding convertfrom identity \x01\x00\x02] sl@0: } 3 sl@0: sl@0: test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} { sl@0: teststringobj set 1 foo sl@0: teststringobj getunicode 1 sl@0: teststringobj append 1 bar -1 sl@0: teststringobj getunicode 1 sl@0: teststringobj append 1 bar -1 sl@0: teststringobj setlength 1 0 sl@0: teststringobj append 1 bar -1 sl@0: teststringobj get 1 sl@0: } {bar} sl@0: sl@0: testobj freeallvars sl@0: sl@0: # cleanup sl@0: ::tcltest::cleanupTests sl@0: return