go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/starlark/testdata/string.star (about) 1 # Tests of Starlark 'string' 2 # option:set 3 4 load("assert.star", "assert") 5 6 # raw string literals: 7 assert.eq(r"a\bc", "a\\bc") 8 9 # truth 10 assert.true("abc") 11 assert.true(chr(0)) 12 assert.true(not "") 13 14 # str + str 15 assert.eq("a" + "b" + "c", "abc") 16 17 # str * int, int * str 18 assert.eq("abc" * 0, "") 19 assert.eq("abc" * -1, "") 20 assert.eq("abc" * 1, "abc") 21 assert.eq("abc" * 5, "abcabcabcabcabc") 22 assert.eq(0 * "abc", "") 23 assert.eq(-1 * "abc", "") 24 assert.eq(1 * "abc", "abc") 25 assert.eq(5 * "abc", "abcabcabcabcabc") 26 assert.fails(lambda: 1.0 * "abc", "unknown.*float \\* str") 27 assert.fails(lambda: "abc" * (1000000 * 1000000), "repeat count 1000000000000 too large") 28 assert.fails(lambda: "abc" * 1000000 * 1000000, "excessive repeat \\(3000000 \\* 1000000 elements") 29 30 # len 31 assert.eq(len("Hello, 世界!"), 14) 32 assert.eq(len("𐐷"), 4) # U+10437 has a 4-byte UTF-8 encoding (and a 2-code UTF-16 encoding) 33 34 # chr & ord 35 assert.eq(chr(65), "A") # 1-byte UTF-8 encoding 36 assert.eq(chr(1049), "Й") # 2-byte UTF-8 encoding 37 assert.eq(chr(0x1F63F), "😿") # 4-byte UTF-8 encoding 38 assert.fails(lambda: chr(-1), "Unicode code point -1 out of range \\(<0\\)") 39 assert.fails(lambda: chr(0x110000), "Unicode code point U\\+110000 out of range \\(>0x10FFFF\\)") 40 assert.eq(ord("A"), 0x41) 41 assert.eq(ord("Й"), 0x419) 42 assert.eq(ord("世"), 0x4e16) 43 assert.eq(ord("😿"), 0x1F63F) 44 assert.eq(ord("Й"[1:]), 0xFFFD) # = Unicode replacement character 45 assert.fails(lambda: ord("abc"), "string encodes 3 Unicode code points, want 1") 46 assert.fails(lambda: ord(""), "string encodes 0 Unicode code points, want 1") 47 assert.fails(lambda: ord("😿"[1:]), "string encodes 3 Unicode code points, want 1") # 3 x 0xFFFD 48 49 # string.codepoint_ords 50 assert.eq(type("abcЙ😿".codepoint_ords()), "string.codepoints") 51 assert.eq(str("abcЙ😿".codepoint_ords()), '"abcЙ😿".codepoint_ords()') 52 assert.eq(list("abcЙ😿".codepoint_ords()), [97, 98, 99, 1049, 128575]) 53 assert.eq(list(("A" + "😿Z"[1:]).codepoint_ords()), [ord("A"), 0xFFFD, 0xFFFD, 0xFFFD, ord("Z")]) 54 assert.eq(list("".codepoint_ords()), []) 55 assert.fails(lambda: "abcЙ😿".codepoint_ords()[2], "unhandled index") # not indexable 56 assert.fails(lambda: len("abcЙ😿".codepoint_ords()), "no len") # unknown length 57 58 # string.codepoints 59 assert.eq(type("abcЙ😿".codepoints()), "string.codepoints") 60 assert.eq(str("abcЙ😿".codepoints()), '"abcЙ😿".codepoints()') 61 assert.eq(list("abcЙ😿".codepoints()), ["a", "b", "c", "Й", "😿"]) 62 assert.eq(list(("A" + "😿Z"[1:]).codepoints()), ["A", "�", "�", "�", "Z"]) 63 assert.eq(list("".codepoints()), []) 64 assert.fails(lambda: "abcЙ😿".codepoints()[2], "unhandled index") # not indexable 65 assert.fails(lambda: len("abcЙ😿".codepoints()), "no len") # unknown length 66 67 # string.elem_ords 68 assert.eq(type("abcЙ😿".elem_ords()), "string.elems") 69 assert.eq(str("abcЙ😿".elem_ords()), '"abcЙ😿".elem_ords()') 70 assert.eq(list("abcЙ😿".elem_ords()), [97, 98, 99, 208, 153, 240, 159, 152, 191]) 71 assert.eq(list(("A" + "😿Z"[1:]).elem_ords()), [65, 159, 152, 191, 90]) 72 assert.eq(list("".elem_ords()), []) 73 assert.eq("abcЙ😿".elem_ords()[2], 99) # indexable 74 assert.eq(len("abcЙ😿".elem_ords()), 9) # known length 75 76 # string.elems (1-byte substrings, which are invalid text) 77 assert.eq(type("abcЙ😿".elems()), "string.elems") 78 assert.eq(str("abcЙ😿".elems()), '"abcЙ😿".elems()') 79 assert.eq( 80 repr(list("abcЙ😿".elems())), 81 r'["a", "b", "c", "\xd0", "\x99", "\xf0", "\x9f", "\x98", "\xbf"]', 82 ) 83 assert.eq( 84 repr(list(("A" + "😿Z"[1:]).elems())), 85 r'["A", "\x9f", "\x98", "\xbf", "Z"]', 86 ) 87 assert.eq(list("".elems()), []) 88 assert.eq("abcЙ😿".elems()[2], "c") # indexable 89 assert.eq(len("abcЙ😿".elems()), 9) # known length 90 91 # indexing, x[i] 92 assert.eq("Hello, 世界!"[0], "H") 93 assert.eq(repr("Hello, 世界!"[7]), r'"\xe4"') # (invalid text) 94 assert.eq("Hello, 世界!"[13], "!") 95 assert.fails(lambda: "abc"[-4], "out of range") 96 assert.eq("abc"[-3], "a") 97 assert.eq("abc"[-2], "b") 98 assert.eq("abc"[-1], "c") 99 assert.eq("abc"[0], "a") 100 assert.eq("abc"[1], "b") 101 assert.eq("abc"[2], "c") 102 assert.fails(lambda: "abc"[4], "out of range") 103 104 # x[i] = ... 105 def f(): 106 "abc"[1] = "B" 107 108 assert.fails(f, "string.*does not support.*assignment") 109 110 # slicing, x[i:j] 111 assert.eq("abc"[:], "abc") 112 assert.eq("abc"[-4:], "abc") 113 assert.eq("abc"[-3:], "abc") 114 assert.eq("abc"[-2:], "bc") 115 assert.eq("abc"[-1:], "c") 116 assert.eq("abc"[0:], "abc") 117 assert.eq("abc"[1:], "bc") 118 assert.eq("abc"[2:], "c") 119 assert.eq("abc"[3:], "") 120 assert.eq("abc"[4:], "") 121 assert.eq("abc"[:-4], "") 122 assert.eq("abc"[:-3], "") 123 assert.eq("abc"[:-2], "a") 124 assert.eq("abc"[:-1], "ab") 125 assert.eq("abc"[:0], "") 126 assert.eq("abc"[:1], "a") 127 assert.eq("abc"[:2], "ab") 128 assert.eq("abc"[:3], "abc") 129 assert.eq("abc"[:4], "abc") 130 assert.eq("abc"[1:2], "b") 131 assert.eq("abc"[2:1], "") 132 assert.eq(repr("😿"[:1]), r'"\xf0"') # (invalid text) 133 134 # non-unit strides 135 assert.eq("abcd"[0:4:1], "abcd") 136 assert.eq("abcd"[::2], "ac") 137 assert.eq("abcd"[1::2], "bd") 138 assert.eq("abcd"[4:0:-1], "dcb") 139 assert.eq("banana"[7::-2], "aaa") 140 assert.eq("banana"[6::-2], "aaa") 141 assert.eq("banana"[5::-2], "aaa") 142 assert.eq("banana"[4::-2], "nnb") 143 assert.eq("banana"[::-1], "ananab") 144 assert.eq("banana"[None:None:-2], "aaa") 145 assert.fails(lambda: "banana"[1.0::], "invalid start index: got float, want int") 146 assert.fails(lambda: "banana"[:"":], "invalid end index: got string, want int") 147 assert.fails(lambda: "banana"[:"":True], "invalid slice step: got bool, want int") 148 149 # in, not in 150 assert.true("oo" in "food") 151 assert.true("ox" not in "food") 152 assert.true("" in "food") 153 assert.true("" in "") 154 assert.fails(lambda: 1 in "", "requires string as left operand") 155 assert.fails(lambda: "" in 1, "unknown binary op: string in int") 156 157 # ==, != 158 assert.eq("hello", "he" + "llo") 159 assert.ne("hello", "Hello") 160 161 # hash must follow java.lang.String.hashCode. 162 wanthash = { 163 "": 0, 164 "\0" * 100: 0, 165 "hello": 99162322, 166 "world": 113318802, 167 "Hello, 世界!": 417292677, 168 } 169 gothash = {s: hash(s) for s in wanthash} 170 assert.eq(gothash, wanthash) 171 172 # TODO(adonovan): ordered comparisons 173 174 # string % tuple formatting 175 assert.eq("A %d %x Z" % (123, 456), "A 123 1c8 Z") 176 assert.eq("A %(foo)d %(bar)s Z" % {"foo": 123, "bar": "hi"}, "A 123 hi Z") 177 assert.eq("%s %r" % ("hi", "hi"), 'hi "hi"') # TODO(adonovan): use ''-quotation 178 assert.eq("%%d %d" % 1, "%d 1") 179 assert.fails(lambda: "%d %d" % 1, "not enough arguments for format string") 180 assert.fails(lambda: "%d %d" % (1, 2, 3), "too many arguments for format string") 181 assert.fails(lambda: "" % 1, "too many arguments for format string") 182 183 # %c 184 assert.eq("%c" % 65, "A") 185 assert.eq("%c" % 0x3b1, "α") 186 assert.eq("%c" % "A", "A") 187 assert.eq("%c" % "α", "α") 188 assert.fails(lambda: "%c" % "abc", "requires a single-character string") 189 assert.fails(lambda: "%c" % "", "requires a single-character string") 190 assert.fails(lambda: "%c" % 65.0, "requires int or single-character string") 191 assert.fails(lambda: "%c" % 10000000, "requires a valid Unicode code point") 192 assert.fails(lambda: "%c" % -1, "requires a valid Unicode code point") 193 # TODO(adonovan): more tests 194 195 # str.format 196 assert.eq("a{}b".format(123), "a123b") 197 assert.eq("a{}b{}c{}d{}".format(1, 2, 3, 4), "a1b2c3d4") 198 assert.eq("a{{b".format(), "a{b") 199 assert.eq("a}}b".format(), "a}b") 200 assert.eq("a{{b}}c".format(), "a{b}c") 201 assert.eq("a{x}b{y}c{}".format(1, x = 2, y = 3), "a2b3c1") 202 assert.fails(lambda: "a{z}b".format(x = 1), "keyword z not found") 203 assert.fails(lambda: "{-1}".format(1), "keyword -1 not found") 204 assert.fails(lambda: "{-0}".format(1), "keyword -0 not found") 205 assert.fails(lambda: "{+0}".format(1), "keyword \\+0 not found") 206 assert.fails(lambda: "{+1}".format(1), "keyword \\+1 not found") # starlark-go/issues/114 207 assert.eq("{0000000000001}".format(0, 1), "1") 208 assert.eq("{012}".format(*range(100)), "12") # decimal, despite leading zeros 209 assert.fails(lambda: "{0,1} and {1}".format(1, 2), "keyword 0,1 not found") 210 assert.fails(lambda: "a{123}b".format(), "tuple index out of range") 211 assert.fails(lambda: "a{}b{}c".format(1), "tuple index out of range") 212 assert.eq("a{010}b".format(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), "a10b") # index is decimal 213 assert.fails(lambda: "a{}b{1}c".format(1, 2), "cannot switch from automatic field numbering to manual") 214 assert.eq("a{!s}c".format("b"), "abc") 215 assert.eq("a{!r}c".format("b"), r'a"b"c') 216 assert.eq("a{x!r}c".format(x = "b"), r'a"b"c') 217 assert.fails(lambda: "{x!}".format(x = 1), "unknown conversion") 218 assert.fails(lambda: "{x!:}".format(x = 1), "unknown conversion") 219 assert.fails(lambda: "{a.b}".format(1), "syntax x.y is not supported") 220 assert.fails(lambda: "{a[0]}".format(1), "syntax a\\[i\\] is not supported") 221 assert.fails(lambda: "{ {} }".format(1), "nested replacement fields not supported") 222 assert.fails(lambda: "{{}".format(1), "single '}' in format") 223 assert.fails(lambda: "{}}".format(1), "single '}' in format") 224 assert.fails(lambda: "}}{".format(1), "unmatched '{' in format") 225 assert.fails(lambda: "}{{".format(1), "single '}' in format") 226 227 # str.split, str.rsplit 228 assert.eq("a.b.c.d".split("."), ["a", "b", "c", "d"]) 229 assert.eq("a.b.c.d".rsplit("."), ["a", "b", "c", "d"]) 230 assert.eq("a.b.c.d".split(".", -1), ["a", "b", "c", "d"]) 231 assert.eq("a.b.c.d".rsplit(".", -1), ["a", "b", "c", "d"]) 232 assert.eq("a.b.c.d".split(".", 0), ["a.b.c.d"]) 233 assert.eq("a.b.c.d".rsplit(".", 0), ["a.b.c.d"]) 234 assert.eq("a.b.c.d".split(".", 1), ["a", "b.c.d"]) 235 assert.eq("a.b.c.d".rsplit(".", 1), ["a.b.c", "d"]) 236 assert.eq("a.b.c.d".split(".", 2), ["a", "b", "c.d"]) 237 assert.eq("a.b.c.d".rsplit(".", 2), ["a.b", "c", "d"]) 238 assert.eq(" ".split("."), [" "]) 239 assert.eq(" ".rsplit("."), [" "]) 240 241 # {,r}split on white space: 242 assert.eq(" a bc\n def \t ghi".split(), ["a", "bc", "def", "ghi"]) 243 assert.eq(" a bc\n def \t ghi".split(None), ["a", "bc", "def", "ghi"]) 244 assert.eq(" a bc\n def \t ghi".split(None, 0), ["a bc\n def \t ghi"]) 245 assert.eq(" a bc\n def \t ghi".rsplit(None, 0), [" a bc\n def \t ghi"]) 246 assert.eq(" a bc\n def \t ghi".split(None, 1), ["a", "bc\n def \t ghi"]) 247 assert.eq(" a bc\n def \t ghi".rsplit(None, 1), [" a bc\n def", "ghi"]) 248 assert.eq(" a bc\n def \t ghi".split(None, 2), ["a", "bc", "def \t ghi"]) 249 assert.eq(" a bc\n def \t ghi".rsplit(None, 2), [" a bc", "def", "ghi"]) 250 assert.eq(" a bc\n def \t ghi".split(None, 3), ["a", "bc", "def", "ghi"]) 251 assert.eq(" a bc\n def \t ghi".rsplit(None, 3), [" a", "bc", "def", "ghi"]) 252 assert.eq(" a bc\n def \t ghi".split(None, 4), ["a", "bc", "def", "ghi"]) 253 assert.eq(" a bc\n def \t ghi".rsplit(None, 4), ["a", "bc", "def", "ghi"]) 254 assert.eq(" a bc\n def \t ghi".rsplit(None, 5), ["a", "bc", "def", "ghi"]) 255 256 assert.eq(" a bc\n def \t ghi ".split(None, 0), ["a bc\n def \t ghi "]) 257 assert.eq(" a bc\n def \t ghi ".rsplit(None, 0), [" a bc\n def \t ghi"]) 258 assert.eq(" a bc\n def \t ghi ".split(None, 1), ["a", "bc\n def \t ghi "]) 259 assert.eq(" a bc\n def \t ghi ".rsplit(None, 1), [" a bc\n def", "ghi"]) 260 261 # Observe the algorithmic difference when splitting on spaces versus other delimiters. 262 assert.eq("--aa--bb--cc--".split("-", 0), ["--aa--bb--cc--"]) # contrast this 263 assert.eq(" aa bb cc ".split(None, 0), ["aa bb cc "]) # with this 264 assert.eq("--aa--bb--cc--".rsplit("-", 0), ["--aa--bb--cc--"]) # ditto this 265 assert.eq(" aa bb cc ".rsplit(None, 0), [" aa bb cc"]) # and this 266 267 # 268 assert.eq("--aa--bb--cc--".split("-", 1), ["", "-aa--bb--cc--"]) 269 assert.eq("--aa--bb--cc--".rsplit("-", 1), ["--aa--bb--cc-", ""]) 270 assert.eq(" aa bb cc ".split(None, 1), ["aa", "bb cc "]) 271 assert.eq(" aa bb cc ".rsplit(None, 1), [" aa bb", "cc"]) 272 273 # 274 assert.eq("--aa--bb--cc--".split("-", -1), ["", "", "aa", "", "bb", "", "cc", "", ""]) 275 assert.eq("--aa--bb--cc--".rsplit("-", -1), ["", "", "aa", "", "bb", "", "cc", "", ""]) 276 assert.eq(" aa bb cc ".split(None, -1), ["aa", "bb", "cc"]) 277 assert.eq(" aa bb cc ".rsplit(None, -1), ["aa", "bb", "cc"]) 278 assert.eq(" ".split(None), []) 279 assert.eq(" ".rsplit(None), []) 280 281 assert.eq("localhost:80".rsplit(":", 1)[-1], "80") 282 283 # str.splitlines 284 assert.eq("\nabc\ndef".splitlines(), ["", "abc", "def"]) 285 assert.eq("\nabc\ndef".splitlines(True), ["\n", "abc\n", "def"]) 286 assert.eq("\nabc\ndef\n".splitlines(), ["", "abc", "def"]) 287 assert.eq("\nabc\ndef\n".splitlines(True), ["\n", "abc\n", "def\n"]) 288 assert.eq("".splitlines(), []) # 289 assert.eq("".splitlines(True), []) # 290 assert.eq("a".splitlines(), ["a"]) 291 assert.eq("a".splitlines(True), ["a"]) 292 assert.eq("\n".splitlines(), [""]) 293 assert.eq("\n".splitlines(True), ["\n"]) 294 assert.eq("a\n".splitlines(), ["a"]) 295 assert.eq("a\n".splitlines(True), ["a\n"]) 296 assert.eq("a\n\nb".splitlines(), ["a", "", "b"]) 297 assert.eq("a\n\nb".splitlines(True), ["a\n", "\n", "b"]) 298 assert.eq("a\nb\nc".splitlines(), ["a", "b", "c"]) 299 assert.eq("a\nb\nc".splitlines(True), ["a\n", "b\n", "c"]) 300 assert.eq("a\nb\nc\n".splitlines(), ["a", "b", "c"]) 301 assert.eq("a\nb\nc\n".splitlines(True), ["a\n", "b\n", "c\n"]) 302 303 # str.{,l,r}strip 304 assert.eq(" \tfoo\n ".strip(), "foo") 305 assert.eq(" \tfoo\n ".lstrip(), "foo\n ") 306 assert.eq(" \tfoo\n ".rstrip(), " \tfoo") 307 assert.eq(" \tfoo\n ".strip(""), "foo") 308 assert.eq(" \tfoo\n ".lstrip(""), "foo\n ") 309 assert.eq(" \tfoo\n ".rstrip(""), " \tfoo") 310 assert.eq("blah.h".strip("b.h"), "la") 311 assert.eq("blah.h".lstrip("b.h"), "lah.h") 312 assert.eq("blah.h".rstrip("b.h"), "bla") 313 314 # str.count 315 assert.eq("banana".count("a"), 3) 316 assert.eq("banana".count("a", 2), 2) 317 assert.eq("banana".count("a", -4, -2), 1) 318 assert.eq("banana".count("a", 1, 4), 2) 319 assert.eq("banana".count("a", 0, -100), 0) 320 321 # str.{starts,ends}with 322 assert.true("foo".endswith("oo")) 323 assert.true(not "foo".endswith("x")) 324 assert.true("foo".startswith("fo")) 325 assert.true(not "foo".startswith("x")) 326 assert.fails(lambda: "foo".startswith(1), "got int.*want string") 327 328 # 329 assert.true("abc".startswith(("a", "A"))) 330 assert.true("ABC".startswith(("a", "A"))) 331 assert.true(not "ABC".startswith(("b", "B"))) 332 assert.fails(lambda: "123".startswith((1, 2)), "got int, for element 0") 333 assert.fails(lambda: "123".startswith(["3"]), "got list") 334 335 # 336 assert.true("abc".endswith(("c", "C"))) 337 assert.true("ABC".endswith(("c", "C"))) 338 assert.true(not "ABC".endswith(("b", "B"))) 339 assert.fails(lambda: "123".endswith((1, 2)), "got int, for element 0") 340 assert.fails(lambda: "123".endswith(["3"]), "got list") 341 342 # start/end 343 assert.true("abc".startswith("bc", 1)) 344 assert.true(not "abc".startswith("b", 999)) 345 assert.true("abc".endswith("ab", None, -1)) 346 assert.true(not "abc".endswith("b", None, -999)) 347 348 # str.replace 349 assert.eq("banana".replace("a", "o", 1), "bonana") 350 assert.eq("banana".replace("a", "o"), "bonono") 351 # TODO(adonovan): more tests 352 353 # str.{,r}find 354 assert.eq("foofoo".find("oo"), 1) 355 assert.eq("foofoo".find("ox"), -1) 356 assert.eq("foofoo".find("oo", 2), 4) 357 assert.eq("foofoo".rfind("oo"), 4) 358 assert.eq("foofoo".rfind("ox"), -1) 359 assert.eq("foofoo".rfind("oo", 1, 4), 1) 360 assert.eq("foofoo".find(""), 0) 361 assert.eq("foofoo".rfind(""), 6) 362 363 # str.{,r}partition 364 assert.eq("foo/bar/wiz".partition("/"), ("foo", "/", "bar/wiz")) 365 assert.eq("foo/bar/wiz".rpartition("/"), ("foo/bar", "/", "wiz")) 366 assert.eq("foo/bar/wiz".partition("."), ("foo/bar/wiz", "", "")) 367 assert.eq("foo/bar/wiz".rpartition("."), ("", "", "foo/bar/wiz")) 368 assert.fails(lambda: "foo/bar/wiz".partition(""), "empty separator") 369 assert.fails(lambda: "foo/bar/wiz".rpartition(""), "empty separator") 370 371 assert.eq("?".join(["foo", "a/b/c.go".rpartition("/")[0]]), "foo?a/b") 372 373 # str.is{alpha,...} 374 def test_predicates(): 375 predicates = ["alnum", "alpha", "digit", "lower", "space", "title", "upper"] 376 table = { 377 "Hello, World!": "title", 378 "hello, world!": "lower", 379 "base64": "alnum lower", 380 "HAL-9000": "upper", 381 "Catch-22": "title", 382 "": "", 383 "\n\t\r": "space", 384 "abc": "alnum alpha lower", 385 "ABC": "alnum alpha upper", 386 "123": "alnum digit", 387 "DŽLJ": "alnum alpha upper", 388 "DžLj": "alnum alpha", 389 "Dž Lj": "title", 390 "džlj": "alnum alpha lower", 391 } 392 for str, want in table.items(): 393 got = " ".join([name for name in predicates if getattr(str, "is" + name)()]) 394 if got != want: 395 assert.fail("%r matched [%s], want [%s]" % (str, got, want)) 396 397 test_predicates() 398 399 # Strings are not iterable. 400 # ok 401 assert.eq(len("abc"), 3) # len 402 assert.true("a" in "abc") # str in str 403 assert.eq("abc"[1], "b") # indexing 404 405 # not ok 406 def for_string(): 407 for x in "abc": 408 pass 409 410 def args(*args): 411 return args 412 413 assert.fails(lambda: args(*"abc"), "must be iterable, not string") # varargs 414 assert.fails(lambda: list("abc"), "got string, want iterable") # list(str) 415 assert.fails(lambda: tuple("abc"), "got string, want iterable") # tuple(str) 416 assert.fails(lambda: set("abc"), "got string, want iterable") # set(str) 417 assert.fails(lambda: set() | "abc", "unknown binary op: set | string") # set union 418 assert.fails(lambda: enumerate("ab"), "got string, want iterable") # enumerate 419 assert.fails(lambda: sorted("abc"), "got string, want iterable") # sorted 420 assert.fails(lambda: [].extend("bc"), "got string, want iterable") # list.extend 421 assert.fails(lambda: ",".join("abc"), "got string, want iterable") # string.join 422 assert.fails(lambda: dict(["ab"]), "not iterable .*string") # dict 423 assert.fails(for_string, "string value is not iterable") # for loop 424 assert.fails(lambda: [x for x in "abc"], "string value is not iterable") # comprehension 425 assert.fails(lambda: all("abc"), "got string, want iterable") # all 426 assert.fails(lambda: any("abc"), "got string, want iterable") # any 427 assert.fails(lambda: reversed("abc"), "got string, want iterable") # reversed 428 assert.fails(lambda: zip("ab", "cd"), "not iterable: string") # zip 429 430 # str.join 431 assert.eq(",".join([]), "") 432 assert.eq(",".join(["a"]), "a") 433 assert.eq(",".join(["a", "b"]), "a,b") 434 assert.eq(",".join(["a", "b", "c"]), "a,b,c") 435 assert.eq(",".join(("a", "b", "c")), "a,b,c") 436 assert.eq("".join(("a", "b", "c")), "abc") 437 assert.fails(lambda: "".join(None), "got NoneType, want iterable") 438 assert.fails(lambda: "".join(["one", 2]), "join: in list, want string, got int") 439 440 # TODO(adonovan): tests for: {,r}index 441 442 # str.capitalize 443 assert.eq("hElLo, WoRlD!".capitalize(), "Hello, world!") 444 assert.eq("por qué".capitalize(), "Por qué") 445 assert.eq("¿Por qué?".capitalize(), "¿por qué?") 446 447 # str.lower 448 assert.eq("hElLo, WoRlD!".lower(), "hello, world!") 449 assert.eq("por qué".lower(), "por qué") 450 assert.eq("¿Por qué?".lower(), "¿por qué?") 451 assert.eq("LJUBOVIĆ".lower(), "ljubović") 452 assert.true("dženan ljubović".islower()) 453 454 # str.upper 455 assert.eq("hElLo, WoRlD!".upper(), "HELLO, WORLD!") 456 assert.eq("por qué".upper(), "POR QUÉ") 457 assert.eq("¿Por qué?".upper(), "¿POR QUÉ?") 458 assert.eq("ljubović".upper(), "LJUBOVIĆ") 459 assert.true("DŽENAN LJUBOVIĆ".isupper()) 460 461 # str.title 462 assert.eq("hElLo, WoRlD!".title(), "Hello, World!") 463 assert.eq("por qué".title(), "Por Qué") 464 assert.eq("¿Por qué?".title(), "¿Por Qué?") 465 assert.eq("ljubović".title(), "Ljubović") 466 assert.true("Dženan Ljubović".istitle()) 467 assert.true(not "DŽenan LJubović".istitle()) 468 469 # method spell check 470 assert.fails(lambda: "".starts_with, "no .starts_with field.*did you mean .startswith") 471 assert.fails(lambda: "".StartsWith, "no .StartsWith field.*did you mean .startswith") 472 assert.fails(lambda: "".fin, "no .fin field.*.did you mean .find") 473 474 475 # removesuffix 476 assert.eq("Apricot".removesuffix("cot"), "Apri") 477 assert.eq("Apricot".removesuffix("Cot"), "Apricot") 478 assert.eq("Apricot".removesuffix("t"), "Aprico") 479 assert.eq("a".removesuffix(""), "a") 480 assert.eq("".removesuffix(""), "") 481 assert.eq("".removesuffix("a"), "") 482 assert.eq("Apricot".removesuffix("co"), "Apricot") 483 assert.eq("Apricotcot".removesuffix("cot"), "Apricot") 484 485 # removeprefix 486 assert.eq("Apricot".removeprefix("Apr"), "icot") 487 assert.eq("Apricot".removeprefix("apr"), "Apricot") 488 assert.eq("Apricot".removeprefix("A"), "pricot") 489 assert.eq("a".removeprefix(""), "a") 490 assert.eq("".removeprefix(""), "") 491 assert.eq("".removeprefix("a"), "") 492 assert.eq("Apricot".removeprefix("pr"), "Apricot") 493 assert.eq("AprApricot".removeprefix("Apr"), "Apricot")