tstrutil.nim 9.6 KB

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