tstrutil.nim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. # test the new strutils module
  2. import
  3. strutils
  4. template rejectParse(e) =
  5. try:
  6. discard e
  7. raise newException(AssertionDefect, "This was supposed to fail: $#!" % astToStr(e))
  8. except ValueError: discard
  9. proc testStrip() =
  10. doAssert strip(" ha ") == "ha"
  11. proc testRemoveSuffix =
  12. var s = "hello\n\r"
  13. s.removeSuffix
  14. assert s == "hello"
  15. s.removeSuffix
  16. assert s == "hello"
  17. s = "hello\n\n"
  18. s.removeSuffix
  19. assert s == "hello"
  20. s = "hello\r"
  21. s.removeSuffix
  22. assert s == "hello"
  23. s = "hello \n there"
  24. s.removeSuffix
  25. assert s == "hello \n there"
  26. s = "hello"
  27. s.removeSuffix("llo")
  28. assert s == "he"
  29. s.removeSuffix('e')
  30. assert s == "h"
  31. s = "hellos"
  32. s.removeSuffix({'s','z'})
  33. assert s == "hello"
  34. s.removeSuffix({'l','o'})
  35. assert s == "he"
  36. s = "aeiou"
  37. s.removeSuffix("")
  38. assert s == "aeiou"
  39. s = ""
  40. s.removeSuffix("")
  41. assert s == ""
  42. s = " "
  43. s.removeSuffix
  44. assert s == " "
  45. s = " "
  46. s.removeSuffix("")
  47. assert s == " "
  48. s = " "
  49. s.removeSuffix(" ")
  50. assert s == " "
  51. s = " "
  52. s.removeSuffix(' ')
  53. assert s == ""
  54. # Contrary to Chomp in other languages
  55. # empty string does not change behaviour
  56. s = "hello\r\n\r\n"
  57. s.removeSuffix("")
  58. assert s == "hello\r\n\r\n"
  59. proc testRemovePrefix =
  60. var s = "\n\rhello"
  61. s.removePrefix
  62. assert s == "hello"
  63. s.removePrefix
  64. assert s == "hello"
  65. s = "\n\nhello"
  66. s.removePrefix
  67. assert s == "hello"
  68. s = "\rhello"
  69. s.removePrefix
  70. assert s == "hello"
  71. s = "hello \n there"
  72. s.removePrefix
  73. assert s == "hello \n there"
  74. s = "hello"
  75. s.removePrefix("hel")
  76. assert s == "lo"
  77. s.removePrefix('l')
  78. assert s == "o"
  79. s = "hellos"
  80. s.removePrefix({'h','e'})
  81. assert s == "llos"
  82. s.removePrefix({'l','o'})
  83. assert s == "s"
  84. s = "aeiou"
  85. s.removePrefix("")
  86. assert s == "aeiou"
  87. s = ""
  88. s.removePrefix("")
  89. assert s == ""
  90. s = " "
  91. s.removePrefix
  92. assert s == " "
  93. s = " "
  94. s.removePrefix("")
  95. assert s == " "
  96. s = " "
  97. s.removePrefix(" ")
  98. assert s == " "
  99. s = " "
  100. s.removePrefix(' ')
  101. assert s == ""
  102. # Contrary to Chomp in other languages
  103. # empty string does not change behaviour
  104. s = "\r\n\r\nhello"
  105. s.removePrefix("")
  106. assert s == "\r\n\r\nhello"
  107. proc main() =
  108. testStrip()
  109. testRemoveSuffix()
  110. testRemovePrefix()
  111. var ret: seq[string] # or use `toSeq`
  112. for p in split("/home/a1:xyz:/usr/bin", {':'}): ret.add p
  113. doAssert ret == @["/home/a1", "xyz", "/usr/bin"]
  114. proc testDelete =
  115. var s = "0123456789ABCDEFGH"
  116. delete(s, 4, 5)
  117. assert s == "01236789ABCDEFGH"
  118. delete(s, s.len-1, s.len-1)
  119. assert s == "01236789ABCDEFG"
  120. delete(s, 0, 0)
  121. assert s == "1236789ABCDEFG"
  122. proc testFind =
  123. assert "0123456789ABCDEFGH".find('A') == 10
  124. assert "0123456789ABCDEFGH".find('A', 5) == 10
  125. assert "0123456789ABCDEFGH".find('A', 5, 10) == 10
  126. assert "0123456789ABCDEFGH".find('A', 5, 9) == -1
  127. assert "0123456789ABCDEFGH".find("A") == 10
  128. assert "0123456789ABCDEFGH".find("A", 5) == 10
  129. assert "0123456789ABCDEFGH".find("A", 5, 10) == 10
  130. assert "0123456789ABCDEFGH".find("A", 5, 9) == -1
  131. assert "0123456789ABCDEFGH".find({'A'..'C'}) == 10
  132. assert "0123456789ABCDEFGH".find({'A'..'C'}, 5) == 10
  133. assert "0123456789ABCDEFGH".find({'A'..'C'}, 5, 10) == 10
  134. assert "0123456789ABCDEFGH".find({'A'..'C'}, 5, 9) == -1
  135. proc testRFind =
  136. assert "0123456789ABCDEFGAH".rfind('A') == 17
  137. assert "0123456789ABCDEFGAH".rfind('A', last=13) == 10
  138. assert "0123456789ABCDEFGAH".rfind('H', last=13) == -1
  139. assert "0123456789ABCDEFGAH".rfind("A") == 17
  140. assert "0123456789ABCDEFGAH".rfind("A", last=13) == 10
  141. assert "0123456789ABCDEFGAH".rfind("H", last=13) == -1
  142. assert "0123456789ABCDEFGAH".rfind({'A'..'C'}) == 17
  143. assert "0123456789ABCDEFGAH".rfind({'A'..'C'}, last=13) == 12
  144. assert "0123456789ABCDEFGAH".rfind({'G'..'H'}, last=13) == -1
  145. assert "0123456789ABCDEFGAH".rfind('A', start=18) == -1
  146. assert "0123456789ABCDEFGAH".rfind('A', start=11, last=17) == 17
  147. assert "0123456789ABCDEFGAH".rfind("0", start=0) == 0
  148. assert "0123456789ABCDEFGAH".rfind("0", start=1) == -1
  149. assert "0123456789ABCDEFGAH".rfind("H", start=11) == 18
  150. assert "0123456789ABCDEFGAH".rfind({'0'..'9'}, start=5) == 9
  151. assert "0123456789ABCDEFGAH".rfind({'0'..'9'}, start=10) == -1
  152. proc testTrimZeros() =
  153. var x = "1200"
  154. x.trimZeros()
  155. assert x == "1200"
  156. x = "120.0"
  157. x.trimZeros()
  158. assert x == "120"
  159. x = "0."
  160. x.trimZeros()
  161. assert x == "0"
  162. x = "1.0e2"
  163. x.trimZeros()
  164. assert x == "1e2"
  165. x = "78.90"
  166. x.trimZeros()
  167. assert x == "78.9"
  168. x = "1.23e4"
  169. x.trimZeros()
  170. assert x == "1.23e4"
  171. x = "1.01"
  172. x.trimZeros()
  173. assert x == "1.01"
  174. x = "1.1001"
  175. x.trimZeros()
  176. assert x == "1.1001"
  177. x = "0.0"
  178. x.trimZeros()
  179. assert x == "0"
  180. x = "0.01"
  181. x.trimZeros()
  182. assert x == "0.01"
  183. x = "1e0"
  184. x.trimZeros()
  185. assert x == "1e0"
  186. proc testSplitLines() =
  187. let fixture = "a\nb\rc\r\nd"
  188. assert len(fixture.splitLines) == 4
  189. assert splitLines(fixture) == @["a", "b", "c", "d"]
  190. assert splitLines(fixture, keepEol=true) == @["a\n", "b\r", "c\r\n", "d"]
  191. proc testCountLines =
  192. proc assertCountLines(s: string) = assert s.countLines == s.splitLines.len
  193. assertCountLines("")
  194. assertCountLines("\n")
  195. assertCountLines("\n\n")
  196. assertCountLines("abc")
  197. assertCountLines("abc\n123")
  198. assertCountLines("abc\n123\n")
  199. assertCountLines("\nabc\n123")
  200. assertCountLines("\nabc\n123\n")
  201. proc testParseInts =
  202. # binary
  203. assert "0b1111".parseBinInt == 15
  204. assert "0B1111".parseBinInt == 15
  205. assert "1111".parseBinInt == 15
  206. assert "1110".parseBinInt == 14
  207. assert "1_1_1_1".parseBinInt == 15
  208. assert "0b1_1_1_1".parseBinInt == 15
  209. rejectParse "".parseBinInt
  210. rejectParse "_".parseBinInt
  211. rejectParse "0b".parseBinInt
  212. rejectParse "0b1234".parseBinInt
  213. # hex
  214. assert "0x72".parseHexInt == 114
  215. assert "0X72".parseHexInt == 114
  216. assert "#72".parseHexInt == 114
  217. assert "72".parseHexInt == 114
  218. assert "FF".parseHexInt == 255
  219. assert "ff".parseHexInt == 255
  220. assert "fF".parseHexInt == 255
  221. assert "0x7_2".parseHexInt == 114
  222. rejectParse "".parseHexInt
  223. rejectParse "_".parseHexInt
  224. rejectParse "0x".parseHexInt
  225. rejectParse "0xFFG".parseHexInt
  226. rejectParse "reject".parseHexInt
  227. # octal
  228. assert "0o17".parseOctInt == 15
  229. assert "0O17".parseOctInt == 15
  230. assert "17".parseOctInt == 15
  231. assert "10".parseOctInt == 8
  232. assert "0o1_0_0".parseOctInt == 64
  233. rejectParse "".parseOctInt
  234. rejectParse "_".parseOctInt
  235. rejectParse "0o".parseOctInt
  236. rejectParse "9".parseOctInt
  237. rejectParse "0o9".parseOctInt
  238. rejectParse "reject".parseOctInt
  239. testDelete()
  240. testFind()
  241. testRFind()
  242. testTrimZeros()
  243. testSplitLines()
  244. testCountLines()
  245. testParseInts()
  246. assert(insertSep($1000_000) == "1_000_000")
  247. assert(insertSep($232) == "232")
  248. assert(insertSep($12345, ',') == "12,345")
  249. assert(insertSep($0) == "0")
  250. assert "/1/2/3".rfind('/') == 4
  251. assert "/1/2/3".rfind('/', last=1) == 0
  252. assert "/1/2/3".rfind('0') == -1
  253. assert(toHex(100i16, 32) == "00000000000000000000000000000064")
  254. assert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
  255. assert(toHex(high(uint64)) == "FFFFFFFFFFFFFFFF")
  256. assert(toHex(high(uint64), 16) == "FFFFFFFFFFFFFFFF")
  257. assert(toHex(high(uint64), 32) == "0000000000000000FFFFFFFFFFFFFFFF")
  258. assert "".parseHexStr == ""
  259. assert "00Ff80".parseHexStr == "\0\xFF\x80"
  260. try:
  261. discard "00Ff8".parseHexStr
  262. assert false, "Should raise ValueError"
  263. except ValueError:
  264. discard
  265. try:
  266. discard "0k".parseHexStr
  267. assert false, "Should raise ValueError"
  268. except ValueError:
  269. discard
  270. assert "".toHex == ""
  271. assert "\x00\xFF\x80".toHex == "00FF80"
  272. assert "0123456789abcdef".parseHexStr.toHex == "0123456789ABCDEF"
  273. assert(' '.repeat(8) == " ")
  274. assert(" ".repeat(8) == " ")
  275. assert(spaces(8) == " ")
  276. assert(' '.repeat(0) == "")
  277. assert(" ".repeat(0) == "")
  278. assert(spaces(0) == "")
  279. # bug #11369
  280. var num: int64 = -1
  281. assert num.toBin(64) == "1111111111111111111111111111111111111111111111111111111111111111"
  282. assert num.toOct(24) == "001777777777777777777777"
  283. # bug #8911
  284. when true:
  285. static:
  286. let a = ""
  287. let a2 = a.replace("\n", "\\n")
  288. when true:
  289. static:
  290. let b = "b"
  291. let b2 = b.replace("\n", "\\n")
  292. when true:
  293. let c = ""
  294. let c2 = c.replace("\n", "\\n")
  295. main()
  296. #OUT ha/home/a1xyz/usr/bin
  297. # `parseEnum`, ref issue #14030
  298. # check enum defined at top level
  299. type
  300. Foo = enum
  301. A = -10
  302. B = "bb"
  303. C = (-5, "ccc")
  304. D = 15
  305. E = "ee" # check that we count enum fields correctly
  306. block:
  307. let a = parseEnum[Foo]("A")
  308. let b = parseEnum[Foo]("bb")
  309. let c = parseEnum[Foo]("ccc")
  310. let d = parseEnum[Foo]("D")
  311. let e = parseEnum[Foo]("ee")
  312. doAssert a == A
  313. doAssert b == B
  314. doAssert c == C
  315. doAssert d == D
  316. doAssert e == E
  317. try:
  318. let f = parseEnum[Foo]("Bar")
  319. doAssert false
  320. except ValueError:
  321. discard
  322. # finally using default
  323. let g = parseEnum[Foo]("Bar", A)
  324. doAssert g == A
  325. block:
  326. # check enum defined in block
  327. type
  328. Bar = enum
  329. V
  330. W = "ww"
  331. X = (3, "xx")
  332. Y = 10
  333. Z = "zz" # check that we count enum fields correctly
  334. let a = parseEnum[Bar]("V")
  335. let b = parseEnum[Bar]("ww")
  336. let c = parseEnum[Bar]("xx")
  337. let d = parseEnum[Bar]("Y")
  338. let e = parseEnum[Bar]("zz")
  339. doAssert a == V
  340. doAssert b == W
  341. doAssert c == X
  342. doAssert d == Y
  343. doAssert e == Z
  344. try:
  345. let f = parseEnum[Bar]("Baz")
  346. doAssert false
  347. except ValueError:
  348. discard
  349. # finally using default
  350. let g = parseEnum[Bar]("Baz", V)
  351. doAssert g == V
  352. block:
  353. # check ambiguous enum fails to parse
  354. type
  355. Ambig = enum
  356. f1 = "A"
  357. f2 = "B"
  358. f3 = "A"
  359. doAssert not compiles((let a = parseEnum[Ambig]("A")))
  360. block:
  361. # check almost ambiguous enum
  362. type
  363. AlmostAmbig = enum
  364. f1 = "someA"
  365. f2 = "someB"
  366. f3 = "SomeA"
  367. let a = parseEnum[AlmostAmbig]("someA")
  368. let b = parseEnum[AlmostAmbig]("someB")
  369. let c = parseEnum[AlmostAmbig]("SomeA")
  370. doAssert a == f1
  371. doAssert b == f2
  372. doAssert c == f3
  373. block:
  374. assert 0 == indentation """
  375. hey
  376. low
  377. there
  378. """
  379. assert 2 == indentation """
  380. hey
  381. low
  382. there
  383. """
  384. assert 2 == indentation """ hey
  385. low
  386. there
  387. """
  388. assert 2 == indentation """ hey
  389. low
  390. there"""
  391. assert 0 == indentation ""
  392. assert 0 == indentation " \n \n"
  393. assert 0 == indentation " "