diff options
Diffstat (limited to 'tests/stdlib/tstrutils.nim')
-rw-r--r-- | tests/stdlib/tstrutils.nim | 277 |
1 files changed, 244 insertions, 33 deletions
diff --git a/tests/stdlib/tstrutils.nim b/tests/stdlib/tstrutils.nim index a6248d1e3..35f6bc669 100644 --- a/tests/stdlib/tstrutils.nim +++ b/tests/stdlib/tstrutils.nim @@ -1,9 +1,11 @@ discard """ - targets: "c cpp js" + matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on" """ import std/strutils - +from stdtest/testutils import disableVm +import std/assertions +import std/private/jsutils # xxx each instance of `disableVm` and `when not defined js:` should eventually be fixed template rejectParse(e) = @@ -12,10 +14,6 @@ template rejectParse(e) = raise newException(AssertionDefect, "This was supposed to fail: $#!" % astToStr(e)) except ValueError: discard -template disableVm(body) = - when nimvm: discard - else: body - template main() = block: # strip doAssert strip(" ha ") == "ha" @@ -55,6 +53,15 @@ template main() = doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "] doAssert s.split(' ', maxsplit = 1) == @["", "this is an example "] doAssert s.split(" ", maxsplit = 4) == @["", "this", "is", "an", "example "] + # Empty string: + doAssert "".split() == @[""] + doAssert "".split(" ") == @[""] + doAssert "".split({' '}) == @[""] + # Empty separators: + doAssert "".split({}) == @[""] + doAssert "".split("") == @[""] + doAssert s.split({}) == @[s] + doAssert s.split("") == @[s] block: # splitLines let fixture = "a\nb\rc\r\nd" @@ -65,12 +72,21 @@ template main() = block: # rsplit doAssert rsplit("foo bar", seps = Whitespace) == @["foo", "bar"] doAssert rsplit(" foo bar", seps = Whitespace, maxsplit = 1) == @[" foo", "bar"] - doAssert rsplit(" foo bar ", seps = Whitespace, maxsplit = 1) == @[ - " foo bar", ""] + doAssert rsplit(" foo bar ", seps = Whitespace, maxsplit = 1) == @[" foo bar", ""] doAssert rsplit(":foo:bar", sep = ':') == @["", "foo", "bar"] doAssert rsplit(":foo:bar", sep = ':', maxsplit = 2) == @["", "foo", "bar"] doAssert rsplit(":foo:bar", sep = ':', maxsplit = 3) == @["", "foo", "bar"] doAssert rsplit("foothebar", sep = "the") == @["foo", "bar"] + # Empty string: + doAssert "".rsplit() == @[""] + doAssert "".rsplit(" ") == @[""] + doAssert "".rsplit({' '}) == @[""] + # Empty separators: + let s = " this is an example " + doAssert "".rsplit({}) == @[""] + doAssert "".rsplit("") == @[""] + doAssert s.rsplit({}) == @[s] + doAssert s.rsplit("") == @[s] block: # splitWhitespace let s = " this is an example " @@ -202,7 +218,30 @@ template main() = s.removePrefix("") doAssert s == "\r\n\r\nhello" - block: # delete + block: # delete(slice) + var s = "0123456789ABCDEFGH" + delete(s, 4 .. 5) + doAssert s == "01236789ABCDEFGH" + delete(s, s.len-1 .. s.len-1) + doAssert s == "01236789ABCDEFG" + delete(s, 0..0) + doAssert s == "1236789ABCDEFG" + s = "" + doAssertRaises(IndexDefect): delete(s, 0..0) + doAssert s == "" + s = "abc" + doAssertRaises(IndexDefect): delete(s, -1 .. -2) + doAssertRaises(IndexDefect): delete(s, 2..3) + doAssertRaises(IndexDefect): delete(s, 3..2) + delete(s, 2..2) + doAssert s == "ab" + delete(s, 1..0) + doAssert s == "ab" + delete(s, 0..0) + doAssert s == "b" + + block: # delete(first, last) + {.push warning[deprecated]:off.} var s = "0123456789ABCDEFGH" delete(s, 4, 5) doAssert s == "01236789ABCDEFGH" @@ -210,20 +249,88 @@ template main() = doAssert s == "01236789ABCDEFG" delete(s, 0, 0) doAssert s == "1236789ABCDEFG" + {.pop.} block: # find - doAssert "0123456789ABCDEFGH".find('A') == 10 - doAssert "0123456789ABCDEFGH".find('A', 5) == 10 - doAssert "0123456789ABCDEFGH".find('A', 5, 10) == 10 - doAssert "0123456789ABCDEFGH".find('A', 5, 9) == -1 - doAssert "0123456789ABCDEFGH".find("A") == 10 - doAssert "0123456789ABCDEFGH".find("A", 5) == 10 - doAssert "0123456789ABCDEFGH".find("A", 5, 10) == 10 - doAssert "0123456789ABCDEFGH".find("A", 5, 9) == -1 - doAssert "0123456789ABCDEFGH".find({'A'..'C'}) == 10 - doAssert "0123456789ABCDEFGH".find({'A'..'C'}, 5) == 10 - doAssert "0123456789ABCDEFGH".find({'A'..'C'}, 5, 10) == 10 - doAssert "0123456789ABCDEFGH".find({'A'..'C'}, 5, 9) == -1 + const haystack: string = "0123456789ABCDEFGH" + doAssert haystack.find('A') == 10 + doAssert haystack.find('A', 5) == 10 + doAssert haystack.find('A', 5, 10) == 10 + doAssert haystack.find('A', 5, 9) == -1 + doAssert haystack.find("A") == 10 + doAssert haystack.find("A", 5) == 10 + doAssert haystack.find("A", 5, 10) == 10 + doAssert haystack.find("A", 5, 9) == -1 + doAssert haystack.find({'A'..'C'}) == 10 + doAssert haystack.find({'A'..'C'}, 5) == 10 + doAssert haystack.find({'A'..'C'}, 5, 10) == 10 + doAssert haystack.find({'A'..'C'}, 5, 9) == -1 + doAssert haystack.find('A', 0, 0) == -1 # search limited to the first char + doAssert haystack.find('A', 5, 0) == -1 # last < start + doAssert haystack.find('A', 5, 4) == -1 # last < start + + block: + const haystack: string = "ABCABABABABCAB" + doAssert haystack.len == 14 + + # only last argument + doAssert haystack.find("ABC") == 0 + doAssert haystack.find("ABC", last=13) == 0 # after the second ABC + doAssert haystack.find("ABC", last=5) == 0 # before the second ABC + + # only start argument + doAssert haystack.find("ABC", start=0) == 0 + doAssert haystack.find("ABC", start=1) == 9 + doAssert haystack.find("ABC", start=9) == 9 + doAssert haystack.find("ABC", start=10) == -1 + + # both start and last arguments + doAssert haystack.find("ABC", start=0, last=14) == 0 + doAssert haystack.find("ABC", start=0, last=13) == 0 + doAssert haystack.find("ABC", start=0, last=12) == 0 + doAssert haystack.find("ABC", start=1, last=13) == 9 + doAssert haystack.find("ABC", start=1, last=12) == 9 + doAssert haystack.find("ABC", start=1, last=11) == 9 + doAssert haystack.find("ABC", start=1, last=10) == -1 + + doAssert "".find("/") == -1 + doAssert "/".find("/") == 0 + doAssert "/".find("//") == -1 + doAssert "///".find("//", start=3) == -1 + + # searching for empty string + doAssert "".find("") == 0 + doAssert "abc".find("") == 0 + doAssert "abc".find("", start=1) == 1 + doAssert "abc".find("", start=2) == 2 + doAssert "abc".find("", start=3) == 3 + doAssert "abc".find("", start=4) == -1 + doAssert "abc".find("", start=400) == -1 + doAssert "abc".find("", start=1, last=3) == 1 + doAssert "abc".find("", start=1, last=2) == 1 + doAssert "abc".find("", start=1, last=1) == 1 + doAssert "abc".find("", start=1, last=0) == 1 + doAssert "abc".find("", start=1, last = -1) == 1 + + # when last <= start, searching for non-empty string + block: + let last: int = -1 # searching through whole line + doAssert "abcd".find("ab", start=0, last=last) == 0 + doAssert "abcd".find("ab", start=1, last=last) == -1 + doAssert "abcd".find("bc", start=1, last=last) == 1 + doAssert "abcd".find("bc", start=2, last=last) == -1 + block: + let last: int = 0 + doAssert "abcd".find("ab", start=0, last=last) == -1 + doAssert "abcd".find("ab", start=1, last=last) == -1 + doAssert "abcd".find("bc", start=1, last=last) == -1 + doAssert "abcd".find("bc", start=2, last=last) == -1 + block: + let last: int = 1 + doAssert "abcd".find("ab", start=0, last=last) == 0 + doAssert "abcd".find("ab", start=1, last=last) == -1 + doAssert "abcd".find("bc", start=1, last=last) == -1 + doAssert "abcd".find("bc", start=2, last=last) == -1 block: # rfind doAssert "0123456789ABCDEFGAH".rfind('A') == 17 @@ -247,6 +354,70 @@ template main() = doAssert "/1/2/3".rfind('/', last=1) == 0 doAssert "/1/2/3".rfind('0') == -1 + block: + const haystack: string = "ABCABABABABCAB" + doAssert haystack.len == 14 + doAssert haystack.rfind("ABC") == 9 + doAssert haystack.rfind("ABC", last=13) == 9 + doAssert haystack.rfind("ABC", last=12) == 9 + doAssert haystack.rfind("ABC", last=11) == 9 + doAssert haystack.rfind("ABC", last=10) == 0 + + doAssert haystack.rfind("ABC", start=0) == 9 + doAssert haystack.rfind("ABC", start=1) == 9 + doAssert haystack.rfind("ABC", start=9) == 9 + doAssert haystack.rfind("ABC", start=10) == -1 + + doAssert haystack.rfind("ABC", start=0, last=13) == 9 + doAssert haystack.rfind("ABC", start=0, last=12) == 9 + doAssert haystack.rfind("ABC", start=0, last=11) == 9 + doAssert haystack.rfind("ABC", start=0, last=10) == 0 + doAssert haystack.rfind("ABC", start=1, last=10) == -1 + + doAssert "".rfind("/") == -1 + doAssert "/".rfind("/") == 0 + doAssert "/".rfind("//") == -1 + doAssert "///".rfind("//", start=3) == -1 + + # searching for empty string + doAssert "".rfind("") == 0 + doAssert "abc".rfind("") == 3 + doAssert "abc".rfind("", start=1) == 3 + doAssert "abc".rfind("", start=2) == 3 + doAssert "abc".rfind("", start=3) == 3 + doAssert "abc".rfind("", start=4) == 4 + doAssert "abc".rfind("", start=400) == 400 + + doAssert "abc".rfind("", start=1, last=3) == 3 + doAssert "abc".rfind("", start=1, last=2) == 2 + doAssert "abc".rfind("", start=1, last=1) == 1 + # This returns the start index instead of the last index + # because start > last + doAssert "abc".rfind("", start=1, last=0) == 1 + doAssert "abc".rfind("", start=1, last = -1) == 3 + + doAssert "abc".rfind("", start=0, last=0) == 0 + + # when last <= start, searching for non-empty string + block: + let last: int = -1 + doAssert "abcd".rfind("ab", start=0, last=last) == 0 + doAssert "abcd".rfind("ab", start=1, last=last) == -1 + doAssert "abcd".rfind("bc", start=1, last=last) == 1 + doAssert "abcd".rfind("bc", start=2, last=last) == -1 + block: + let last: int = 0 + doAssert "abcd".rfind("ab", start=0, last=last) == -1 + doAssert "abcd".rfind("ab", start=1, last=last) == -1 + doAssert "abcd".rfind("bc", start=1, last=last) == -1 + doAssert "abcd".rfind("bc", start=2, last=last) == -1 + block: + let last: int = 1 + doAssert "abcd".rfind("ab", start=0, last=last) == 0 + doAssert "abcd".rfind("ab", start=1, last=last) == -1 + doAssert "abcd".rfind("bc", start=1, last=last) == -1 + doAssert "abcd".rfind("bc", start=2, last=last) == -1 + block: # trimZeros var x = "1200" x.trimZeros() @@ -281,6 +452,9 @@ template main() = x = "1e0" x.trimZeros() doAssert x == "1e0" + x = "1.23" + x.trimZeros() + doAssert x == "1.23" block: # countLines proc assertCountLines(s: string) = doAssert s.countLines == s.splitLines.len @@ -353,8 +527,9 @@ template main() = block: # toHex doAssert(toHex(100i16, 32) == "00000000000000000000000000000064") - doAssert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C") - when not defined js: + whenJsNoBigInt64: discard + do: + doAssert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C") doAssert(toHex(high(uint64)) == "FFFFFFFFFFFFFFFF") doAssert(toHex(high(uint64), 16) == "FFFFFFFFFFFFFFFF") doAssert(toHex(high(uint64), 32) == "0000000000000000FFFFFFFFFFFFFFFF") @@ -375,11 +550,12 @@ template main() = doAssert(spaces(0) == "") block: # toBin, toOct - block:# bug #11369 + whenJsNoBigInt64: # bug #11369 + discard + do: var num: int64 = -1 - when not defined js: - doAssert num.toBin(64) == "1111111111111111111111111111111111111111111111111111111111111111" - doAssert num.toOct(24) == "001777777777777777777777" + doAssert num.toBin(64) == "1111111111111111111111111111111111111111111111111111111111111111" + doAssert num.toOct(24) == "001777777777777777777777" block: # replace doAssert "oo".replace("", "abc") == "oo" @@ -440,6 +616,17 @@ template main() = let g = parseEnum[Foo]("Bar", A) doAssert g == A + block: # bug #19463 + const CAMPAIGN_TABLE = "wikientries_campaign" + const CHARACTER_TABLE = "wikientries_character" + + type Tables = enum + a = CAMPAIGN_TABLE, + b = CHARACTER_TABLE, + + let myA = CAMPAIGN_TABLE + doAssert $parseEnum[Tables](myA) == "wikientries_campaign" + block: # check enum defined in block type Bar = enum @@ -492,11 +679,22 @@ template main() = doAssert b == f2 doAssert c == f3 - block: # parseEnum TODO: merge above - type MyEnum = enum enA, enB, enC, enuD, enE - doAssert parseEnum[MyEnum]("enu_D") == enuD - - doAssert parseEnum("invalid enum value", enC) == enC + block: + type MyEnum = enum enA, enB, enC, enuD, enE + doAssert parseEnum[MyEnum]("enu_D") == enuD + + doAssert parseEnum("invalid enum value", enC) == enC + + block: # issue #22726 + type SomeEnum = enum A, B, C + + proc assignEnum(dest: var enum, s: string) = + type ty = typeof(dest) + dest = parseEnum[ty](s) + + var v: SomeEnum + v.assignEnum("A") + doAssert v == A block: # indentation doAssert 0 == indentation """ @@ -575,7 +773,8 @@ bar block: # formatSize disableVm: - when not defined(js): + whenJsNoBigInt64: discard + do: doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" # <=== bug #8231 doAssert formatSize((2.234*1024*1024).int) == "2.234MiB" doAssert formatSize(4096) == "4KiB" @@ -698,5 +897,17 @@ bar doAssert s.endsWith('a') == false doAssert s.endsWith('\0') == false + block: # nimIdentNormalize + doAssert nimIdentNormalize("") == "" + doAssert nimIdentNormalize("foo") == "foo" + doAssert nimIdentNormalize("foo_bar") == "foobar" + doAssert nimIdentNormalize("Foo_bar") == "Foobar" + doAssert nimIdentNormalize("_Foo_bar") == "_foobar" + + block: # bug #19500 + doAssert "abc \0 def".find("def") == 6 + doAssert "abc \0 def".find('d') == 6 + + static: main() main() |