From da3e6eab9e1b6e565858dbd8f33007ea9d35db9d Mon Sep 17 00:00:00 2001
From: flywind <43030857+xflywind@users.noreply.github.com>
Date: Wed, 25 Nov 2020 02:06:41 +0800
Subject: [PATCH] move tests to testament (#16101)
* move tests to testament
* minor
* fix random
* disable test random
---
lib/pure/algorithm.nim | 98 ----------
lib/pure/collections/critbits.nim | 63 ------
lib/pure/collections/tables.nim | 314 ------------------------------
lib/pure/cookies.nim | 15 --
lib/pure/fenv.nim | 8 -
lib/pure/hashes.nim | 43 ----
lib/pure/httpcore.nim | 25 ---
lib/pure/math.nim | 125 ------------
lib/pure/md5.nim | 7 -
lib/pure/options.nim | 141 --------------
lib/pure/parsecsv.nim | 32 ---
lib/pure/parseutils.nim | 43 ----
lib/pure/punycode.nim | 6 -
lib/pure/random.nim | 54 -----
lib/pure/rationals.nim | 97 ---------
lib/pure/stats.nim | 47 -----
lib/pure/streams.nim | 14 --
lib/pure/strformat.nim | 142 --------------
lib/pure/strmisc.nim | 21 --
lib/pure/strscans.nim | 112 -----------
lib/pure/strtabs.nim | 12 --
lib/pure/strutils.nim | 217 ---------------------
lib/pure/unicode.nim | 216 --------------------
lib/pure/unidecode/unidecode.nim | 5 -
lib/pure/uri.nim | 285 ---------------------------
lib/std/enumerate.nim | 19 --
lib/std/monotimes.nim | 16 --
lib/std/sha1.nim | 13 --
tests/stdlib/talgorithm.nim | 97 +++++++++
tests/stdlib/tcookies.nim | 15 ++
tests/stdlib/tcritbits.nim | 61 ++++++
tests/stdlib/tenumerate.nim | 19 ++
tests/stdlib/tfenv.nim | 8 +
tests/stdlib/thashes.nim | 87 ++++++---
tests/stdlib/thttpcore.nim | 42 ++--
tests/stdlib/tmath.nim | 126 ++++++++++++
tests/stdlib/tmd5.nim | 7 +
tests/stdlib/tmonotimes.nim | 16 ++
tests/stdlib/toptions.nim | 144 +++++++++++++-
tests/stdlib/tparsecsv.nim | 31 +++
tests/stdlib/tparseutils.nim | 43 ++++
tests/stdlib/tpunycode.nim | 5 +
tests/stdlib/trandom.nim | 59 ++++++
tests/stdlib/trationals.nim | 98 ++++++++++
tests/stdlib/tsha1.nim | 13 ++
tests/stdlib/tstats.nim | 46 +++++
tests/stdlib/tstreams.nim | 14 ++
tests/stdlib/tstrformat.nim | 139 ++++++++++++-
tests/stdlib/tstrmiscs.nim | 22 +++
tests/stdlib/tstrscans.nim | 112 +++++++++++
tests/stdlib/tstrtabs.nim | 12 ++
tests/stdlib/tstrutil.nim | 217 +++++++++++++++++++++
tests/stdlib/ttables.nim | 311 +++++++++++++++++++++++++++++
tests/stdlib/tunicode.nim | 215 ++++++++++++++++++++
tests/stdlib/tunidecode.nim | 3 +-
tests/stdlib/turi.nim | 285 ++++++++++++++++++++++++++-
56 files changed, 2205 insertions(+), 2232 deletions(-)
create mode 100644 tests/stdlib/tcookies.nim
create mode 100644 tests/stdlib/tcritbits.nim
create mode 100644 tests/stdlib/tenumerate.nim
create mode 100644 tests/stdlib/tfenv.nim
create mode 100644 tests/stdlib/tmd5.nim
create mode 100644 tests/stdlib/tmonotimes.nim
create mode 100644 tests/stdlib/tparsecsv.nim
create mode 100644 tests/stdlib/tparseutils.nim
create mode 100644 tests/stdlib/tpunycode.nim
create mode 100644 tests/stdlib/trandom.nim
create mode 100644 tests/stdlib/trationals.nim
create mode 100644 tests/stdlib/tsha1.nim
create mode 100644 tests/stdlib/tstats.nim
create mode 100644 tests/stdlib/tstrmiscs.nim
create mode 100644 tests/stdlib/ttables.nim
create mode 100644 tests/stdlib/tunicode.nim
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index ff835b57a01a8..2430e7330c2c6 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -665,36 +665,6 @@ proc prevPermutation*[T](x: var openArray[T]): bool {.discardable.} =
result = true
-when isMainModule:
- # Tests for lowerBound
- var arr = @[1, 2, 3, 5, 6, 7, 8, 9]
- assert arr.lowerBound(0) == 0
- assert arr.lowerBound(4) == 3
- assert arr.lowerBound(5) == 3
- assert arr.lowerBound(10) == 8
- arr = @[1, 5, 10]
- assert arr.lowerBound(4) == 1
- assert arr.lowerBound(5) == 1
- assert arr.lowerBound(6) == 2
- # Tests for isSorted
- var srt1 = [1, 2, 3, 4, 4, 4, 4, 5]
- var srt2 = ["iello", "hello"]
- var srt3 = [1.0, 1.0, 1.0]
- var srt4: seq[int]
- assert srt1.isSorted(cmp) == true
- assert srt2.isSorted(cmp) == false
- assert srt3.isSorted(cmp) == true
- assert srt4.isSorted(cmp) == true
- var srtseq = newSeq[int]()
- assert srtseq.isSorted(cmp) == true
- # Tests for reversed
- var arr1 = @[0, 1, 2, 3, 4]
- assert arr1.reversed() == @[4, 3, 2, 1, 0]
- for i in 0 .. high(arr1):
- assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)]
- assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i]
-
-
proc rotateInternal[T](arg: var openArray[T]; first, middle, last: int): int =
## A port of std::rotate from c++. Ported from `this reference `_.
result = first + last - middle
@@ -852,71 +822,3 @@ proc rotatedLeft*[T](arg: openArray[T]; dist: int): seq[T] =
let arglen = arg.len
let distLeft = ((dist mod arglen) + arglen) mod arglen
arg.rotatedInternal(0, distLeft, arg.len)
-
-when isMainModule:
- var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- let list2 = list.rotatedLeft(1 ..< 9, 3)
- let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10]
-
- doAssert list.rotateLeft(1 ..< 9, 3) == 6
- doAssert list == expected
- doAssert list2 == @expected
-
- var s0, s1, s2, s3, s4, s5 = "xxxabcdefgxxx"
-
- doAssert s0.rotateLeft(3 ..< 10, 3) == 7
- doAssert s0 == "xxxdefgabcxxx"
- doAssert s1.rotateLeft(3 ..< 10, 2) == 8
- doAssert s1 == "xxxcdefgabxxx"
- doAssert s2.rotateLeft(3 ..< 10, 4) == 6
- doAssert s2 == "xxxefgabcdxxx"
- doAssert s3.rotateLeft(3 ..< 10, -3) == 6
- doAssert s3 == "xxxefgabcdxxx"
- doAssert s4.rotateLeft(3 ..< 10, -10) == 6
- doAssert s4 == "xxxefgabcdxxx"
- doAssert s5.rotateLeft(3 ..< 10, 11) == 6
- doAssert s5 == "xxxefgabcdxxx"
-
- block product:
- doAssert product(newSeq[seq[int]]()) == newSeq[seq[int]](), "empty input"
- doAssert product(@[newSeq[int](), @[], @[]]) == newSeq[seq[int]](), "bit more empty input"
- doAssert product(@[@[1, 2]]) == @[@[1, 2]], "a simple case of one element"
- doAssert product(@[@[1, 2], @[3, 4]]) == @[@[2, 4], @[1, 4], @[2, 3], @[1,
- 3]], "two elements"
- doAssert product(@[@[1, 2], @[3, 4], @[5, 6]]) == @[@[2, 4, 6], @[1, 4, 6],
- @[2, 3, 6], @[1, 3, 6], @[2, 4, 5], @[1, 4, 5], @[2, 3, 5], @[1, 3, 5]], "three elements"
- doAssert product(@[@[1, 2], @[]]) == newSeq[seq[int]](), "two elements, but one empty"
-
- block lowerBound:
- doAssert lowerBound([1, 2, 4], 3, system.cmp[int]) == 2
- doAssert lowerBound([1, 2, 2, 3], 4, system.cmp[int]) == 4
- doAssert lowerBound([1, 2, 3, 10], 11) == 4
-
- block upperBound:
- doAssert upperBound([1, 2, 4], 3, system.cmp[int]) == 2
- doAssert upperBound([1, 2, 2, 3], 3, system.cmp[int]) == 4
- doAssert upperBound([1, 2, 3, 5], 3) == 3
-
- block fillEmptySeq:
- var s = newSeq[int]()
- s.fill(0)
-
- block testBinarySearch:
- var noData: seq[int]
- doAssert binarySearch(noData, 7) == -1
- let oneData = @[1]
- doAssert binarySearch(oneData, 1) == 0
- doAssert binarySearch(onedata, 7) == -1
- let someData = @[1, 3, 4, 7]
- doAssert binarySearch(someData, 1) == 0
- doAssert binarySearch(somedata, 7) == 3
- doAssert binarySearch(someData, -1) == -1
- doAssert binarySearch(someData, 5) == -1
- doAssert binarySearch(someData, 13) == -1
- let moreData = @[1, 3, 5, 7, 4711]
- doAssert binarySearch(moreData, -1) == -1
- doAssert binarySearch(moreData, 1) == 0
- doAssert binarySearch(moreData, 5) == 2
- doAssert binarySearch(moreData, 6) == -1
- doAssert binarySearch(moreData, 4711) == 4
- doAssert binarySearch(moreData, 4712) == -1
diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim
index 4611c25402f21..695f446460b0a 100644
--- a/lib/pure/collections/critbits.nim
+++ b/lib/pure/collections/critbits.nim
@@ -567,66 +567,3 @@ runnableExamples:
doAssert critbitAsDict["key"] == -int.high
critbitAsDict["key"] = int.high
doAssert critbitAsDict["key"] == int.high
-
-
-when isMainModule:
- import sequtils
-
- var r: CritBitTree[void]
- r.incl "abc"
- r.incl "xyz"
- r.incl "def"
- r.incl "definition"
- r.incl "prefix"
- r.incl "foo"
-
- doAssert r.contains"def"
-
- r.excl "def"
- assert r.missingOrExcl("foo") == false
- assert "foo" notin toSeq(r.items)
-
- assert r.missingOrExcl("foo") == true
-
- assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"]
-
- assert toSeq(r.itemsWithPrefix("de")) == @["definition"]
- var c = CritBitTree[int]()
-
- c.inc("a")
- assert c["a"] == 1
-
- c.inc("a", 4)
- assert c["a"] == 5
-
- c.inc("a", -5)
- assert c["a"] == 0
-
- c.inc("b", 2)
- assert c["b"] == 2
-
- c.inc("c", 3)
- assert c["c"] == 3
-
- c.inc("a", 1)
- assert c["a"] == 1
-
- var cf = CritBitTree[float]()
-
- cf.incl("a", 1.0)
- assert cf["a"] == 1.0
-
- cf.incl("b", 2.0)
- assert cf["b"] == 2.0
-
- cf.incl("c", 3.0)
- assert cf["c"] == 3.0
-
- assert cf.len == 3
- cf.excl("c")
- assert cf.len == 2
-
- var cb: CritBitTree[string]
- cb.incl("help", "help")
- for k in cb.keysWithPrefix("helpp"):
- doAssert false, "there is no prefix helpp"
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index e94e2a00b098d..a0efcdce2e86a 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -2873,317 +2873,3 @@ iterator mvalues*[A](t: CountTableRef[A]): var int =
if t.data[h].val != 0:
yield t.data[h].val
assert(len(t) == L, "the length of the table changed while iterating over it")
-
-
-
-
-when isMainModule:
- type
- Person = object
- firstName, lastName: string
-
- proc hash(x: Person): Hash =
- ## Piggyback on the already available string hash proc.
- ##
- ## Without this proc nothing works!
- result = x.firstName.hash !& x.lastName.hash
- result = !$result
-
- var
- salaries = initTable[Person, int]()
- p1, p2: Person
- p1.firstName = "Jon"
- p1.lastName = "Ross"
- salaries[p1] = 30_000
- p2.firstName = "소진"
- p2.lastName = "박"
- salaries[p2] = 45_000
- var
- s2 = initOrderedTable[Person, int]()
- s3 = initCountTable[Person]()
- s2[p1] = 30_000
- s2[p2] = 45_000
- s3[p1] = 30_000
- s3[p2] = 45_000
-
- block: # Ordered table should preserve order after deletion
- var
- s4 = initOrderedTable[int, int]()
- s4[1] = 1
- s4[2] = 2
- s4[3] = 3
-
- var prev = 0
- for i in s4.values:
- doAssert(prev < i)
- prev = i
-
- s4.del(2)
- doAssert(2 notin s4)
- doAssert(s4.len == 2)
- prev = 0
- for i in s4.values:
- doAssert(prev < i)
- prev = i
-
- block: # Deletion from OrderedTable should account for collision groups. See issue #5057.
- # The bug is reproducible only with exact keys
- const key1 = "boy_jackpot.inGamma"
- const key2 = "boy_jackpot.outBlack"
-
- var t = {
- key1: 0,
- key2: 0
- }.toOrderedTable()
-
- t.del(key1)
- assert(t.len == 1)
- assert(key2 in t)
-
- var
- t1 = initCountTable[string]()
- t2 = initCountTable[string]()
- t1.inc("foo")
- t1.inc("bar", 2)
- t1.inc("baz", 3)
- t2.inc("foo", 4)
- t2.inc("bar")
- t2.inc("baz", 11)
- merge(t1, t2)
- assert(t1["foo"] == 5)
- assert(t1["bar"] == 3)
- assert(t1["baz"] == 14)
-
- let
- t1r = newCountTable[string]()
- t2r = newCountTable[string]()
- t1r.inc("foo")
- t1r.inc("bar", 2)
- t1r.inc("baz", 3)
- t2r.inc("foo", 4)
- t2r.inc("bar")
- t2r.inc("baz", 11)
- merge(t1r, t2r)
- assert(t1r["foo"] == 5)
- assert(t1r["bar"] == 3)
- assert(t1r["baz"] == 14)
-
- var
- t1l = initCountTable[string]()
- t2l = initCountTable[string]()
- t1l.inc("foo")
- t1l.inc("bar", 2)
- t1l.inc("baz", 3)
- t2l.inc("foo", 4)
- t2l.inc("bar")
- t2l.inc("baz", 11)
-
- block:
- const testKey = "TESTKEY"
- let t: CountTableRef[string] = newCountTable[string]()
-
- # Before, does not compile with error message:
- #test_counttable.nim(7, 43) template/generic instantiation from here
- #lib/pure/collections/tables.nim(117, 21) template/generic instantiation from here
- #lib/pure/collections/tableimpl.nim(32, 27) Error: undeclared field: 'hcode
- doAssert 0 == t[testKey]
- t.inc(testKey, 3)
- doAssert 3 == t[testKey]
-
- block:
- # Clear tests
- var clearTable = newTable[int, string]()
- clearTable[42] = "asd"
- clearTable[123123] = "piuyqwb "
- doAssert clearTable[42] == "asd"
- clearTable.clear()
- doAssert(not clearTable.hasKey(123123))
- doAssert clearTable.getOrDefault(42) == ""
-
- block: #5482
- var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
- var b = newOrderedTable[string, string](initialSize = 2)
- b["wrong?"] = "foo"
- b["wrong?"] = "foo2"
- assert a == b
-
- block: #5482
- var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
- var b = newOrderedTable[string, string](initialSize = 2)
- b["wrong?"] = "foo"
- b["wrong?"] = "foo2"
- assert a == b
-
- block: #5487
- var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
- var b = newOrderedTable[string, string]() # notice, default size!
- b["wrong?"] = "foo"
- b["wrong?"] = "foo2"
- assert a == b
-
- block: #5487
- var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
- var b = newOrderedTable[string, string]() # notice, default size!
- b["wrong?"] = "foo"
- b["wrong?"] = "foo2"
- assert a == b
-
- block:
- var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
- var b = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
- var c = newOrderedTable[string, string]() # notice, default size!
- c["wrong?"] = "foo"
- c["wrong?"] = "foo2"
- assert a == b
- assert a == c
-
- block: #6250
- let
- a = {3: 1}.toOrderedTable
- b = {3: 2}.toOrderedTable
- assert((a == b) == false)
- assert((b == a) == false)
-
- block: #6250
- let
- a = {3: 2}.toOrderedTable
- b = {3: 2}.toOrderedTable
- assert((a == b) == true)
- assert((b == a) == true)
-
- block: # CountTable.smallest
- let t = toCountTable([0, 0, 5, 5, 5])
- doAssert t.smallest == (0, 2)
-
- block: #10065
- let t = toCountTable("abracadabra")
- doAssert t['z'] == 0
-
- var t_mut = toCountTable("abracadabra")
- doAssert t_mut['z'] == 0
- # the previous read may not have modified the table.
- doAssert t_mut.hasKey('z') == false
- t_mut['z'] = 1
- doAssert t_mut['z'] == 1
- doAssert t_mut.hasKey('z') == true
-
- block: #12813 #13079
- var t = toCountTable("abracadabra")
- doAssert len(t) == 5
-
- t['a'] = 0 # remove a key
- doAssert len(t) == 4
-
- block:
- var tp: Table[string, string] = initTable[string, string]()
- doAssert "test1" == tp.getOrDefault("test1", "test1")
- tp["test2"] = "test2"
- doAssert "test2" == tp.getOrDefault("test2", "test1")
- var tr: TableRef[string, string] = newTable[string, string]()
- doAssert "test1" == tr.getOrDefault("test1", "test1")
- tr["test2"] = "test2"
- doAssert "test2" == tr.getOrDefault("test2", "test1")
- var op: OrderedTable[string, string] = initOrderedTable[string, string]()
- doAssert "test1" == op.getOrDefault("test1", "test1")
- op["test2"] = "test2"
- doAssert "test2" == op.getOrDefault("test2", "test1")
- var orf: OrderedTableRef[string, string] = newOrderedTable[string, string]()
- doAssert "test1" == orf.getOrDefault("test1", "test1")
- orf["test2"] = "test2"
- doAssert "test2" == orf.getOrDefault("test2", "test1")
-
- block tableWithoutInit:
- var
- a: Table[string, int]
- b: Table[string, int]
- c: Table[string, int]
- d: Table[string, int]
- e: Table[string, int]
-
- a["a"] = 7
- doAssert a.hasKey("a")
- doAssert a.len == 1
- doAssert a["a"] == 7
- a["a"] = 9
- doAssert a.len == 1
- doAssert a["a"] == 9
-
- doAssert b.hasKeyOrPut("b", 5) == false
- doAssert b.hasKey("b")
- doAssert b.hasKeyOrPut("b", 8)
- doAssert b["b"] == 5
-
- doAssert c.getOrDefault("a") == 0
- doAssert c.getOrDefault("a", 3) == 3
- c["a"] = 6
- doAssert c.getOrDefault("a", 3) == 6
-
- doAssert d.mgetOrPut("a", 3) == 3
- doAssert d.mgetOrPut("a", 6) == 3
-
- var x = 99
- doAssert e.pop("a", x) == false
- doAssert x == 99
- e["a"] = 77
- doAssert e.pop("a", x)
- doAssert x == 77
-
- block orderedTableWithoutInit:
- var
- a: OrderedTable[string, int]
- b: OrderedTable[string, int]
- c: OrderedTable[string, int]
- d: OrderedTable[string, int]
-
- a["a"] = 7
- doAssert a.hasKey("a")
- doAssert a.len == 1
- doAssert a["a"] == 7
- a["a"] = 9
- doAssert a.len == 1
- doAssert a["a"] == 9
-
- doAssert b.hasKeyOrPut("b", 5) == false
- doAssert b.hasKey("b")
- doAssert b.hasKeyOrPut("b", 8)
- doAssert b["b"] == 5
-
- doAssert c.getOrDefault("a") == 0
- doAssert c.getOrDefault("a", 3) == 3
- c["a"] = 6
- doAssert c.getOrDefault("a", 3) == 6
-
- doAssert d.mgetOrPut("a", 3) == 3
- doAssert d.mgetOrPut("a", 6) == 3
-
- block countTableWithoutInit:
- var
- a: CountTable[string]
- b: CountTable[string]
- c: CountTable[string]
- d: CountTable[string]
- e: CountTable[string]
-
- a["a"] = 7
- doAssert a.hasKey("a")
- doAssert a.len == 1
- doAssert a["a"] == 7
- a["a"] = 9
- doAssert a.len == 1
- doAssert a["a"] == 9
-
- doAssert b["b"] == 0
- b.inc("b")
- doAssert b["b"] == 1
-
- doAssert c.getOrDefault("a") == 0
- doAssert c.getOrDefault("a", 3) == 3
- c["a"] = 6
- doAssert c.getOrDefault("a", 3) == 6
-
- e["f"] = 3
- merge(d, e)
- doAssert d.hasKey("f")
- d.inc("f")
- merge(d, e)
- doAssert d["f"] == 7
diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim
index eaff86ae6aa80..7e686d44fafb7 100644
--- a/lib/pure/cookies.nim
+++ b/lib/pure/cookies.nim
@@ -59,18 +59,3 @@ proc setCookie*(key, value: string, expires: DateTime|Time,
return setCookie(key, value, domain, path,
format(expires.utc, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"),
noname, secure, httpOnly)
-
-when isMainModule:
- let expire = fromUnix(0) + 1.seconds
-
- let cookies = [
- setCookie("test", "value", expire),
- setCookie("test", "value", expire.local),
- setCookie("test", "value", expire.utc)
- ]
- let expected = "Set-Cookie: test=value; Expires=Thu, 01 Jan 1970 00:00:01 GMT"
- doAssert cookies == [expected, expected, expected]
-
- let table = parseCookies("uid=1; kp=2")
- doAssert table["uid"] == "1"
- doAssert table["kp"] == "2"
diff --git a/lib/pure/fenv.nim b/lib/pure/fenv.nim
index 53b3e3b50806b..abddaf4cbd839 100644
--- a/lib/pure/fenv.nim
+++ b/lib/pure/fenv.nim
@@ -178,11 +178,3 @@ template maximumPositiveValue*(T: typedesc[float64]): float64 = DBL_MAX
template epsilon*(T: typedesc[float64]): float64 = DBL_EPSILON
## The difference between 1.0 and the smallest number greater than
## 1.0 that can be represented in a 64-bit floating-point type.
-
-
-when isMainModule:
- func is_significant(x: float): bool =
- if x > minimumPositiveValue(float) and x < maximumPositiveValue(float): true
- else: false
-
- doAssert is_significant(10.0)
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim
index 3191d40305387..667f27e95d2ef 100644
--- a/lib/pure/hashes.nim
+++ b/lib/pure/hashes.nim
@@ -485,46 +485,3 @@ proc hash*[A](x: set[A]): Hash =
for it in items(x):
result = result !& hash(it)
result = !$result
-
-
-when isMainModule:
- block empty:
- var
- a = ""
- b = newSeq[char]()
- c = newSeq[int]()
- d = cstring""
- e = "abcd"
- doAssert hash(a) == 0
- doAssert hash(b) == 0
- doAssert hash(c) == 0
- doAssert hash(d) == 0
- doAssert hashIgnoreCase(a) == 0
- doAssert hashIgnoreStyle(a) == 0
- doAssert hash(e, 3, 2) == 0
- block sameButDifferent:
- doAssert hash("aa bb aaaa1234") == hash("aa bb aaaa1234", 0, 13)
- doAssert hash("aa bb aaaa1234") == hash(cstring"aa bb aaaa1234")
- doAssert hashIgnoreCase("aA bb aAAa1234") == hashIgnoreCase("aa bb aaaa1234")
- doAssert hashIgnoreStyle("aa_bb_AAaa1234") == hashIgnoreCase("aaBBAAAa1234")
- block smallSize: # no multibyte hashing
- let
- xx = @['H', 'i']
- ii = @[72'u8, 105]
- ss = "Hi"
- doAssert hash(xx) == hash(ii)
- doAssert hash(xx) == hash(ss)
- doAssert hash(xx) == hash(xx, 0, xx.high)
- doAssert hash(ss) == hash(ss, 0, ss.high)
- block largeSize: # longer than 4 characters
- let
- xx = @['H', 'e', 'l', 'l', 'o']
- xxl = @['H', 'e', 'l', 'l', 'o', 'w', 'e', 'e', 'n', 's']
- ssl = "Helloweens"
- doAssert hash(xxl) == hash(ssl)
- doAssert hash(xxl) == hash(xxl, 0, xxl.high)
- doAssert hash(ssl) == hash(ssl, 0, ssl.high)
- doAssert hash(xx) == hash(xxl, 0, 4)
- doAssert hash(xx) == hash(ssl, 0, 4)
- doAssert hash(xx, 0, 3) == hash(xxl, 0, 3)
- doAssert hash(xx, 0, 3) == hash(ssl, 0, 3)
diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim
index 401e78b9b3687..7ead64d838e73 100644
--- a/lib/pure/httpcore.nim
+++ b/lib/pure/httpcore.nim
@@ -345,28 +345,3 @@ func is5xx*(code: HttpCode): bool {.inline.} =
func `$`*(httpMethod: HttpMethod): string =
return (system.`$`(httpMethod))[4 .. ^1].toUpperAscii()
-
-when isMainModule:
- var test = newHttpHeaders()
- test["Connection"] = @["Upgrade", "Close"]
- doAssert test["Connection", 0] == "Upgrade"
- doAssert test["Connection", 1] == "Close"
- test.add("Connection", "Test")
- doAssert test["Connection", 2] == "Test"
- doAssert "upgrade" in test["Connection"]
-
- # Bug #5344.
- doAssert parseHeader("foobar: ") == ("foobar", @[""])
- let (key, value) = parseHeader("foobar: ")
- test = newHttpHeaders()
- test[key] = value
- doAssert test["foobar"] == ""
-
- doAssert parseHeader("foobar:") == ("foobar", @[""])
-
- block: # test title case
- var testTitleCase = newHttpHeaders(titleCase=true)
- testTitleCase.add("content-length", "1")
- doAssert testTitleCase.hasKey("Content-Length")
- for key, val in testTitleCase:
- doAssert key == "Content-Length"
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 59368fbd28c6c..af31a578512ed 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -1101,128 +1101,3 @@ proc lcm*[T](x: openArray[T]): T {.since: (1, 1).} =
while i < x.len:
result = lcm(result, x[i])
inc(i)
-
-when isMainModule and not defined(js) and not windowsCC89:
- # Check for no side effect annotation
- proc mySqrt(num: float): float {.noSideEffect.} =
- return sqrt(num)
-
- # check gamma function
- assert(gamma(5.0) == 24.0) # 4!
- assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
- assert(erf(6.0) > erf(5.0))
- assert(erfc(6.0) < erfc(5.0))
-
-when isMainModule:
- # Function for approximate comparison of floats
- proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9)
-
- block: # prod
- doAssert prod([1, 2, 3, 4]) == 24
- doAssert prod([1.5, 3.4]) == 5.1
- let x: seq[float] = @[]
- doAssert prod(x) == 1.0
-
- block: # round() tests
- # Round to 0 decimal places
- doAssert round(54.652) ==~ 55.0
- doAssert round(54.352) ==~ 54.0
- doAssert round(-54.652) ==~ -55.0
- doAssert round(-54.352) ==~ -54.0
- doAssert round(0.0) ==~ 0.0
-
- block: # splitDecimal() tests
- doAssert splitDecimal(54.674).intpart ==~ 54.0
- doAssert splitDecimal(54.674).floatpart ==~ 0.674
- doAssert splitDecimal(-693.4356).intpart ==~ -693.0
- doAssert splitDecimal(-693.4356).floatpart ==~ -0.4356
- doAssert splitDecimal(0.0).intpart ==~ 0.0
- doAssert splitDecimal(0.0).floatpart ==~ 0.0
-
- block: # trunc tests for vcc
- doAssert(trunc(-1.1) == -1)
- doAssert(trunc(1.1) == 1)
- doAssert(trunc(-0.1) == -0)
- doAssert(trunc(0.1) == 0)
-
- #special case
- doAssert(classify(trunc(1e1000000)) == fcInf)
- doAssert(classify(trunc(-1e1000000)) == fcNegInf)
- doAssert(classify(trunc(0.0/0.0)) == fcNan)
- doAssert(classify(trunc(0.0)) == fcZero)
-
- #trick the compiler to produce signed zero
- let
- f_neg_one = -1.0
- f_zero = 0.0
- f_nan = f_zero / f_zero
-
- doAssert(classify(trunc(f_neg_one*f_zero)) == fcNegZero)
-
- doAssert(trunc(-1.1'f32) == -1)
- doAssert(trunc(1.1'f32) == 1)
- doAssert(trunc(-0.1'f32) == -0)
- doAssert(trunc(0.1'f32) == 0)
- doAssert(classify(trunc(1e1000000'f32)) == fcInf)
- doAssert(classify(trunc(-1e1000000'f32)) == fcNegInf)
- doAssert(classify(trunc(f_nan.float32)) == fcNan)
- doAssert(classify(trunc(0.0'f32)) == fcZero)
-
- block: # sgn() tests
- assert sgn(1'i8) == 1
- assert sgn(1'i16) == 1
- assert sgn(1'i32) == 1
- assert sgn(1'i64) == 1
- assert sgn(1'u8) == 1
- assert sgn(1'u16) == 1
- assert sgn(1'u32) == 1
- assert sgn(1'u64) == 1
- assert sgn(-12342.8844'f32) == -1
- assert sgn(123.9834'f64) == 1
- assert sgn(0'i32) == 0
- assert sgn(0'f32) == 0
- assert sgn(NegInf) == -1
- assert sgn(Inf) == 1
- assert sgn(NaN) == 0
-
- block: # fac() tests
- try:
- discard fac(-1)
- except AssertionDefect:
- discard
-
- doAssert fac(0) == 1
- doAssert fac(1) == 1
- doAssert fac(2) == 2
- doAssert fac(3) == 6
- doAssert fac(4) == 24
-
- block: # floorMod/floorDiv
- doAssert floorDiv(8, 3) == 2
- doAssert floorMod(8, 3) == 2
-
- doAssert floorDiv(8, -3) == -3
- doAssert floorMod(8, -3) == -1
-
- doAssert floorDiv(-8, 3) == -3
- doAssert floorMod(-8, 3) == 1
-
- doAssert floorDiv(-8, -3) == 2
- doAssert floorMod(-8, -3) == -2
-
- doAssert floorMod(8.0, -3.0) ==~ -1.0
- doAssert floorMod(-8.5, 3.0) ==~ 0.5
-
- block: # log
- doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0)
- doAssert log2(8.0'f64) == 3.0'f64
- doAssert log2(4.0'f64) == 2.0'f64
- doAssert log2(2.0'f64) == 1.0'f64
- doAssert log2(1.0'f64) == 0.0'f64
- doAssert classify(log2(0.0'f64)) == fcNegInf
-
- doAssert log2(8.0'f32) == 3.0'f32
- doAssert log2(4.0'f32) == 2.0'f32
- doAssert log2(2.0'f32) == 1.0'f32
- doAssert log2(1.0'f32) == 0.0'f32
- doAssert classify(log2(0.0'f32)) == fcNegInf
diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim
index 1ea71afd26dbc..ba944ba813112 100644
--- a/lib/pure/md5.nim
+++ b/lib/pure/md5.nim
@@ -278,12 +278,5 @@ proc md5Final*(c: var MD5Context, digest: var MD5Digest) =
zeroMem(addr(c), sizeof(MD5Context))
-when isMainModule:
- assert(getMD5("Franz jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
- "a3cca2b2aa1e3b5b3b5aad99a8529074")
- assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
- "7e716d0e702df0505fc72e2b89467910")
- assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")
-
when defined(nimHasStyleChecks):
{.pop.} #{.push styleChecks: off.}
diff --git a/lib/pure/options.nim b/lib/pure/options.nim
index 076cf37077b8c..8de4430c1d5c0 100644
--- a/lib/pure/options.nim
+++ b/lib/pure/options.nim
@@ -371,144 +371,3 @@ proc unsafeGet*[T](self: Option[T]): lent T {.inline.}=
## Generally, using `get proc <#get,Option[T]>`_ is preferred.
assert self.isSome
result = self.val
-
-when isMainModule:
- import unittest, sequtils
-
- # RefPerson is used to test that overloaded `==` operator is not called by
- # options. It is defined here in the global scope, because otherwise the test
- # will not even consider the `==` operator. Different bug?
- type RefPerson = ref object
- name: string
-
- proc `==`(a, b: RefPerson): bool =
- assert(not a.isNil and not b.isNil)
- a.name == b.name
-
- suite "options":
- # work around a bug in unittest
- let intNone = none(int)
- let stringNone = none(string)
-
- test "example":
- proc find(haystack: string, needle: char): Option[int] =
- for i, c in haystack:
- if c == needle:
- return some i
-
- check("abc".find('c').get() == 2)
-
- let result = "team".find('i')
-
- check result == intNone
- check result.isNone
-
- test "some":
- check some(6).get() == 6
- check some("a").unsafeGet() == "a"
- check some(6).isSome
- check some("a").isSome
-
- test "none":
- expect UnpackDefect:
- discard none(int).get()
- check(none(int).isNone)
- check(not none(string).isSome)
-
- test "equality":
- check some("a") == some("a")
- check some(7) != some(6)
- check some("a") != stringNone
- check intNone == intNone
-
- when compiles(some("a") == some(5)):
- check false
- when compiles(none(string) == none(int)):
- check false
-
- test "get with a default value":
- check(some("Correct").get("Wrong") == "Correct")
- check(stringNone.get("Correct") == "Correct")
-
- test "$":
- check($(some("Correct")) == "Some(\"Correct\")")
- check($(stringNone) == "None[string]")
-
- test "map with a void result":
- var procRan = 0
- some(123).map(proc (v: int) = procRan = v)
- check procRan == 123
- intNone.map(proc (v: int) = check false)
-
- test "map":
- check(some(123).map(proc (v: int): int = v * 2) == some(246))
- check(intNone.map(proc (v: int): int = v * 2).isNone)
-
- test "filter":
- check(some(123).filter(proc (v: int): bool = v == 123) == some(123))
- check(some(456).filter(proc (v: int): bool = v == 123).isNone)
- check(intNone.filter(proc (v: int): bool = check false).isNone)
-
- test "flatMap":
- proc addOneIfNotZero(v: int): Option[int] =
- if v != 0:
- result = some(v + 1)
- else:
- result = none(int)
-
- check(some(1).flatMap(addOneIfNotZero) == some(2))
- check(some(0).flatMap(addOneIfNotZero) == none(int))
- check(some(1).flatMap(addOneIfNotZero).flatMap(addOneIfNotZero) == some(3))
-
- proc maybeToString(v: int): Option[string] =
- if v != 0:
- result = some($v)
- else:
- result = none(string)
-
- check(some(1).flatMap(maybeToString) == some("1"))
-
- proc maybeExclaim(v: string): Option[string] =
- if v != "":
- result = some v & "!"
- else:
- result = none(string)
-
- check(some(1).flatMap(maybeToString).flatMap(maybeExclaim) == some("1!"))
- check(some(0).flatMap(maybeToString).flatMap(maybeExclaim) == none(string))
-
- test "SomePointer":
- var intref: ref int
- check(option(intref).isNone)
- intref.new
- check(option(intref).isSome)
-
- let tmp = option(intref)
- check(sizeof(tmp) == sizeof(ptr int))
-
- var prc = proc (x: int): int = x + 1
- check(option(prc).isSome)
- prc = nil
- check(option(prc).isNone)
-
- test "none[T]":
- check(none[int]().isNone)
- check(none(int) == none[int]())
-
- test "$ on typed with .name":
- type Named = object
- name: string
-
- let nobody = none(Named)
- check($nobody == "None[Named]")
-
- test "$ on type with name()":
- type Person = object
- myname: string
-
- let noperson = none(Person)
- check($noperson == "None[Person]")
-
- test "Ref type with overloaded `==`":
- let p = some(RefPerson.new())
- check p.isSome
diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim
index 2c0dbb8020069..4a7117dc5bd0d 100644
--- a/lib/pure/parsecsv.nim
+++ b/lib/pure/parsecsv.nim
@@ -357,35 +357,3 @@ when not defined(testing) and isMainModule:
for val in items(x.row):
echo "##", val, "##"
close(x)
-
-when isMainModule:
- import os
- import strutils
- block: # Tests for reading the header row
- let content = "\nOne,Two,Three,Four\n1,2,3,4\n10,20,30,40,\n100,200,300,400\n"
- writeFile("temp.csv", content)
-
- var p: CsvParser
- p.open("temp.csv")
- p.readHeaderRow()
- while p.readRow():
- let zeros = repeat('0', p.currRow-2)
- doAssert p.rowEntry("One") == "1" & zeros
- doAssert p.rowEntry("Two") == "2" & zeros
- doAssert p.rowEntry("Three") == "3" & zeros
- doAssert p.rowEntry("Four") == "4" & zeros
- p.close()
-
- when not defined(testing):
- var parser: CsvParser
- parser.open("temp.csv")
- parser.readHeaderRow()
- while parser.readRow():
- echo "new row: "
- for col in items(parser.headers):
- echo "##", col, ":", parser.rowEntry(col), "##"
- parser.close()
- removeFile("temp.csv")
-
- # Tidy up
- removeFile("temp.csv")
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 4b123117ae040..29159816d9184 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -651,47 +651,4 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
break
i = j
-when isMainModule:
- import sequtils
- let input = "$test{} $this is ${an{ example}} "
- let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"),
- (ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")]
- doAssert toSeq(interpolatedFragments(input)) == expected
-
- var value = 0
- discard parseHex("0x38", value)
- doAssert value == 56
-
- value = -1
- doAssert(parseSaturatedNatural("848", value) == 3)
- doAssert value == 848
-
- value = -1
- discard parseSaturatedNatural("84899999999999999999324234243143142342135435342532453", value)
- doAssert value == high(int)
-
- value = -1
- discard parseSaturatedNatural("9223372036854775808", value)
- doAssert value == high(int)
-
- value = -1
- discard parseSaturatedNatural("9223372036854775807", value)
- doAssert value == high(int)
-
- value = -1
- discard parseSaturatedNatural("18446744073709551616", value)
- doAssert value == high(int)
-
- value = -1
- discard parseSaturatedNatural("18446744073709551615", value)
- doAssert value == high(int)
-
- value = -1
- doAssert(parseSaturatedNatural("1_000_000", value) == 9)
- doAssert value == 1_000_000
-
- var i64Value: int64
- discard parseBiggestInt("9223372036854775807", i64Value)
- doAssert i64Value == 9223372036854775807
-
{.pop.}
diff --git a/lib/pure/punycode.nim b/lib/pure/punycode.nim
index fc80fabfded1c..e9e11a1c31bc2 100644
--- a/lib/pure/punycode.nim
+++ b/lib/pure/punycode.nim
@@ -206,9 +206,3 @@ runnableExamples:
doAssert decode("Mnchen-3ya-") == "Mnchen-3ya"
doAssert decode("Mnchen-Ost-9db") == "München-Ost"
doAssert decode("Bahnhof Mnchen-Ost-u6b") == "Bahnhof München-Ost"
-
-
-when isMainModule:
- assert(decode(encode("", "bücher")) == "bücher")
- assert(decode(encode("münchen")) == "münchen")
- assert encode("xn--", "münchen") == "xn--mnchen-3ya"
diff --git a/lib/pure/random.nim b/lib/pure/random.nim
index 3d9948d08e717..683140cd8dcf0 100644
--- a/lib/pure/random.nim
+++ b/lib/pure/random.nim
@@ -651,57 +651,3 @@ when not defined(nimscript) and not defined(standalone):
randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanosecond)
{.pop.}
-
-when isMainModule:
- import stats
-
- proc main =
- var occur: array[1000, int]
-
- var x = 8234
- for i in 0..100_000:
- x = rand(high(occur))
- inc occur[x]
- for i, oc in occur:
- if oc < 69:
- doAssert false, "too few occurrences of " & $i
- elif oc > 150:
- doAssert false, "too many occurrences of " & $i
-
- when false:
- var rs: RunningStat
- for j in 1..5:
- for i in 1 .. 1_000:
- rs.push(gauss())
- echo("mean: ", rs.mean,
- " stdDev: ", rs.standardDeviation(),
- " min: ", rs.min,
- " max: ", rs.max)
- rs.clear()
-
- var a = [0, 1]
- shuffle(a)
- doAssert a[0] == 1
- doAssert a[1] == 0
-
- doAssert rand(0) == 0
- doAssert sample("a") == 'a'
-
- when compileOption("rangeChecks"):
- try:
- discard rand(-1)
- doAssert false
- except RangeDefect:
- discard
-
- try:
- discard rand(-1.0)
- doAssert false
- except RangeDefect:
- discard
-
-
- # don't use causes integer overflow
- doAssert compiles(rand[int](low(int) .. high(int)))
-
- main()
diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim
index c7af91eddc076..38a88ebc3a795 100644
--- a/lib/pure/rationals.nim
+++ b/lib/pure/rationals.nim
@@ -279,100 +279,3 @@ proc hash*[T](x: Rational[T]): Hash =
h = h !& hash(copy.num)
h = h !& hash(copy.den)
result = !$h
-
-when isMainModule:
- var
- z = Rational[int](num: 0, den: 1)
- o = initRational(num = 1, den = 1)
- a = initRational(1, 2)
- b = -1 // -2
- m1 = -1 // 1
- tt = 10 // 2
-
- assert(a == a)
- assert( (a-a) == z)
- assert( (a+b) == o)
- assert( (a/b) == o)
- assert( (a*b) == 1 // 4)
- assert( (3/a) == 6 // 1)
- assert( (a/3) == 1 // 6)
- assert(a*b == 1 // 4)
- assert(tt*z == z)
- assert(10*a == tt)
- assert(a*10 == tt)
- assert(tt/10 == a)
- assert(a-m1 == 3 // 2)
- assert(a+m1 == -1 // 2)
- assert(m1+tt == 16 // 4)
- assert(m1-tt == 6 // -1)
-
- assert(z < o)
- assert(z <= o)
- assert(z == z)
- assert(cmp(z, o) < 0)
- assert(cmp(o, z) > 0)
-
- assert(o == o)
- assert(o >= o)
- assert(not(o > o))
- assert(cmp(o, o) == 0)
- assert(cmp(z, z) == 0)
- assert(hash(o) == hash(o))
-
- assert(a == b)
- assert(a >= b)
- assert(not(b > a))
- assert(cmp(a, b) == 0)
- assert(hash(a) == hash(b))
-
- var x = 1//3
-
- x *= 5//1
- assert(x == 5//3)
- x += 2 // 9
- assert(x == 17//9)
- x -= 9//18
- assert(x == 25//18)
- x /= 1//2
- assert(x == 50//18)
-
- var y = 1//3
-
- y *= 4
- assert(y == 4//3)
- y += 5
- assert(y == 19//3)
- y -= 2
- assert(y == 13//3)
- y /= 9
- assert(y == 13//27)
-
- assert toRational(5) == 5//1
- assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
- assert toInt(z) == 0
-
- when sizeof(int) == 8:
- assert toRational(0.98765432) == 2111111029 // 2137499919
- assert toRational(PI) == 817696623 // 260280919
- when sizeof(int) == 4:
- assert toRational(0.98765432) == 80 // 81
- assert toRational(PI) == 355 // 113
-
- assert toRational(0.1) == 1 // 10
- assert toRational(0.9) == 9 // 10
-
- assert toRational(0.0) == 0 // 1
- assert toRational(-0.25) == 1 // -4
- assert toRational(3.2) == 16 // 5
- assert toRational(0.33) == 33 // 100
- assert toRational(0.22) == 11 // 50
- assert toRational(10.0) == 10 // 1
-
- assert (1//1) div (3//10) == 3
- assert (-1//1) div (3//10) == -3
- assert (3//10) mod (1//1) == 3//10
- assert (-3//10) mod (1//1) == -3//10
- assert floorDiv(1//1, 3//10) == 3
- assert floorDiv(-1//1, 3//10) == -4
- assert floorMod(3//10, 1//1) == 3//10
- assert floorMod(-3//10, 1//1) == 7//10
diff --git a/lib/pure/stats.nim b/lib/pure/stats.nim
index 8684cb60a6150..20fd1fdcd61fd 100644
--- a/lib/pure/stats.nim
+++ b/lib/pure/stats.nim
@@ -335,50 +335,3 @@ runnableExamples:
doAssert statistics.skewnessS() === 1.018350154434631
doAssert statistics.kurtosis() === -1.0
doAssert statistics.kurtosisS() === -0.7000000000000008
-
-
-when isMainModule:
- proc clean(x: float): float =
- result = round(1.0e8*x).float * 1.0e-8
-
- var rs: RunningStat
- rs.push(@[1.0, 2.0, 1.0, 4.0, 1.0, 4.0, 1.0, 2.0])
- doAssert(rs.n == 8)
- doAssert(clean(rs.mean) == 2.0)
- doAssert(clean(rs.variance()) == 1.5)
- doAssert(clean(rs.varianceS()) == 1.71428571)
- doAssert(clean(rs.skewness()) == 0.81649658)
- doAssert(clean(rs.skewnessS()) == 1.01835015)
- doAssert(clean(rs.kurtosis()) == -1.0)
- doAssert(clean(rs.kurtosisS()) == -0.7000000000000001)
-
- var rs1, rs2: RunningStat
- rs1.push(@[1.0, 2.0, 1.0, 4.0])
- rs2.push(@[1.0, 4.0, 1.0, 2.0])
- let rs3 = rs1 + rs2
- doAssert(clean(rs3.mom2) == clean(rs.mom2))
- doAssert(clean(rs3.mom3) == clean(rs.mom3))
- doAssert(clean(rs3.mom4) == clean(rs.mom4))
- rs1 += rs2
- doAssert(clean(rs1.mom2) == clean(rs.mom2))
- doAssert(clean(rs1.mom3) == clean(rs.mom3))
- doAssert(clean(rs1.mom4) == clean(rs.mom4))
- rs1.clear()
- rs1.push(@[1.0, 2.2, 1.4, 4.9])
- doAssert(rs1.sum == 9.5)
- doAssert(rs1.mean() == 2.375)
-
- when not defined(cpu32):
- # XXX For some reason on 32bit CPUs these results differ
- var rr: RunningRegress
- rr.push(@[0.0, 1.0, 2.8, 3.0, 4.0], @[0.0, 1.0, 2.3, 3.0, 4.0])
- doAssert(rr.slope() == 0.9695585996955861)
- doAssert(rr.intercept() == -0.03424657534246611)
- doAssert(rr.correlation() == 0.9905100362239381)
- var rr1, rr2: RunningRegress
- rr1.push(@[0.0, 1.0], @[0.0, 1.0])
- rr2.push(@[2.8, 3.0, 4.0], @[2.3, 3.0, 4.0])
- let rr3 = rr1 + rr2
- doAssert(rr3.correlation() == rr.correlation())
- doAssert(clean(rr3.slope()) == clean(rr.slope()))
- doAssert(clean(rr3.intercept()) == clean(rr.intercept()))
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index dc00271a5d028..de3f41f09cdd5 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -1520,17 +1520,3 @@ when false:
var handle = open(filename, flags)
if handle < 0: raise newEOS("posix.open() call failed")
result = newFileHandleStream(handle)
-
-when isMainModule and defined(testing):
- var ss = newStringStream("The quick brown fox jumped over the lazy dog.\nThe lazy dog ran")
- assert(ss.getPosition == 0)
- assert(ss.peekStr(5) == "The q")
- assert(ss.getPosition == 0) # haven't moved
- assert(ss.readStr(5) == "The q")
- assert(ss.getPosition == 5) # did move
- assert(ss.peekLine() == "uick brown fox jumped over the lazy dog.")
- assert(ss.getPosition == 5) # haven't moved
- var str = newString(100)
- assert(ss.peekLine(str))
- assert(str == "uick brown fox jumped over the lazy dog.")
- assert(ss.getPosition == 5) # haven't moved
diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim
index c37b6b1c050e7..ddf996e4846fc 100644
--- a/lib/pure/strformat.nim
+++ b/lib/pure/strformat.nim
@@ -660,145 +660,3 @@ macro fmt*(pattern: string; openChar, closeChar: char): untyped =
doAssert """(()"foo" & "bar"())""".fmt(')', '(') == "(foobar)"
doAssert """ ""{"123+123"}"" """.fmt('"', '"') == " \"{246}\" "
strformatImpl(pattern, openChar.intVal.char, closeChar.intVal.char)
-
-when isMainModule:
- template check(actual, expected: string) =
- doAssert actual == expected
-
- from strutils import toUpperAscii, repeat
-
- # Basic tests
- let s = "string"
- check &"{0} {s}", "0 string"
- check &"{s[0..2].toUpperAscii}", "STR"
- check &"{-10:04}", "-010"
- check &"{-10:<04}", "-010"
- check &"{-10:>04}", "-010"
- check &"0x{10:02X}", "0x0A"
-
- check &"{10:#04X}", "0x0A"
-
- check &"""{"test":#>5}""", "#test"
- check &"""{"test":>5}""", " test"
-
- check &"""{"test":#^7}""", "#test##"
-
- check &"""{"test": <5}""", "test "
- check &"""{"test":<5}""", "test "
- check &"{1f:.3f}", "1.000"
- check &"Hello, {s}!", "Hello, string!"
-
- # Tests for identifiers without parenthesis
- check &"{s} works{s}", "string worksstring"
- check &"{s:>7}", " string"
- doAssert(not compiles(&"{s_works}")) # parsed as identifier `s_works`
-
- # Misc general tests
- check &"{{}}", "{}"
- check &"{0}%", "0%"
- check &"{0}%asdf", "0%asdf"
- check &("\n{\"\\n\"}\n"), "\n\n\n"
- check &"""{"abc"}s""", "abcs"
-
- # String tests
- check &"""{"abc"}""", "abc"
- check &"""{"abc":>4}""", " abc"
- check &"""{"abc":<4}""", "abc "
- check &"""{"":>4}""", " "
- check &"""{"":<4}""", " "
-
- # Int tests
- check &"{12345}", "12345"
- check &"{ - 12345}", "-12345"
- check &"{12345:6}", " 12345"
- check &"{12345:>6}", " 12345"
- check &"{12345:4}", "12345"
- check &"{12345:08}", "00012345"
- check &"{-12345:08}", "-0012345"
- check &"{0:0}", "0"
- check &"{0:02}", "00"
- check &"{-1:3}", " -1"
- check &"{-1:03}", "-01"
- check &"{10}", "10"
- check &"{16:#X}", "0x10"
- check &"{16:^#7X}", " 0x10 "
- check &"{16:^+#7X}", " +0x10 "
-
- # Hex tests
- check &"{0:x}", "0"
- check &"{-0:x}", "0"
- check &"{255:x}", "ff"
- check &"{255:X}", "FF"
- check &"{-255:x}", "-ff"
- check &"{-255:X}", "-FF"
- check &"{255:x} uNaffeCteD CaSe", "ff uNaffeCteD CaSe"
- check &"{255:X} uNaffeCteD CaSe", "FF uNaffeCteD CaSe"
- check &"{255:4x}", " ff"
- check &"{255:04x}", "00ff"
- check &"{-255:4x}", " -ff"
- check &"{-255:04x}", "-0ff"
-
- # Float tests
- check &"{123.456}", "123.456"
- check &"{-123.456}", "-123.456"
- check &"{123.456:.3f}", "123.456"
- check &"{123.456:+.3f}", "+123.456"
- check &"{-123.456:+.3f}", "-123.456"
- check &"{-123.456:.3f}", "-123.456"
- check &"{123.456:1g}", "123.456"
- check &"{123.456:.1f}", "123.5"
- check &"{123.456:.0f}", "123."
- check &"{123.456:>9.3f}", " 123.456"
- check &"{123.456:9.3f}", " 123.456"
- check &"{123.456:>9.4f}", " 123.4560"
- check &"{123.456:>9.0f}", " 123."
- check &"{123.456:<9.4f}", "123.4560 "
-
- # Float (scientific) tests
- check &"{123.456:e}", "1.234560e+02"
- check &"{123.456:>13e}", " 1.234560e+02"
- check &"{123.456:<13e}", "1.234560e+02 "
- check &"{123.456:.1e}", "1.2e+02"
- check &"{123.456:.2e}", "1.23e+02"
- check &"{123.456:.3e}", "1.235e+02"
-
- # Note: times.format adheres to the format protocol. Test that this
- # works:
- import times
-
- var dt = initDateTime(01, mJan, 2000, 00, 00, 00)
- check &"{dt:yyyy-MM-dd}", "2000-01-01"
-
- var tm = fromUnix(0)
- discard &"{tm}"
-
- var noww = now()
- check &"{noww}", $noww
-
- # Unicode string tests
- check &"""{"αβγ"}""", "αβγ"
- check &"""{"αβγ":>5}""", " αβγ"
- check &"""{"αβγ":<5}""", "αβγ "
- check &"""a{"a"}α{"α"}€{"€"}𐍈{"𐍈"}""", "aaαα€€𐍈𐍈"
- check &"""a{"a":2}α{"α":2}€{"€":2}𐍈{"𐍈":2}""", "aa αα €€ 𐍈𐍈 "
- # Invalid unicode sequences should be handled as plain strings.
- # Invalid examples taken from: https://stackoverflow.com/a/3886015/1804173
- let invalidUtf8 = [
- "\xc3\x28", "\xa0\xa1",
- "\xe2\x28\xa1", "\xe2\x82\x28",
- "\xf0\x28\x8c\xbc", "\xf0\x90\x28\xbc", "\xf0\x28\x8c\x28"
- ]
- for s in invalidUtf8:
- check &"{s:>5}", repeat(" ", 5-s.len) & s
-
- # bug #11089
- let flfoo: float = 1.0
- check &"{flfoo}", "1.0"
-
- # bug #11092
- check &"{high(int64)}", "9223372036854775807"
- check &"{low(int64)}", "-9223372036854775808"
-
- doAssert fmt"{'a'} {'b'}" == "a b"
-
- echo("All tests ok")
diff --git a/lib/pure/strmisc.nim b/lib/pure/strmisc.nim
index 061c2063b6758..5060deb78d0e7 100644
--- a/lib/pure/strmisc.nim
+++ b/lib/pure/strmisc.nim
@@ -84,24 +84,3 @@ proc rpartition*(s: string, sep: string): (string, string, string)
doAssert rpartition("foofoobar", "bar") == ("foofoo", "bar", "")
return partition(s, sep, right = true)
-
-when isMainModule:
- doAssert expandTabs("\t", 4) == " "
- doAssert expandTabs("\tfoo\t", 4) == " foo "
- doAssert expandTabs("\tfoo\tbar", 4) == " foo bar"
- doAssert expandTabs("\tfoo\tbar\t", 4) == " foo bar "
- doAssert expandTabs("", 4) == ""
- doAssert expandTabs("", 0) == ""
- doAssert expandTabs("\t\t\t", 0) == ""
-
- doAssert partition("foo:bar", ":") == ("foo", ":", "bar")
- doAssert partition("foobarbar", "bar") == ("foo", "bar", "bar")
- doAssert partition("foobarbar", "bank") == ("foobarbar", "", "")
- doAssert partition("foobarbar", "foo") == ("", "foo", "barbar")
- doAssert partition("foofoobar", "bar") == ("foofoo", "bar", "")
-
- doAssert rpartition("foo:bar", ":") == ("foo", ":", "bar")
- doAssert rpartition("foobarbar", "bar") == ("foobar", "bar", "")
- doAssert rpartition("foobarbar", "bank") == ("", "", "foobarbar")
- doAssert rpartition("foobarbar", "foo") == ("", "foo", "barbar")
- doAssert rpartition("foofoobar", "bar") == ("foofoo", "bar", "")
diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim
index f078b0d207c59..f7032f428fba8 100644
--- a/lib/pure/strscans.nim
+++ b/lib/pure/strscans.nim
@@ -633,115 +633,3 @@ macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool =
result.add res
when defined(debugScanp):
echo repr result
-
-
-when isMainModule:
- proc twoDigits(input: string; x: var int; start: int): int =
- if start+1 < input.len and input[start] == '0' and input[start+1] == '0':
- result = 2
- x = 13
- else:
- result = 0
-
- proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int =
- result = 0
- while start+result < input.len and input[start+result] in seps: inc result
-
- proc demangle(s: string; res: var string; start: int): int =
- while result+start < s.len and s[result+start] in {'_', '@'}: inc result
- res = ""
- while result+start < s.len and s[result+start] > ' ' and s[result+start] != '_':
- res.add s[result+start]
- inc result
- while result+start < s.len and s[result+start] > ' ':
- inc result
-
- proc parseGDB(resp: string): seq[string] =
- const
- digits = {'0'..'9'}
- hexdigits = digits + {'a'..'f', 'A'..'F'}
- whites = {' ', '\t', '\C', '\L'}
- result = @[]
- var idx = 0
- while true:
- var prc = ""
- var info = ""
- if scanp(resp, idx, *`whites`, '#', *`digits`, +`whites`, ?("0x", *`hexdigits`, " in "),
- demangle($input, prc, $index), *`whites`, '(', * ~ ')', ')',
- *`whites`, "at ", +(~{'\C', '\L'} -> info.add($_))):
- result.add prc & " " & info
- else:
- break
-
- var key, val: string
- var intval: int
- var floatval: float
- doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intval, floatVal)
- doAssert key == "abc"
- doAssert val == "xyz"
- doAssert intval == 89
- doAssert floatVal == 33.25
-
- var binval: int
- var octval: int
- var hexval: int
- doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
- doAssert binval == 0b0101
- doAssert octval == 0o1234
- doAssert hexval == 0xabcd
-
- let xx = scanf("$abc", "$$$i", intval)
- doAssert xx == false
-
-
- let xx2 = scanf("$1234", "$$$i", intval)
- doAssert xx2
-
- let yy = scanf(";.--Breakpoint00 [output]",
- "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
- intVal, key)
- doAssert yy
- doAssert key == "output"
- doAssert intVal == 13
-
- var ident = ""
- var idx = 0
- let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{
- ' ', '\t'}, "x"), ~'U', "Z")
- doAssert zz
- doAssert ident == "foobar"
-
- const digits = {'0'..'9'}
- var year = 0
- var idx2 = 0
- if scanp("201655-8-9", idx2, `digits`{4, 6} -> (year = year * 10 + ord($_) -
- ord('0')), "-8", "-9"):
- doAssert year == 201655
-
- const gdbOut = """
- #0 @foo_96013_1208911747@8 (x0=...)
- at c:/users/anwender/projects/nim/temp.nim:11
- #1 0x00417754 in tempInit000 () at c:/users/anwender/projects/nim/temp.nim:13
- #2 0x0041768d in NimMainInner ()
- at c:/users/anwender/projects/nim/lib/system.nim:2605
- #3 0x004176b1 in NimMain ()
- at c:/users/anwender/projects/nim/lib/system.nim:2613
- #4 0x004176db in main (argc=1, args=0x712cc8, env=0x711ca8)
- at c:/users/anwender/projects/nim/lib/system.nim:2620"""
- const result = @["foo c:/users/anwender/projects/nim/temp.nim:11",
- "tempInit000 c:/users/anwender/projects/nim/temp.nim:13",
- "NimMainInner c:/users/anwender/projects/nim/lib/system.nim:2605",
- "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613",
- "main c:/users/anwender/projects/nim/lib/system.nim:2620"]
- #doAssert parseGDB(gdbOut) == result
-
- # bug #6487
- var count = 0
-
- proc test(): string =
- inc count
- result = ",123123"
-
- var a: int
- discard scanf(test(), ",$i", a)
- doAssert count == 1
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 7b726e134059a..7cf668d192a58 100644
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -420,15 +420,3 @@ proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {.
else:
add(result, f[i])
inc(i)
-
-when isMainModule:
- var x = {"k": "v", "11": "22", "565": "67"}.newStringTable
- assert x["k"] == "v"
- assert x["11"] == "22"
- assert x["565"] == "67"
- x["11"] = "23"
- assert x["11"] == "23"
-
- x.clear(modeCaseInsensitive)
- x["11"] = "22"
- assert x["11"] == "22"
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 0eff80863ac40..f0b447de7938a 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -2920,220 +2920,3 @@ proc isEmptyOrWhitespace*(s: string): bool {.noSideEffect, rtl,
extern: "nsuIsEmptyOrWhitespace".} =
## Checks if `s` is empty or consists entirely of whitespace characters.
result = s.allCharsInSet(Whitespace)
-
-
-when isMainModule:
- proc nonStaticTests =
- doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
- when not defined(js):
- doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235." # bugs 8242, 12586
- doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"
- doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
- doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in
- ["1,0e-11", "1,0e-011"]
- # bug #6589
- when not defined(js):
- doAssert formatFloat(123.456, ffScientific, precision = -1) == "1.234560e+02"
-
- doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
- doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb"
-
- block: # formatSize tests
- when not defined(js):
- 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"
- doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB"
- doAssert formatSize(4096, includeSpace = true) == "4 KiB"
- doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB"
-
- block: # formatEng tests
- doAssert formatEng(0, 2, trim = false) == "0.00"
- doAssert formatEng(0, 2) == "0"
- doAssert formatEng(53, 2, trim = false) == "53.00"
- doAssert formatEng(0.053, 2, trim = false) == "53.00e-3"
- doAssert formatEng(0.053, 4, trim = false) == "53.0000e-3"
- doAssert formatEng(0.053, 4, trim = true) == "53e-3"
- doAssert formatEng(0.053, 0) == "53e-3"
- doAssert formatEng(52731234) == "52.731234e6"
- doAssert formatEng(-52731234) == "-52.731234e6"
- doAssert formatEng(52731234, 1) == "52.7e6"
- doAssert formatEng(-52731234, 1) == "-52.7e6"
- doAssert formatEng(52731234, 1, decimalSep = ',') == "52,7e6"
- doAssert formatEng(-52731234, 1, decimalSep = ',') == "-52,7e6"
-
- doAssert formatEng(4100, siPrefix = true, unit = "V") == "4.1 kV"
- doAssert formatEng(4.1, siPrefix = true, unit = "V",
- useUnitSpace = true) == "4.1 V"
- doAssert formatEng(4.1, siPrefix = true) == "4.1" # Note lack of space
- doAssert formatEng(4100, siPrefix = true) == "4.1 k"
- doAssert formatEng(4.1, siPrefix = true, unit = "",
- useUnitSpace = true) == "4.1 " # Includes space
- doAssert formatEng(4100, siPrefix = true, unit = "") == "4.1 k"
- doAssert formatEng(4100) == "4.1e3"
- doAssert formatEng(4100, unit = "V", useUnitSpace = true) == "4.1e3 V"
- doAssert formatEng(4100, unit = "", useUnitSpace = true) == "4.1e3 "
- # Don't use SI prefix as number is too big
- doAssert formatEng(3.1e22, siPrefix = true, unit = "a",
- useUnitSpace = true) == "31e21 a"
- # Don't use SI prefix as number is too small
- doAssert formatEng(3.1e-25, siPrefix = true, unit = "A",
- useUnitSpace = true) == "310e-27 A"
-
- proc staticTests =
- doAssert align("abc", 4) == " abc"
- doAssert align("a", 0) == "a"
- doAssert align("1232", 6) == " 1232"
- doAssert align("1232", 6, '#') == "##1232"
-
- doAssert alignLeft("abc", 4) == "abc "
- doAssert alignLeft("a", 0) == "a"
- doAssert alignLeft("1232", 6) == "1232 "
- doAssert alignLeft("1232", 6, '#') == "1232##"
-
- doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] ==
- "The cat eats fish."
-
- doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
- doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
-
- doAssert "-lda-ldz -ld abc".replaceWord("") == "-lda-ldz -ld abc"
- doAssert "oo".replace("", "abc") == "oo"
-
- type MyEnum = enum enA, enB, enC, enuD, enE
- doAssert parseEnum[MyEnum]("enu_D") == enuD
-
- doAssert parseEnum("invalid enum value", enC) == enC
-
- doAssert center("foo", 13) == " foo "
- doAssert center("foo", 0) == "foo"
- doAssert center("foo", 3, fillChar = 'a') == "foo"
- doAssert center("foo", 10, fillChar = '\t') == "\t\t\tfoo\t\t\t\t"
-
- doAssert count("foofoofoo", "foofoo") == 1
- doAssert count("foofoofoo", "foofoo", overlapping = true) == 2
- doAssert count("foofoofoo", 'f') == 3
- doAssert count("foofoofoobar", {'f', 'b'}) == 4
-
- doAssert strip(" foofoofoo ") == "foofoofoo"
- doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
- doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
- doAssert strip("stripme but don't strip this stripme",
- chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
- " but don't strip this "
- doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
- doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
-
- doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar"
-
- doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab"
- doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.",
- "PEOPLE!")) == "HELLO PEOPLE!"
- doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa"
-
- doAssert isAlphaAscii('r')
- doAssert isAlphaAscii('A')
- doAssert(not isAlphaAscii('$'))
-
- doAssert isAlphaNumeric('3')
- doAssert isAlphaNumeric('R')
- doAssert(not isAlphaNumeric('!'))
-
- doAssert isDigit('3')
- doAssert(not isDigit('a'))
- doAssert(not isDigit('%'))
-
- doAssert isSpaceAscii('\t')
- doAssert isSpaceAscii('\l')
- doAssert(not isSpaceAscii('A'))
-
- doAssert(isEmptyOrWhitespace(""))
- doAssert(isEmptyOrWhitespace(" "))
- doAssert(isEmptyOrWhitespace("\t\l \v\r\f"))
- doAssert(not isEmptyOrWhitespace("ABc \td"))
-
- doAssert isLowerAscii('a')
- doAssert isLowerAscii('z')
- doAssert(not isLowerAscii('A'))
- doAssert(not isLowerAscii('5'))
- doAssert(not isLowerAscii('&'))
- doAssert(not isLowerAscii(' '))
-
- doAssert isUpperAscii('A')
- doAssert(not isUpperAscii('b'))
- doAssert(not isUpperAscii('5'))
- doAssert(not isUpperAscii('%'))
-
- 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", 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"]
-
- doAssert(unescape(r"\x013", "", "") == "\x013")
-
- doAssert join(["foo", "bar", "baz"]) == "foobarbaz"
- doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz"
- doAssert join([1, 2, 3]) == "123"
- doAssert join(@[1, 2, 3], ", ") == "1, 2, 3"
-
- doAssert """~~!!foo
-~~!!bar
-~~!!baz""".unindent(2, "~~!!") == "foo\nbar\nbaz"
-
- doAssert """~~!!foo
-~~!!bar
-~~!!baz""".unindent(2, "~~!!aa") == "~~!!foo\n~~!!bar\n~~!!baz"
- doAssert """~~foo
-~~ bar
-~~ baz""".unindent(4, "~") == "foo\n bar\n baz"
- doAssert """foo
-bar
- baz
- """.unindent(4) == "foo\nbar\nbaz\n"
- doAssert """foo
- bar
- baz
- """.unindent(2) == "foo\n bar\n baz\n"
- doAssert """foo
- bar
- baz
- """.unindent(100) == "foo\nbar\nbaz\n"
-
- doAssert """foo
- foo
- bar
- """.unindent() == "foo\nfoo\nbar\n"
-
- let s = " this is an example "
- let s2 = ":this;is;an:example;;"
-
- doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
- doAssert s2.split(seps = {':', ';'}) == @["", "this", "is", "an", "example",
- "", ""]
- 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 "]
-
- doAssert s.splitWhitespace() == @["this", "is", "an", "example"]
- doAssert s.splitWhitespace(maxsplit = 1) == @["this", "is an example "]
- doAssert s.splitWhitespace(maxsplit = 2) == @["this", "is", "an example "]
- doAssert s.splitWhitespace(maxsplit = 3) == @["this", "is", "an", "example "]
- doAssert s.splitWhitespace(maxsplit = 4) == @["this", "is", "an", "example"]
-
- block: # startsWith / endsWith char tests
- var s = "abcdef"
- doAssert s.startsWith('a')
- doAssert s.startsWith('b') == false
- doAssert s.endsWith('f')
- doAssert s.endsWith('a') == false
- doAssert s.endsWith('\0') == false
-
- #echo("strutils tests passed")
-
- nonStaticTests()
- staticTests()
- static: staticTests()
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index 8839a77671933..a28e98cafb397 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -1169,219 +1169,3 @@ proc alignLeft*(s: string, count: Natural, padding = ' '.Rune): string {.
result.add padStr
else:
result = s
-
-
-when isMainModule:
-
- proc asRune(s: static[string]): Rune =
- ## Compile-time conversion proc for converting string literals to a Rune
- ## value. Returns the first Rune of the specified string.
- ##
- ## Shortcuts code like ``"å".runeAt(0)`` to ``"å".asRune`` and returns a
- ## compile-time constant.
- if s.len == 0: Rune(0)
- else: s.runeAt(0)
-
- let
- someString = "öÑ"
- someRunes = toRunes(someString)
- compared = (someString == $someRunes)
- doAssert compared == true
-
- proc testReplacements(word: string): string =
- case word
- of "two":
- return "2"
- of "foo":
- return "BAR"
- of "βeta":
- return "beta"
- of "alpha":
- return "αlpha"
- else:
- return "12345"
-
- doAssert translate("two not alpha foo βeta", testReplacements) == "2 12345 αlpha BAR beta"
- doAssert translate(" two not foo βeta ", testReplacements) == " 2 12345 BAR beta "
-
- doAssert title("foo bar") == "Foo Bar"
- doAssert title("αlpha βeta γamma") == "Αlpha Βeta Γamma"
- doAssert title("") == ""
-
- doAssert capitalize("βeta") == "Βeta"
- doAssert capitalize("foo") == "Foo"
- doAssert capitalize("") == ""
-
- doAssert swapCase("FooBar") == "fOObAR"
- doAssert swapCase(" ") == " "
- doAssert swapCase("Αlpha Βeta Γamma") == "αLPHA βETA γAMMA"
- doAssert swapCase("a✓B") == "A✓b"
- doAssert swapCase("Јамогујестистаклоитоминештети") == "јАМОГУЈЕСТИСТАКЛОИТОМИНЕШТЕТИ"
- doAssert swapCase("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει") == "ὝΑΛΟΝΦΑΓΕῖΝΔΎΝΑΜΑΙΤΟῦΤΟΟὔΜΕΒΛΆΠΤΕΙ"
- doAssert swapCase("Կրնամապակիուտեևինծիանհանգիստչըներ") == "կՐՆԱՄԱՊԱԿԻՈՒՏԵևԻՆԾԻԱՆՀԱՆԳԻՍՏՉԸՆԵՐ"
- doAssert swapCase("") == ""
-
- doAssert isAlpha("r")
- doAssert isAlpha("α")
- doAssert isAlpha("ϙ")
- doAssert isAlpha("ஶ")
- doAssert(not isAlpha("$"))
- doAssert(not isAlpha(""))
-
- doAssert isAlpha("Βeta")
- doAssert isAlpha("Args")
- doAssert isAlpha("𐌼𐌰𐌲𐌲𐌻𐌴𐍃𐍄𐌰𐌽")
- doAssert isAlpha("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει")
- doAssert isAlpha("Јамогујестистаклоитоминештети")
- doAssert isAlpha("Կրնամապակիուտեևինծիանհանգիստչըներ")
- doAssert(not isAlpha("$Foo✓"))
- doAssert(not isAlpha("⠙⠕⠑⠎⠝⠞"))
-
- doAssert isSpace("\t")
- doAssert isSpace("\l")
- doAssert(not isSpace("Β"))
- doAssert(not isSpace("Βeta"))
-
- doAssert isSpace("\t\l \v\r\f")
- doAssert isSpace(" ")
- doAssert(not isSpace(""))
- doAssert(not isSpace("ΑΓc \td"))
-
- doAssert(not isLower(' '.Rune))
-
- doAssert(not isUpper(' '.Rune))
-
- doAssert toUpper("Γ") == "Γ"
- doAssert toUpper("b") == "B"
- doAssert toUpper("α") == "Α"
- doAssert toUpper("✓") == "✓"
- doAssert toUpper("ϙ") == "Ϙ"
- doAssert toUpper("") == ""
-
- doAssert toUpper("ΑΒΓ") == "ΑΒΓ"
- doAssert toUpper("AAccβ") == "AACCΒ"
- doAssert toUpper("A✓$β") == "A✓$Β"
-
- doAssert toLower("a") == "a"
- doAssert toLower("γ") == "γ"
- doAssert toLower("Γ") == "γ"
- doAssert toLower("4") == "4"
- doAssert toLower("Ϙ") == "ϙ"
- doAssert toLower("") == ""
-
- doAssert toLower("abcdγ") == "abcdγ"
- doAssert toLower("abCDΓ") == "abcdγ"
- doAssert toLower("33aaΓ") == "33aaγ"
-
- doAssert reversed("Reverse this!") == "!siht esreveR"
- doAssert reversed("先秦兩漢") == "漢兩秦先"
- doAssert reversed("as⃝df̅") == "f̅ds⃝a"
- doAssert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞"
- doAssert reversed("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει") == "ιετπάλβεμὔοοτῦοτιαμανύδνῖεγαϕνολαὕ"
- doAssert reversed("Јамогујестистаклоитоминештети") == "итетшенимотиолкатситсејугомаЈ"
- doAssert reversed("Կրնամապակիուտեևինծիանհանգիստչըներ") == "րենըչտսիգնահնաիծնիևետւոիկապամանրԿ"
- doAssert len(toRunes("as⃝df̅")) == runeLen("as⃝df̅")
- const test = "as⃝"
- doAssert lastRune(test, test.len-1)[1] == 3
- doAssert graphemeLen("è", 0) == 2
-
- # test for rune positioning and runeSubStr()
- let s = "Hänsel ««: 10,00€"
-
- var t = ""
- for c in s.utf8:
- t.add c
-
- doAssert(s == t)
-
- doAssert(runeReverseOffset(s, 1) == (20, 18))
- doAssert(runeReverseOffset(s, 19) == (-1, 18))
-
- doAssert(runeStrAtPos(s, 0) == "H")
- doAssert(runeSubStr(s, 0, 1) == "H")
- doAssert(runeStrAtPos(s, 10) == ":")
- doAssert(runeSubStr(s, 10, 1) == ":")
- doAssert(runeStrAtPos(s, 9) == "«")
- doAssert(runeSubStr(s, 9, 1) == "«")
- doAssert(runeStrAtPos(s, 17) == "€")
- doAssert(runeSubStr(s, 17, 1) == "€")
- # echo runeStrAtPos(s, 18) # index error
-
- doAssert(runeSubStr(s, 0) == "Hänsel ««: 10,00€")
- doAssert(runeSubStr(s, -18) == "Hänsel ««: 10,00€")
- doAssert(runeSubStr(s, 10) == ": 10,00€")
- doAssert(runeSubStr(s, 18) == "")
- doAssert(runeSubStr(s, 0, 10) == "Hänsel ««")
-
- doAssert(runeSubStr(s, 12) == "10,00€")
- doAssert(runeSubStr(s, -6) == "10,00€")
-
- doAssert(runeSubStr(s, 12, 5) == "10,00")
- doAssert(runeSubStr(s, 12, -1) == "10,00")
- doAssert(runeSubStr(s, -6, 5) == "10,00")
- doAssert(runeSubStr(s, -6, -1) == "10,00")
-
- doAssert(runeSubStr(s, 0, 100) == "Hänsel ««: 10,00€")
- doAssert(runeSubStr(s, -100, 100) == "Hänsel ««: 10,00€")
- doAssert(runeSubStr(s, 0, -100) == "")
- doAssert(runeSubStr(s, 100, -100) == "")
-
- block splitTests:
- let s = " this is an example "
- let s2 = ":this;is;an:example;;"
- let s3 = ":this×is×an:example××"
- doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
- doAssert s2.split(seps = [':'.Rune, ';'.Rune]) == @["", "this", "is", "an",
- "example", "", ""]
- doAssert s3.split(seps = [':'.Rune, "×".asRune]) == @["", "this", "is",
- "an", "example", "", ""]
- doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "]
- doAssert s.split(' '.Rune, maxsplit = 1) == @["", "this is an example "]
- doAssert s3.split("×".runeAt(0)) == @[":this", "is", "an:example", "", ""]
-
- block stripTests:
- doAssert(strip("") == "")
- doAssert(strip(" ") == "")
- doAssert(strip("y") == "y")
- doAssert(strip(" foofoofoo ") == "foofoofoo")
- doAssert(strip("sfoofoofoos", runes = ['s'.Rune]) == "foofoofoo")
-
- block:
- let stripTestRunes = ['b'.Rune, 'a'.Rune, 'r'.Rune]
- doAssert(strip("barfoofoofoobar", runes = stripTestRunes) == "foofoofoo")
- doAssert(strip("sfoofoofoos", leading = false, runes = ['s'.Rune]) == "sfoofoofoo")
- doAssert(strip("sfoofoofoos", trailing = false, runes = ['s'.Rune]) == "foofoofoos")
-
- block:
- let stripTestRunes = ["«".asRune, "»".asRune]
- doAssert(strip("«TEXT»", runes = stripTestRunes) == "TEXT")
- doAssert(strip("copyright©", leading = false, runes = ["©".asRune]) == "copyright")
- doAssert(strip("¿Question?", trailing = false, runes = ["¿".asRune]) == "Question?")
- doAssert(strip("×text×", leading = false, runes = ["×".asRune]) == "×text")
- doAssert(strip("×text×", trailing = false, runes = ["×".asRune]) == "text×")
-
- block repeatTests:
- doAssert repeat('c'.Rune, 5) == "ccccc"
- doAssert repeat("×".asRune, 5) == "×××××"
-
- block alignTests:
- doAssert align("abc", 4) == " abc"
- doAssert align("a", 0) == "a"
- doAssert align("1232", 6) == " 1232"
- doAssert align("1232", 6, '#'.Rune) == "##1232"
- doAssert align("1232", 6, "×".asRune) == "××1232"
- doAssert alignLeft("abc", 4) == "abc "
- doAssert alignLeft("a", 0) == "a"
- doAssert alignLeft("1232", 6) == "1232 "
- doAssert alignLeft("1232", 6, '#'.Rune) == "1232##"
- doAssert alignLeft("1232", 6, "×".asRune) == "1232××"
-
- block differentSizes:
- # upper and lower variants have different number of bytes
- doAssert toLower("AẞC") == "aßc"
- doAssert toLower("ȺẞCD") == "ⱥßcd"
- doAssert toUpper("ⱥbc") == "ȺBC"
- doAssert toUpper("rsⱦuv") == "RSȾUV"
- doAssert swapCase("ⱥbCd") == "ȺBcD"
- doAssert swapCase("XyꟆaB") == "xYᶎAb"
- doAssert swapCase("aᵹcᲈd") == "AꝽCꙊD"
diff --git a/lib/pure/unidecode/unidecode.nim b/lib/pure/unidecode/unidecode.nim
index 30aaa7cd87f12..9a10ccc0073af 100644
--- a/lib/pure/unidecode/unidecode.nim
+++ b/lib/pure/unidecode/unidecode.nim
@@ -66,8 +66,3 @@ proc unidecode*(s: string): string =
var c = int(r)
if c <=% 127: add(result, chr(c))
elif c <% translationTable.len: add(result, translationTable[c-128])
-
-when isMainModule:
- #loadUnidecodeTable("lib/pure/unidecode/unidecode.dat")
- doAssert unidecode("Äußerst") == "Ausserst"
- doAssert unidecode("北京") == "Bei Jing "
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index 3e107a6b85ca5..15d0996a78cb3 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -503,288 +503,3 @@ proc getDataUri*(data, mime: string, encoding = "utf-8"): string {.since: (1, 3)
runnableExamples: static: doAssert getDataUri("Nim", "text/plain") == "data:text/plain;charset=utf-8;base64,Tmlt"
assert encoding.len > 0 and mime.len > 0 # Must *not* be URL-Safe, see RFC-2397
result = "data:" & mime & ";charset=" & encoding & ";base64," & base64.encode(data)
-
-
-when isMainModule:
- block:
- const test1 = "abc\L+def xyz"
- doAssert encodeUrl(test1) == "abc%0A%2Bdef+xyz"
- doAssert decodeUrl(encodeUrl(test1)) == test1
- doAssert encodeUrl(test1, false) == "abc%0A%2Bdef%20xyz"
- doAssert decodeUrl(encodeUrl(test1, false), false) == test1
- doAssert decodeUrl(encodeUrl(test1)) == test1
-
- block:
- let str = "http://localhost"
- let test = parseUri(str)
- doAssert test.path == ""
-
- block:
- let str = "http://localhost/"
- let test = parseUri(str)
- doAssert test.path == "/"
-
- block:
- let str = "http://localhost:8080/test"
- let test = parseUri(str)
- doAssert test.scheme == "http"
- doAssert test.port == "8080"
- doAssert test.path == "/test"
- doAssert test.hostname == "localhost"
- doAssert($test == str)
-
- block:
- let str = "foo://username:password@example.com:8042/over/there" &
- "/index.dtb?type=animal&name=narwhal#nose"
- let test = parseUri(str)
- doAssert test.scheme == "foo"
- doAssert test.username == "username"
- doAssert test.password == "password"
- doAssert test.hostname == "example.com"
- doAssert test.port == "8042"
- doAssert test.path == "/over/there/index.dtb"
- doAssert test.query == "type=animal&name=narwhal"
- doAssert test.anchor == "nose"
- doAssert($test == str)
-
- block:
- # IPv6 address
- let str = "foo://[::1]:1234/bar?baz=true&qux#quux"
- let uri = parseUri(str)
- doAssert uri.scheme == "foo"
- doAssert uri.hostname == "::1"
- doAssert uri.port == "1234"
- doAssert uri.path == "/bar"
- doAssert uri.query == "baz=true&qux"
- doAssert uri.anchor == "quux"
-
- block:
- let str = "urn:example:animal:ferret:nose"
- let test = parseUri(str)
- doAssert test.scheme == "urn"
- doAssert test.path == "example:animal:ferret:nose"
- doAssert($test == str)
-
- block:
- let str = "mailto:username@example.com?subject=Topic"
- let test = parseUri(str)
- doAssert test.scheme == "mailto"
- doAssert test.username == "username"
- doAssert test.hostname == "example.com"
- doAssert test.query == "subject=Topic"
- doAssert($test == str)
-
- block:
- let str = "magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar"
- let test = parseUri(str)
- doAssert test.scheme == "magnet"
- doAssert test.query == "xt=urn:sha1:72hsga62ba515sbd62&dn=foobar"
- doAssert($test == str)
-
- block:
- let str = "/test/foo/bar?q=2#asdf"
- let test = parseUri(str)
- doAssert test.scheme == ""
- doAssert test.path == "/test/foo/bar"
- doAssert test.query == "q=2"
- doAssert test.anchor == "asdf"
- doAssert($test == str)
-
- block:
- let str = "test/no/slash"
- let test = parseUri(str)
- doAssert test.path == "test/no/slash"
- doAssert($test == str)
-
- block:
- let str = "//git@github.com:dom96/packages"
- let test = parseUri(str)
- doAssert test.scheme == ""
- doAssert test.username == "git"
- doAssert test.hostname == "github.com"
- doAssert test.port == "dom96"
- doAssert test.path == "/packages"
-
- block:
- let str = "file:///foo/bar/baz.txt"
- let test = parseUri(str)
- doAssert test.scheme == "file"
- doAssert test.username == ""
- doAssert test.hostname == ""
- doAssert test.port == ""
- doAssert test.path == "/foo/bar/baz.txt"
-
- # Remove dot segments tests
- block:
- doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"
-
- # Combine tests
- block:
- let concat = combine(parseUri("http://google.com/foo/bar/"), parseUri("baz"))
- doAssert concat.path == "/foo/bar/baz"
- doAssert concat.hostname == "google.com"
- doAssert concat.scheme == "http"
-
- block:
- let concat = combine(parseUri("http://google.com/foo"), parseUri("/baz"))
- doAssert concat.path == "/baz"
- doAssert concat.hostname == "google.com"
- doAssert concat.scheme == "http"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
- doAssert concat.path == "/foo/bar"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test"), parseUri("/bar"))
- doAssert concat.path == "/bar"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
- doAssert concat.path == "/foo/bar"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar"))
- doAssert concat.path == "/foo/test/bar"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"))
- doAssert concat.path == "/foo/test/bar/"
-
- block:
- let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"),
- parseUri("baz"))
- doAssert concat.path == "/foo/test/bar/baz"
-
- # `/` tests
- block:
- let test = parseUri("http://example.com/foo") / "bar/asd"
- doAssert test.path == "/foo/bar/asd"
-
- block:
- let test = parseUri("http://example.com/foo/") / "/bar/asd"
- doAssert test.path == "/foo/bar/asd"
-
- # removeDotSegments tests
- block:
- # empty test
- doAssert removeDotSegments("") == ""
-
- # bug #3207
- block:
- doAssert parseUri("http://qq/1").combine(parseUri("https://qqq")).`$` == "https://qqq"
-
- # bug #4959
- block:
- let foo = parseUri("http://example.com") / "/baz"
- doAssert foo.path == "/baz"
-
- # bug found on stream 13/10/17
- block:
- let foo = parseUri("http://localhost:9515") / "status"
- doAssert $foo == "http://localhost:9515/status"
-
- # bug #6649 #6652
- block:
- var foo = parseUri("http://example.com")
- foo.hostname = "example.com"
- foo.path = "baz"
- doAssert $foo == "http://example.com/baz"
-
- foo.hostname = "example.com/"
- foo.path = "baz"
- doAssert $foo == "http://example.com/baz"
-
- foo.hostname = "example.com"
- foo.path = "/baz"
- doAssert $foo == "http://example.com/baz"
-
- foo.hostname = "example.com/"
- foo.path = "/baz"
- doAssert $foo == "http://example.com/baz"
-
- foo.hostname = "example.com/"
- foo.port = "8000"
- foo.path = "baz"
- doAssert $foo == "http://example.com:8000/baz"
-
- foo = parseUri("file:/dir/file")
- foo.path = "relative"
- doAssert $foo == "file:relative"
-
- # isAbsolute tests
- block:
- doAssert "www.google.com".parseUri().isAbsolute() == false
- doAssert "http://www.google.com".parseUri().isAbsolute() == true
- doAssert "file:/dir/file".parseUri().isAbsolute() == true
- doAssert "file://localhost/dir/file".parseUri().isAbsolute() == true
- doAssert "urn:ISSN:1535-3613".parseUri().isAbsolute() == true
-
- # path-relative URL *relative
- doAssert "about".parseUri().isAbsolute == false
- doAssert "about/staff.html".parseUri().isAbsolute == false
- doAssert "about/staff.html?".parseUri().isAbsolute == false
- doAssert "about/staff.html?parameters".parseUri().isAbsolute == false
-
- # absolute-path-relative URL *relative
- doAssert "/".parseUri().isAbsolute == false
- doAssert "/about".parseUri().isAbsolute == false
- doAssert "/about/staff.html".parseUri().isAbsolute == false
- doAssert "/about/staff.html?".parseUri().isAbsolute == false
- doAssert "/about/staff.html?parameters".parseUri().isAbsolute == false
-
- # scheme-relative URL *relative
- doAssert "//username:password@example.com:8888".parseUri().isAbsolute == false
- doAssert "//username@example.com".parseUri().isAbsolute == false
- doAssert "//example.com".parseUri().isAbsolute == false
- doAssert "//example.com/".parseUri().isAbsolute == false
- doAssert "//example.com/about".parseUri().isAbsolute == false
- doAssert "//example.com/about/staff.html".parseUri().isAbsolute == false
- doAssert "//example.com/about/staff.html?".parseUri().isAbsolute == false
- doAssert "//example.com/about/staff.html?parameters".parseUri().isAbsolute == false
-
- # absolute URL *absolute
- doAssert "https://username:password@example.com:8888".parseUri().isAbsolute == true
- doAssert "https://username@example.com".parseUri().isAbsolute == true
- doAssert "https://example.com".parseUri().isAbsolute == true
- doAssert "https://example.com/".parseUri().isAbsolute == true
- doAssert "https://example.com/about".parseUri().isAbsolute == true
- doAssert "https://example.com/about/staff.html".parseUri().isAbsolute == true
- doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true
- doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true
-
- # encodeQuery tests
- block:
- doAssert encodeQuery({:}) == ""
- doAssert encodeQuery({"foo": "bar"}) == "foo=bar"
- doAssert encodeQuery({"foo": "bar & baz"}) == "foo=bar+%26+baz"
- doAssert encodeQuery({"foo": "bar & baz"}, usePlus = false) == "foo=bar%20%26%20baz"
- doAssert encodeQuery({"foo": ""}) == "foo"
- doAssert encodeQuery({"foo": ""}, omitEq = false) == "foo="
- doAssert encodeQuery({"a": "1", "b": "", "c": "3"}) == "a=1&b&c=3"
- doAssert encodeQuery({"a": "1", "b": "", "c": "3"}, omitEq = false) == "a=1&b=&c=3"
-
- block:
- var foo = parseUri("http://example.com") / "foo" ? {"bar": "1", "baz": "qux"}
- var foo1 = parseUri("http://example.com/foo?bar=1&baz=qux")
- doAssert foo == foo1
-
- block:
- var foo = parseUri("http://example.com") / "foo" ? {"do": "do", "bar": ""}
- var foo1 = parseUri("http://example.com/foo?do=do&bar")
- doAssert foo == foo1
-
- block dataUriBase64:
- doAssert getDataUri("", "text/plain") == "data:text/plain;charset=utf-8;base64,"
- doAssert getDataUri(" ", "text/plain") == "data:text/plain;charset=utf-8;base64,IA=="
- doAssert getDataUri("c\xf7>", "text/plain") == "data:text/plain;charset=utf-8;base64,Y/c+"
- doAssert getDataUri("Hello World", "text/plain") == "data:text/plain;charset=utf-8;base64,SGVsbG8gV29ybGQ="
- doAssert getDataUri("leasure.", "text/plain") == "data:text/plain;charset=utf-8;base64,bGVhc3VyZS4="
- doAssert getDataUri("""!@#$%^&*()_+""", "text/plain") == "data:text/plain;charset=utf-8;base64,IUAjJCVeJiooKV8r"
- doAssert(getDataUri("the quick brown dog jumps over the lazy fox", "text/plain") ==
- "data:text/plain;charset=utf-8;base64,dGhlIHF1aWNrIGJyb3duIGRvZyBqdW1wcyBvdmVyIHRoZSBsYXp5IGZveA==")
- doAssert(getDataUri("""The present is theirs
- The future, for which I really worked, is mine.""", "text/plain") ==
- "data:text/plain;charset=utf-8;base64,VGhlIHByZXNlbnQgaXMgdGhlaXJzCiAgICAgIFRoZSBmdXR1cmUsIGZvciB3aGljaCBJIHJlYWxseSB3b3JrZWQsIGlzIG1pbmUu")
-
- echo("All good!")
diff --git a/lib/std/enumerate.nim b/lib/std/enumerate.nim
index 3def653c83f17..a8f0e1ba7f8b5 100644
--- a/lib/std/enumerate.nim
+++ b/lib/std/enumerate.nim
@@ -68,22 +68,3 @@ macro enumerate*(x: ForLoopStmt): untyped {.since: (1, 3).} =
result.add newFor
# now wrap the whole macro in a block to create a new scope
result = newBlockStmt(result)
-
-when isMainModule:
- let a = @[1, 3, 5, 7]
-
- block:
- var res: seq[(int, int)]
- for i, x in enumerate(a):
- res.add (i, x)
- assert res == @[(0, 1), (1, 3), (2, 5), (3, 7)]
- block:
- var res: seq[(int, int)]
- for (i, x) in enumerate(a.items):
- res.add (i, x)
- assert res == @[(0, 1), (1, 3), (2, 5), (3, 7)]
- block:
- var res: seq[(int, int)]
- for i, x in enumerate(3, a):
- res.add (i, x)
- assert res == @[(3, 1), (4, 3), (5, 5), (6, 7)]
diff --git a/lib/std/monotimes.nim b/lib/std/monotimes.nim
index f819cbc8d1865..c56bf77b30c61 100644
--- a/lib/std/monotimes.nim
+++ b/lib/std/monotimes.nim
@@ -152,19 +152,3 @@ proc high*(typ: typedesc[MonoTime]): MonoTime =
proc low*(typ: typedesc[MonoTime]): MonoTime =
## Returns the lowest representable `MonoTime`.
MonoTime(ticks: low(int64))
-
-when isMainModule:
- let d = initDuration(nanoseconds = 10)
- let t1 = getMonoTime()
- let t2 = t1 + d
-
- doAssert t2 - t1 == d
- doAssert t1 == t1
- doAssert t1 != t2
- doAssert t2 - d == t1
- doAssert t1 < t2
- doAssert t1 <= t2
- doAssert t1 <= t1
- doAssert not(t2 < t1)
- doAssert t1 < high(MonoTime)
- doAssert low(MonoTime) < t1
diff --git a/lib/std/sha1.nim b/lib/std/sha1.nim
index 9763b286e5f66..3c1674bcbe33d 100644
--- a/lib/std/sha1.nim
+++ b/lib/std/sha1.nim
@@ -267,16 +267,3 @@ proc `==`*(a, b: SecureHash): bool =
assert a == c
# Not a constant-time comparison, but that's acceptable in this context
Sha1Digest(a) == Sha1Digest(b)
-
-when isMainModule:
- let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
- doAssert hash1 == hash1
- doAssert parseSecureHash($hash1) == hash1
-
- template checkVector(s, exp: string) =
- doAssert secureHash(s) == parseSecureHash(exp)
-
- checkVector("", "da39a3ee5e6b4b0d3255bfef95601890afd80709")
- checkVector("abc", "a9993e364706816aba3e25717850c26c9cd0d89d")
- checkVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
- "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
diff --git a/tests/stdlib/talgorithm.nim b/tests/stdlib/talgorithm.nim
index 85ae792196d0a..59336e70d5b30 100644
--- a/tests/stdlib/talgorithm.nim
+++ b/tests/stdlib/talgorithm.nim
@@ -16,3 +16,100 @@ proc test() =
discard
test()
+
+block:
+ # Tests for lowerBound
+ var arr = @[1, 2, 3, 5, 6, 7, 8, 9]
+ assert arr.lowerBound(0) == 0
+ assert arr.lowerBound(4) == 3
+ assert arr.lowerBound(5) == 3
+ assert arr.lowerBound(10) == 8
+ arr = @[1, 5, 10]
+ assert arr.lowerBound(4) == 1
+ assert arr.lowerBound(5) == 1
+ assert arr.lowerBound(6) == 2
+ # Tests for isSorted
+ var srt1 = [1, 2, 3, 4, 4, 4, 4, 5]
+ var srt2 = ["iello", "hello"]
+ var srt3 = [1.0, 1.0, 1.0]
+ var srt4: seq[int]
+ assert srt1.isSorted(cmp) == true
+ assert srt2.isSorted(cmp) == false
+ assert srt3.isSorted(cmp) == true
+ assert srt4.isSorted(cmp) == true
+ var srtseq = newSeq[int]()
+ assert srtseq.isSorted(cmp) == true
+ # Tests for reversed
+ var arr1 = @[0, 1, 2, 3, 4]
+ assert arr1.reversed() == @[4, 3, 2, 1, 0]
+ for i in 0 .. high(arr1):
+ assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)]
+ assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i]
+
+block:
+ var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ let list2 = list.rotatedLeft(1 ..< 9, 3)
+ let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10]
+
+ doAssert list.rotateLeft(1 ..< 9, 3) == 6
+ doAssert list == expected
+ doAssert list2 == @expected
+
+ var s0, s1, s2, s3, s4, s5 = "xxxabcdefgxxx"
+
+ doAssert s0.rotateLeft(3 ..< 10, 3) == 7
+ doAssert s0 == "xxxdefgabcxxx"
+ doAssert s1.rotateLeft(3 ..< 10, 2) == 8
+ doAssert s1 == "xxxcdefgabxxx"
+ doAssert s2.rotateLeft(3 ..< 10, 4) == 6
+ doAssert s2 == "xxxefgabcdxxx"
+ doAssert s3.rotateLeft(3 ..< 10, -3) == 6
+ doAssert s3 == "xxxefgabcdxxx"
+ doAssert s4.rotateLeft(3 ..< 10, -10) == 6
+ doAssert s4 == "xxxefgabcdxxx"
+ doAssert s5.rotateLeft(3 ..< 10, 11) == 6
+ doAssert s5 == "xxxefgabcdxxx"
+
+ block product:
+ doAssert product(newSeq[seq[int]]()) == newSeq[seq[int]](), "empty input"
+ doAssert product(@[newSeq[int](), @[], @[]]) == newSeq[seq[int]](), "bit more empty input"
+ doAssert product(@[@[1, 2]]) == @[@[1, 2]], "a simple case of one element"
+ doAssert product(@[@[1, 2], @[3, 4]]) == @[@[2, 4], @[1, 4], @[2, 3], @[1,
+ 3]], "two elements"
+ doAssert product(@[@[1, 2], @[3, 4], @[5, 6]]) == @[@[2, 4, 6], @[1, 4, 6],
+ @[2, 3, 6], @[1, 3, 6], @[2, 4, 5], @[1, 4, 5], @[2, 3, 5], @[1, 3, 5]], "three elements"
+ doAssert product(@[@[1, 2], @[]]) == newSeq[seq[int]](), "two elements, but one empty"
+
+ block lowerBound:
+ doAssert lowerBound([1, 2, 4], 3, system.cmp[int]) == 2
+ doAssert lowerBound([1, 2, 2, 3], 4, system.cmp[int]) == 4
+ doAssert lowerBound([1, 2, 3, 10], 11) == 4
+
+ block upperBound:
+ doAssert upperBound([1, 2, 4], 3, system.cmp[int]) == 2
+ doAssert upperBound([1, 2, 2, 3], 3, system.cmp[int]) == 4
+ doAssert upperBound([1, 2, 3, 5], 3) == 3
+
+ block fillEmptySeq:
+ var s = newSeq[int]()
+ s.fill(0)
+
+ block testBinarySearch:
+ var noData: seq[int]
+ doAssert binarySearch(noData, 7) == -1
+ let oneData = @[1]
+ doAssert binarySearch(oneData, 1) == 0
+ doAssert binarySearch(onedata, 7) == -1
+ let someData = @[1, 3, 4, 7]
+ doAssert binarySearch(someData, 1) == 0
+ doAssert binarySearch(somedata, 7) == 3
+ doAssert binarySearch(someData, -1) == -1
+ doAssert binarySearch(someData, 5) == -1
+ doAssert binarySearch(someData, 13) == -1
+ let moreData = @[1, 3, 5, 7, 4711]
+ doAssert binarySearch(moreData, -1) == -1
+ doAssert binarySearch(moreData, 1) == 0
+ doAssert binarySearch(moreData, 5) == 2
+ doAssert binarySearch(moreData, 6) == -1
+ doAssert binarySearch(moreData, 4711) == 4
+ doAssert binarySearch(moreData, 4712) == -1
diff --git a/tests/stdlib/tcookies.nim b/tests/stdlib/tcookies.nim
new file mode 100644
index 0000000000000..95b431b19aecd
--- /dev/null
+++ b/tests/stdlib/tcookies.nim
@@ -0,0 +1,15 @@
+import cookies, times, strtabs
+
+let expire = fromUnix(0) + 1.seconds
+
+let theCookies = [
+ setCookie("test", "value", expire),
+ setCookie("test", "value", expire.local),
+ setCookie("test", "value", expire.utc)
+]
+let expected = "Set-Cookie: test=value; Expires=Thu, 01 Jan 1970 00:00:01 GMT"
+doAssert theCookies == [expected, expected, expected]
+
+let table = parseCookies("uid=1; kp=2")
+doAssert table["uid"] == "1"
+doAssert table["kp"] == "2"
diff --git a/tests/stdlib/tcritbits.nim b/tests/stdlib/tcritbits.nim
new file mode 100644
index 0000000000000..51cbb7bf21ef8
--- /dev/null
+++ b/tests/stdlib/tcritbits.nim
@@ -0,0 +1,61 @@
+import sequtils, critbits
+
+
+var r: CritBitTree[void]
+r.incl "abc"
+r.incl "xyz"
+r.incl "def"
+r.incl "definition"
+r.incl "prefix"
+r.incl "foo"
+
+doAssert r.contains"def"
+
+r.excl "def"
+assert r.missingOrExcl("foo") == false
+assert "foo" notin toSeq(r.items)
+
+assert r.missingOrExcl("foo") == true
+
+assert toSeq(r.items) == @["abc", "definition", "prefix", "xyz"]
+
+assert toSeq(r.itemsWithPrefix("de")) == @["definition"]
+var c = CritBitTree[int]()
+
+c.inc("a")
+assert c["a"] == 1
+
+c.inc("a", 4)
+assert c["a"] == 5
+
+c.inc("a", -5)
+assert c["a"] == 0
+
+c.inc("b", 2)
+assert c["b"] == 2
+
+c.inc("c", 3)
+assert c["c"] == 3
+
+c.inc("a", 1)
+assert c["a"] == 1
+
+var cf = CritBitTree[float]()
+
+cf.incl("a", 1.0)
+assert cf["a"] == 1.0
+
+cf.incl("b", 2.0)
+assert cf["b"] == 2.0
+
+cf.incl("c", 3.0)
+assert cf["c"] == 3.0
+
+assert cf.len == 3
+cf.excl("c")
+assert cf.len == 2
+
+var cb: CritBitTree[string]
+cb.incl("help", "help")
+for k in cb.keysWithPrefix("helpp"):
+ doAssert false, "there is no prefix helpp"
diff --git a/tests/stdlib/tenumerate.nim b/tests/stdlib/tenumerate.nim
new file mode 100644
index 0000000000000..e5f21bc15b6fe
--- /dev/null
+++ b/tests/stdlib/tenumerate.nim
@@ -0,0 +1,19 @@
+import std/enumerate
+
+let a = @[1, 3, 5, 7]
+
+block:
+ var res: seq[(int, int)]
+ for i, x in enumerate(a):
+ res.add (i, x)
+ assert res == @[(0, 1), (1, 3), (2, 5), (3, 7)]
+block:
+ var res: seq[(int, int)]
+ for (i, x) in enumerate(a.items):
+ res.add (i, x)
+ assert res == @[(0, 1), (1, 3), (2, 5), (3, 7)]
+block:
+ var res: seq[(int, int)]
+ for i, x in enumerate(3, a):
+ res.add (i, x)
+ assert res == @[(3, 1), (4, 3), (5, 5), (6, 7)]
diff --git a/tests/stdlib/tfenv.nim b/tests/stdlib/tfenv.nim
new file mode 100644
index 0000000000000..f58acf1c8d68e
--- /dev/null
+++ b/tests/stdlib/tfenv.nim
@@ -0,0 +1,8 @@
+import fenv
+
+
+func is_significant(x: float): bool =
+ if x > minimumPositiveValue(float) and x < maximumPositiveValue(float): true
+ else: false
+
+doAssert is_significant(10.0)
diff --git a/tests/stdlib/thashes.nim b/tests/stdlib/thashes.nim
index 259ced2aada6c..d155111ffc8a6 100644
--- a/tests/stdlib/thashes.nim
+++ b/tests/stdlib/thashes.nim
@@ -1,34 +1,71 @@
+import hashes
-discard """
-output: '''
-[Suite] hashes
+block hashes:
+ block hashing:
+ var dummy = 0.0
+ doAssert hash(dummy) == hash(-dummy)
-[Suite] hashing
+ # "VM and runtime should make the same hash value (hashIdentity)"
+ block:
+ const hi123 = hashIdentity(123)
+ doAssert hashIdentity(123) == hi123
-'''
-"""
+ # "VM and runtime should make the same hash value (hashWangYi1)"
+ block:
+ const wy123 = hashWangYi1(123)
+ doAssert hashWangYi1(123) == wy123
-import unittest, hashes
+ # "hashIdentity value incorrect at 456"
+ block:
+ doAssert hashIdentity(456) == 456
-suite "hashes":
- suite "hashing":
- test "0.0 and -0.0 should have the same hash value":
- var dummy = 0.0
- check hash(dummy) == hash(-dummy)
+ # "hashWangYi1 value incorrect at 456"
+ block:
+ when Hash.sizeof < 8:
+ doAssert hashWangYi1(456) == 1293320666
+ else:
+ doAssert hashWangYi1(456) == -6421749900419628582
- test "VM and runtime should make the same hash value (hashIdentity)":
- const hi123 = hashIdentity(123)
- check hashIdentity(123) == hi123
+block empty:
+ var
+ a = ""
+ b = newSeq[char]()
+ c = newSeq[int]()
+ d = cstring""
+ e = "abcd"
+ doAssert hash(a) == 0
+ doAssert hash(b) == 0
+ doAssert hash(c) == 0
+ doAssert hash(d) == 0
+ doAssert hashIgnoreCase(a) == 0
+ doAssert hashIgnoreStyle(a) == 0
+ doAssert hash(e, 3, 2) == 0
- test "VM and runtime should make the same hash value (hashWangYi1)":
- const wy123 = hashWangYi1(123)
- check hashWangYi1(123) == wy123
+block sameButDifferent:
+ doAssert hash("aa bb aaaa1234") == hash("aa bb aaaa1234", 0, 13)
+ doAssert hash("aa bb aaaa1234") == hash(cstring"aa bb aaaa1234")
+ doAssert hashIgnoreCase("aA bb aAAa1234") == hashIgnoreCase("aa bb aaaa1234")
+ doAssert hashIgnoreStyle("aa_bb_AAaa1234") == hashIgnoreCase("aaBBAAAa1234")
- test "hashIdentity value incorrect at 456":
- check hashIdentity(456) == 456
+block smallSize: # no multibyte hashing
+ let
+ xx = @['H', 'i']
+ ii = @[72'u8, 105]
+ ss = "Hi"
+ doAssert hash(xx) == hash(ii)
+ doAssert hash(xx) == hash(ss)
+ doAssert hash(xx) == hash(xx, 0, xx.high)
+ doAssert hash(ss) == hash(ss, 0, ss.high)
- test "hashWangYi1 value incorrect at 456":
- when Hash.sizeof < 8:
- check hashWangYi1(456) == 1293320666
- else:
- check hashWangYi1(456) == -6421749900419628582
+block largeSize: # longer than 4 characters
+ let
+ xx = @['H', 'e', 'l', 'l', 'o']
+ xxl = @['H', 'e', 'l', 'l', 'o', 'w', 'e', 'e', 'n', 's']
+ ssl = "Helloweens"
+ doAssert hash(xxl) == hash(ssl)
+ doAssert hash(xxl) == hash(xxl, 0, xxl.high)
+ doAssert hash(ssl) == hash(ssl, 0, ssl.high)
+ doAssert hash(xx) == hash(xxl, 0, 4)
+ doAssert hash(xx) == hash(ssl, 0, 4)
+ doAssert hash(xx, 0, 3) == hash(xxl, 0, 3)
+ doAssert hash(xx, 0, 3) == hash(ssl, 0, 3)
diff --git a/tests/stdlib/thttpcore.nim b/tests/stdlib/thttpcore.nim
index cb1a0875fb86f..fd5e1d90c80e0 100644
--- a/tests/stdlib/thttpcore.nim
+++ b/tests/stdlib/thttpcore.nim
@@ -1,19 +1,12 @@
-discard """
-output: "[Suite] httpcore"
-"""
-
-import unittest
-
import httpcore, strutils
-suite "httpcore":
-
- test "HttpCode":
+block:
+ block HttpCode:
assert $Http418 == "418 I'm a teapot"
assert Http418.is4xx() == true
assert Http418.is2xx() == false
- test "headers":
+ block headers:
var h = newHttpHeaders()
assert h.len == 0
h.add("Cookie", "foo")
@@ -35,7 +28,7 @@ suite "httpcore":
assert seq[string](h1["a"]).join(",") == "1,2,3"
- test "test cookies with comma":
+ block test_cookies_with_comma:
doAssert parseHeader("cookie: foo, bar") == ("cookie", @["foo, bar"])
doAssert parseHeader("cookie: foo, bar, prologue") == ("cookie", @["foo, bar, prologue"])
doAssert parseHeader("cookie: foo, bar, prologue, starlight") == ("cookie", @["foo, bar, prologue, starlight"])
@@ -52,7 +45,7 @@ suite "httpcore":
doAssert parseHeader("Accept: foo, bar, prologue") == (key: "Accept", value: @["foo", "bar", "prologue"])
doAssert parseHeader("Accept: foo, bar, prologue, starlight") == (key: "Accept", value: @["foo", "bar", "prologue", "starlight"])
- test "add empty sequence to HTTP headers":
+ block add_empty_sequence_to_HTTP_headers:
block:
var headers = newHttpHeaders()
headers["empty"] = @[]
@@ -78,3 +71,28 @@ suite "httpcore":
headers["existing"] = @[]
headers["existing"] = @["true"]
doAssert headers.hasKey("existing")
+
+block:
+ var test = newHttpHeaders()
+ test["Connection"] = @["Upgrade", "Close"]
+ doAssert test["Connection", 0] == "Upgrade"
+ doAssert test["Connection", 1] == "Close"
+ test.add("Connection", "Test")
+ doAssert test["Connection", 2] == "Test"
+ doAssert "upgrade" in test["Connection"]
+
+ # Bug #5344.
+ doAssert parseHeader("foobar: ") == ("foobar", @[""])
+ let (key, value) = parseHeader("foobar: ")
+ test = newHttpHeaders()
+ test[key] = value
+ doAssert test["foobar"] == ""
+
+ doAssert parseHeader("foobar:") == ("foobar", @[""])
+
+ block: # test title case
+ var testTitleCase = newHttpHeaders(titleCase=true)
+ testTitleCase.add("content-length", "1")
+ doAssert testTitleCase.hasKey("Content-Length")
+ for key, val in testTitleCase:
+ doAssert key == "Content-Length"
diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim
index 0de09a858398f..ff1f32d364ffb 100644
--- a/tests/stdlib/tmath.nim
+++ b/tests/stdlib/tmath.nim
@@ -145,3 +145,129 @@ suite "^":
check: compiles(5.5 ^ 2.uint)
check: compiles(5.5 ^ 2.uint8)
check: not compiles(5.5 ^ 2.2)
+
+block:
+ when not defined(js):
+ # Check for no side effect annotation
+ proc mySqrt(num: float): float {.noSideEffect.} =
+ return sqrt(num)
+
+ # check gamma function
+ assert(gamma(5.0) == 24.0) # 4!
+ assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
+ assert(erf(6.0) > erf(5.0))
+ assert(erfc(6.0) < erfc(5.0))
+
+
+ # Function for approximate comparison of floats
+ proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9)
+
+ block: # prod
+ doAssert prod([1, 2, 3, 4]) == 24
+ doAssert prod([1.5, 3.4]) == 5.1
+ let x: seq[float] = @[]
+ doAssert prod(x) == 1.0
+
+ block: # round() tests
+ # Round to 0 decimal places
+ doAssert round(54.652) ==~ 55.0
+ doAssert round(54.352) ==~ 54.0
+ doAssert round(-54.652) ==~ -55.0
+ doAssert round(-54.352) ==~ -54.0
+ doAssert round(0.0) ==~ 0.0
+
+ block: # splitDecimal() tests
+ doAssert splitDecimal(54.674).intpart ==~ 54.0
+ doAssert splitDecimal(54.674).floatpart ==~ 0.674
+ doAssert splitDecimal(-693.4356).intpart ==~ -693.0
+ doAssert splitDecimal(-693.4356).floatpart ==~ -0.4356
+ doAssert splitDecimal(0.0).intpart ==~ 0.0
+ doAssert splitDecimal(0.0).floatpart ==~ 0.0
+
+ block: # trunc tests for vcc
+ doAssert(trunc(-1.1) == -1)
+ doAssert(trunc(1.1) == 1)
+ doAssert(trunc(-0.1) == -0)
+ doAssert(trunc(0.1) == 0)
+
+ #special case
+ doAssert(classify(trunc(1e1000000)) == fcInf)
+ doAssert(classify(trunc(-1e1000000)) == fcNegInf)
+ doAssert(classify(trunc(0.0/0.0)) == fcNan)
+ doAssert(classify(trunc(0.0)) == fcZero)
+
+ #trick the compiler to produce signed zero
+ let
+ f_neg_one = -1.0
+ f_zero = 0.0
+ f_nan = f_zero / f_zero
+
+ doAssert(classify(trunc(f_neg_one*f_zero)) == fcNegZero)
+
+ doAssert(trunc(-1.1'f32) == -1)
+ doAssert(trunc(1.1'f32) == 1)
+ doAssert(trunc(-0.1'f32) == -0)
+ doAssert(trunc(0.1'f32) == 0)
+ doAssert(classify(trunc(1e1000000'f32)) == fcInf)
+ doAssert(classify(trunc(-1e1000000'f32)) == fcNegInf)
+ doAssert(classify(trunc(f_nan.float32)) == fcNan)
+ doAssert(classify(trunc(0.0'f32)) == fcZero)
+
+ block: # sgn() tests
+ assert sgn(1'i8) == 1
+ assert sgn(1'i16) == 1
+ assert sgn(1'i32) == 1
+ assert sgn(1'i64) == 1
+ assert sgn(1'u8) == 1
+ assert sgn(1'u16) == 1
+ assert sgn(1'u32) == 1
+ assert sgn(1'u64) == 1
+ assert sgn(-12342.8844'f32) == -1
+ assert sgn(123.9834'f64) == 1
+ assert sgn(0'i32) == 0
+ assert sgn(0'f32) == 0
+ assert sgn(NegInf) == -1
+ assert sgn(Inf) == 1
+ assert sgn(NaN) == 0
+
+ block: # fac() tests
+ try:
+ discard fac(-1)
+ except AssertionDefect:
+ discard
+
+ doAssert fac(0) == 1
+ doAssert fac(1) == 1
+ doAssert fac(2) == 2
+ doAssert fac(3) == 6
+ doAssert fac(4) == 24
+
+ block: # floorMod/floorDiv
+ doAssert floorDiv(8, 3) == 2
+ doAssert floorMod(8, 3) == 2
+
+ doAssert floorDiv(8, -3) == -3
+ doAssert floorMod(8, -3) == -1
+
+ doAssert floorDiv(-8, 3) == -3
+ doAssert floorMod(-8, 3) == 1
+
+ doAssert floorDiv(-8, -3) == 2
+ doAssert floorMod(-8, -3) == -2
+
+ doAssert floorMod(8.0, -3.0) ==~ -1.0
+ doAssert floorMod(-8.5, 3.0) ==~ 0.5
+
+ block: # log
+ doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0)
+ doAssert log2(8.0'f64) == 3.0'f64
+ doAssert log2(4.0'f64) == 2.0'f64
+ doAssert log2(2.0'f64) == 1.0'f64
+ doAssert log2(1.0'f64) == 0.0'f64
+ doAssert classify(log2(0.0'f64)) == fcNegInf
+
+ doAssert log2(8.0'f32) == 3.0'f32
+ doAssert log2(4.0'f32) == 2.0'f32
+ doAssert log2(2.0'f32) == 1.0'f32
+ doAssert log2(1.0'f32) == 0.0'f32
+ doAssert classify(log2(0.0'f32)) == fcNegInf
diff --git a/tests/stdlib/tmd5.nim b/tests/stdlib/tmd5.nim
new file mode 100644
index 0000000000000..736fa05a76319
--- /dev/null
+++ b/tests/stdlib/tmd5.nim
@@ -0,0 +1,7 @@
+import md5
+
+assert(getMD5("Franz jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
+ "a3cca2b2aa1e3b5b3b5aad99a8529074")
+assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
+ "7e716d0e702df0505fc72e2b89467910")
+assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")
diff --git a/tests/stdlib/tmonotimes.nim b/tests/stdlib/tmonotimes.nim
new file mode 100644
index 0000000000000..cf25ef0258511
--- /dev/null
+++ b/tests/stdlib/tmonotimes.nim
@@ -0,0 +1,16 @@
+import std/monotimes, times
+
+let d = initDuration(nanoseconds = 10)
+let t1 = getMonoTime()
+let t2 = t1 + d
+
+doAssert t2 - t1 == d
+doAssert t1 == t1
+doAssert t1 != t2
+doAssert t2 - d == t1
+doAssert t1 < t2
+doAssert t1 <= t2
+doAssert t1 <= t1
+doAssert not(t2 < t1)
+doAssert t1 < high(MonoTime)
+doAssert low(MonoTime) < t1
diff --git a/tests/stdlib/toptions.nim b/tests/stdlib/toptions.nim
index b982d747d5fd0..04544ffb77c3d 100644
--- a/tests/stdlib/toptions.nim
+++ b/tests/stdlib/toptions.nim
@@ -13,4 +13,146 @@ type
let js = """{"foo": {"test": "123"}}"""
let parsed = parseJson(js)
let a = parsed.to(Test)
-echo $(%*a)
\ No newline at end of file
+echo $(%*a)
+
+
+# RefPerson is used to test that overloaded `==` operator is not called by
+# options. It is defined here in the global scope, because otherwise the test
+# will not even consider the `==` operator. Different bug?
+type RefPerson = ref object
+ name: string
+
+proc `==`(a, b: RefPerson): bool =
+ assert(not a.isNil and not b.isNil)
+ a.name == b.name
+
+block options:
+ # work around a bug in unittest
+ let intNone = none(int)
+ let stringNone = none(string)
+
+ block example:
+ proc find(haystack: string, needle: char): Option[int] =
+ for i, c in haystack:
+ if c == needle:
+ return some i
+
+ doAssert("abc".find('c').get() == 2)
+
+ let result = "team".find('i')
+
+ doAssert result == intNone
+ doAssert result.isNone
+
+ block some:
+ doAssert some(6).get() == 6
+ doAssert some("a").unsafeGet() == "a"
+ doAssert some(6).isSome
+ doAssert some("a").isSome
+
+ block none:
+ doAssertRaises UnpackDefect:
+ discard none(int).get()
+ doAssert(none(int).isNone)
+ doAssert(not none(string).isSome)
+
+ block equality:
+ doAssert some("a") == some("a")
+ doAssert some(7) != some(6)
+ doAssert some("a") != stringNone
+ doAssert intNone == intNone
+
+ when compiles(some("a") == some(5)):
+ doAssert false
+ when compiles(none(string) == none(int)):
+ doAssert false
+
+ block get_with_a_default_value:
+ doAssert(some("Correct").get("Wrong") == "Correct")
+ doAssert(stringNone.get("Correct") == "Correct")
+
+ block stringify:
+ doAssert($(some("Correct")) == "Some(\"Correct\")")
+ doAssert($(stringNone) == "None[string]")
+
+ block map_with_a_void_result:
+ var procRan = 0
+ some(123).map(proc (v: int) = procRan = v)
+ doAssert procRan == 123
+ intNone.map(proc (v: int) = doAssert false)
+
+ block map:
+ doAssert(some(123).map(proc (v: int): int = v * 2) == some(246))
+ doAssert(intNone.map(proc (v: int): int = v * 2).isNone)
+
+ block filter:
+ doAssert(some(123).filter(proc (v: int): bool = v == 123) == some(123))
+ doAssert(some(456).filter(proc (v: int): bool = v == 123).isNone)
+ doAssert(intNone.filter(proc (v: int): bool = doAssert false).isNone)
+
+ block flatMap:
+ proc addOneIfNotZero(v: int): Option[int] =
+ if v != 0:
+ result = some(v + 1)
+ else:
+ result = none(int)
+
+ doAssert(some(1).flatMap(addOneIfNotZero) == some(2))
+ doAssert(some(0).flatMap(addOneIfNotZero) == none(int))
+ doAssert(some(1).flatMap(addOneIfNotZero).flatMap(addOneIfNotZero) == some(3))
+
+ proc maybeToString(v: int): Option[string] =
+ if v != 0:
+ result = some($v)
+ else:
+ result = none(string)
+
+ doAssert(some(1).flatMap(maybeToString) == some("1"))
+
+ proc maybeExclaim(v: string): Option[string] =
+ if v != "":
+ result = some v & "!"
+ else:
+ result = none(string)
+
+ doAssert(some(1).flatMap(maybeToString).flatMap(maybeExclaim) == some("1!"))
+ doAssert(some(0).flatMap(maybeToString).flatMap(maybeExclaim) == none(string))
+
+ block SomePointer:
+ var intref: ref int
+ doAssert(option(intref).isNone)
+ intref.new
+ doAssert(option(intref).isSome)
+
+ let tmp = option(intref)
+ doAssert(sizeof(tmp) == sizeof(ptr int))
+
+ var prc = proc (x: int): int = x + 1
+ doAssert(option(prc).isSome)
+ prc = nil
+ doAssert(option(prc).isNone)
+
+ block:
+ doAssert(none[int]().isNone)
+ doAssert(none(int) == none[int]())
+
+ # "$ on typed with .name"
+ block:
+ type Named = object
+ name: string
+
+ let nobody = none(Named)
+ doAssert($nobody == "None[Named]")
+
+ # "$ on type with name()"
+ block:
+ type Person = object
+ myname: string
+
+ let noperson = none(Person)
+ doAssert($noperson == "None[Person]")
+
+ # "Ref type with overloaded `==`"
+ block:
+ let p = some(RefPerson.new())
+ doAssert p.isSome
diff --git a/tests/stdlib/tparsecsv.nim b/tests/stdlib/tparsecsv.nim
new file mode 100644
index 0000000000000..0d004d45d0bba
--- /dev/null
+++ b/tests/stdlib/tparsecsv.nim
@@ -0,0 +1,31 @@
+include parsecsv
+import strutils, os
+
+block: # Tests for reading the header row
+ let content = "\nOne,Two,Three,Four\n1,2,3,4\n10,20,30,40,\n100,200,300,400\n"
+ writeFile("temp.csv", content)
+
+ var p: CsvParser
+ p.open("temp.csv")
+ p.readHeaderRow()
+ while p.readRow():
+ let zeros = repeat('0', p.currRow-2)
+ doAssert p.rowEntry("One") == "1" & zeros
+ doAssert p.rowEntry("Two") == "2" & zeros
+ doAssert p.rowEntry("Three") == "3" & zeros
+ doAssert p.rowEntry("Four") == "4" & zeros
+ p.close()
+
+ when not defined(testing):
+ var parser: CsvParser
+ parser.open("temp.csv")
+ parser.readHeaderRow()
+ while parser.readRow():
+ echo "new row: "
+ for col in items(parser.headers):
+ echo "##", col, ":", parser.rowEntry(col), "##"
+ parser.close()
+ removeFile("temp.csv")
+
+ # Tidy up
+ removeFile("temp.csv")
diff --git a/tests/stdlib/tparseutils.nim b/tests/stdlib/tparseutils.nim
new file mode 100644
index 0000000000000..3bc54dff193a7
--- /dev/null
+++ b/tests/stdlib/tparseutils.nim
@@ -0,0 +1,43 @@
+import parseutils
+import sequtils
+
+let input = "$test{} $this is ${an{ example}} "
+let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"),
+ (ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")]
+doAssert toSeq(interpolatedFragments(input)) == expected
+
+var value = 0
+discard parseHex("0x38", value)
+doAssert value == 56
+
+value = -1
+doAssert(parseSaturatedNatural("848", value) == 3)
+doAssert value == 848
+
+value = -1
+discard parseSaturatedNatural("84899999999999999999324234243143142342135435342532453", value)
+doAssert value == high(int)
+
+value = -1
+discard parseSaturatedNatural("9223372036854775808", value)
+doAssert value == high(int)
+
+value = -1
+discard parseSaturatedNatural("9223372036854775807", value)
+doAssert value == high(int)
+
+value = -1
+discard parseSaturatedNatural("18446744073709551616", value)
+doAssert value == high(int)
+
+value = -1
+discard parseSaturatedNatural("18446744073709551615", value)
+doAssert value == high(int)
+
+value = -1
+doAssert(parseSaturatedNatural("1_000_000", value) == 9)
+doAssert value == 1_000_000
+
+var i64Value: int64
+discard parseBiggestInt("9223372036854775807", i64Value)
+doAssert i64Value == 9223372036854775807
diff --git a/tests/stdlib/tpunycode.nim b/tests/stdlib/tpunycode.nim
new file mode 100644
index 0000000000000..998bd3bdfabfb
--- /dev/null
+++ b/tests/stdlib/tpunycode.nim
@@ -0,0 +1,5 @@
+import punycode
+
+assert(decode(encode("", "bücher")) == "bücher")
+assert(decode(encode("münchen")) == "münchen")
+assert encode("xn--", "münchen") == "xn--mnchen-3ya"
diff --git a/tests/stdlib/trandom.nim b/tests/stdlib/trandom.nim
new file mode 100644
index 0000000000000..c7c6a3f569379
--- /dev/null
+++ b/tests/stdlib/trandom.nim
@@ -0,0 +1,59 @@
+discard """
+ action: compile
+"""
+
+import random
+
+proc main =
+ var occur: array[1000, int]
+
+ var x = 8234
+ for i in 0..100_000:
+ x = rand(high(occur))
+ inc occur[x]
+ for i, oc in occur:
+ if oc < 69:
+ doAssert false, "too few occurrences of " & $i
+ elif oc > 150:
+ doAssert false, "too many occurrences of " & $i
+
+ when false:
+ var rs: RunningStat
+ for j in 1..5:
+ for i in 1 .. 1_000:
+ rs.push(gauss())
+ echo("mean: ", rs.mean,
+ " stdDev: ", rs.standardDeviation(),
+ " min: ", rs.min,
+ " max: ", rs.max)
+ rs.clear()
+
+ var a = [0, 1]
+ shuffle(a)
+ doAssert a[0] == 1
+ doAssert a[1] == 0
+
+ doAssert rand(0) == 0
+ doAssert sample("a") == 'a'
+
+ when compileOption("rangeChecks"):
+ try:
+ discard rand(-1)
+ doAssert false
+ except RangeDefect:
+ discard
+
+ try:
+ discard rand(-1.0)
+ doAssert false
+ except RangeDefect:
+ discard
+
+
+ # don't use causes integer overflow
+ doAssert compiles(rand[int](low(int) .. high(int)))
+
+randomize(223)
+
+for i in 0 .. 10:
+ main()
diff --git a/tests/stdlib/trationals.nim b/tests/stdlib/trationals.nim
new file mode 100644
index 0000000000000..17238af074769
--- /dev/null
+++ b/tests/stdlib/trationals.nim
@@ -0,0 +1,98 @@
+import rationals, math
+
+
+var
+ z = Rational[int](num: 0, den: 1)
+ o = initRational(num = 1, den = 1)
+ a = initRational(1, 2)
+ b = -1 // -2
+ m1 = -1 // 1
+ tt = 10 // 2
+
+assert(a == a)
+assert( (a-a) == z)
+assert( (a+b) == o)
+assert( (a/b) == o)
+assert( (a*b) == 1 // 4)
+assert( (3/a) == 6 // 1)
+assert( (a/3) == 1 // 6)
+assert(a*b == 1 // 4)
+assert(tt*z == z)
+assert(10*a == tt)
+assert(a*10 == tt)
+assert(tt/10 == a)
+assert(a-m1 == 3 // 2)
+assert(a+m1 == -1 // 2)
+assert(m1+tt == 16 // 4)
+assert(m1-tt == 6 // -1)
+
+assert(z < o)
+assert(z <= o)
+assert(z == z)
+assert(cmp(z, o) < 0)
+assert(cmp(o, z) > 0)
+
+assert(o == o)
+assert(o >= o)
+assert(not(o > o))
+assert(cmp(o, o) == 0)
+assert(cmp(z, z) == 0)
+assert(hash(o) == hash(o))
+
+assert(a == b)
+assert(a >= b)
+assert(not(b > a))
+assert(cmp(a, b) == 0)
+assert(hash(a) == hash(b))
+
+var x = 1//3
+
+x *= 5//1
+assert(x == 5//3)
+x += 2 // 9
+assert(x == 17//9)
+x -= 9//18
+assert(x == 25//18)
+x /= 1//2
+assert(x == 50//18)
+
+var y = 1//3
+
+y *= 4
+assert(y == 4//3)
+y += 5
+assert(y == 19//3)
+y -= 2
+assert(y == 13//3)
+y /= 9
+assert(y == 13//27)
+
+assert toRational(5) == 5//1
+assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
+assert toInt(z) == 0
+
+when sizeof(int) == 8:
+ assert toRational(0.98765432) == 2111111029 // 2137499919
+ assert toRational(PI) == 817696623 // 260280919
+when sizeof(int) == 4:
+ assert toRational(0.98765432) == 80 // 81
+ assert toRational(PI) == 355 // 113
+
+assert toRational(0.1) == 1 // 10
+assert toRational(0.9) == 9 // 10
+
+assert toRational(0.0) == 0 // 1
+assert toRational(-0.25) == 1 // -4
+assert toRational(3.2) == 16 // 5
+assert toRational(0.33) == 33 // 100
+assert toRational(0.22) == 11 // 50
+assert toRational(10.0) == 10 // 1
+
+assert (1//1) div (3//10) == 3
+assert (-1//1) div (3//10) == -3
+assert (3//10) mod (1//1) == 3//10
+assert (-3//10) mod (1//1) == -3//10
+assert floorDiv(1//1, 3//10) == 3
+assert floorDiv(-1//1, 3//10) == -4
+assert floorMod(3//10, 1//1) == 3//10
+assert floorMod(-3//10, 1//1) == 7//10
diff --git a/tests/stdlib/tsha1.nim b/tests/stdlib/tsha1.nim
new file mode 100644
index 0000000000000..7e67ccaf61d2a
--- /dev/null
+++ b/tests/stdlib/tsha1.nim
@@ -0,0 +1,13 @@
+import std/sha1
+
+let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
+doAssert hash1 == hash1
+doAssert parseSecureHash($hash1) == hash1
+
+template checkVector(s, exp: string) =
+ doAssert secureHash(s) == parseSecureHash(exp)
+
+checkVector("", "da39a3ee5e6b4b0d3255bfef95601890afd80709")
+checkVector("abc", "a9993e364706816aba3e25717850c26c9cd0d89d")
+checkVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
diff --git a/tests/stdlib/tstats.nim b/tests/stdlib/tstats.nim
new file mode 100644
index 0000000000000..37240c8848ff0
--- /dev/null
+++ b/tests/stdlib/tstats.nim
@@ -0,0 +1,46 @@
+include stats
+
+proc clean(x: float): float =
+ result = round(1.0e8*x).float * 1.0e-8
+
+var rs: RunningStat
+rs.push(@[1.0, 2.0, 1.0, 4.0, 1.0, 4.0, 1.0, 2.0])
+doAssert(rs.n == 8)
+doAssert(clean(rs.mean) == 2.0)
+doAssert(clean(rs.variance()) == 1.5)
+doAssert(clean(rs.varianceS()) == 1.71428571)
+doAssert(clean(rs.skewness()) == 0.81649658)
+doAssert(clean(rs.skewnessS()) == 1.01835015)
+doAssert(clean(rs.kurtosis()) == -1.0)
+doAssert(clean(rs.kurtosisS()) == -0.7000000000000001)
+
+var rs1, rs2: RunningStat
+rs1.push(@[1.0, 2.0, 1.0, 4.0])
+rs2.push(@[1.0, 4.0, 1.0, 2.0])
+let rs3 = rs1 + rs2
+doAssert(clean(rs3.mom2) == clean(rs.mom2))
+doAssert(clean(rs3.mom3) == clean(rs.mom3))
+doAssert(clean(rs3.mom4) == clean(rs.mom4))
+rs1 += rs2
+doAssert(clean(rs1.mom2) == clean(rs.mom2))
+doAssert(clean(rs1.mom3) == clean(rs.mom3))
+doAssert(clean(rs1.mom4) == clean(rs.mom4))
+rs1.clear()
+rs1.push(@[1.0, 2.2, 1.4, 4.9])
+doAssert(rs1.sum == 9.5)
+doAssert(rs1.mean() == 2.375)
+
+when not defined(cpu32):
+ # XXX For some reason on 32bit CPUs these results differ
+ var rr: RunningRegress
+ rr.push(@[0.0, 1.0, 2.8, 3.0, 4.0], @[0.0, 1.0, 2.3, 3.0, 4.0])
+ doAssert(rr.slope() == 0.9695585996955861)
+ doAssert(rr.intercept() == -0.03424657534246611)
+ doAssert(rr.correlation() == 0.9905100362239381)
+ var rr1, rr2: RunningRegress
+ rr1.push(@[0.0, 1.0], @[0.0, 1.0])
+ rr2.push(@[2.8, 3.0, 4.0], @[2.3, 3.0, 4.0])
+ let rr3 = rr1 + rr2
+ doAssert(rr3.correlation() == rr.correlation())
+ doAssert(clean(rr3.slope()) == clean(rr.slope()))
+ doAssert(clean(rr3.intercept()) == clean(rr.intercept()))
\ No newline at end of file
diff --git a/tests/stdlib/tstreams.nim b/tests/stdlib/tstreams.nim
index 0fe6b69335fa1..e0310b5f524d9 100644
--- a/tests/stdlib/tstreams.nim
+++ b/tests/stdlib/tstreams.nim
@@ -61,3 +61,17 @@ doAssert a.readDataStr(buffer, 1..3) == 3
echo buffer
+
+block:
+ var ss = newStringStream("The quick brown fox jumped over the lazy dog.\nThe lazy dog ran")
+ assert(ss.getPosition == 0)
+ assert(ss.peekStr(5) == "The q")
+ assert(ss.getPosition == 0) # haven't moved
+ assert(ss.readStr(5) == "The q")
+ assert(ss.getPosition == 5) # did move
+ assert(ss.peekLine() == "uick brown fox jumped over the lazy dog.")
+ assert(ss.getPosition == 5) # haven't moved
+ var str = newString(100)
+ assert(ss.peekLine(str))
+ assert(str == "uick brown fox jumped over the lazy dog.")
+ assert(ss.getPosition == 5) # haven't moved
diff --git a/tests/stdlib/tstrformat.nim b/tests/stdlib/tstrformat.nim
index b1f3340a4e1f6..d483093a76535 100644
--- a/tests/stdlib/tstrformat.nim
+++ b/tests/stdlib/tstrformat.nim
@@ -6,7 +6,7 @@ output: '''Received (name: "Foo", species: "Bar")'''
# issue #7632
import genericstrformat
-import strutils
+import strutils, times
doAssert works(5) == "formatted 5"
@@ -376,3 +376,140 @@ block:
doAssert fmt"{x.foo(y) =}" == "x.foo(y) =18"
doAssert fmt"{x.foo(y)= }" == "x.foo(y)= 18"
doAssert fmt"{x.foo(y) = }" == "x.foo(y) = 18"
+
+block:
+ template check(actual, expected: string) =
+ doAssert actual == expected
+
+ # Basic tests
+ let s = "string"
+ check &"{0} {s}", "0 string"
+ check &"{s[0..2].toUpperAscii}", "STR"
+ check &"{-10:04}", "-010"
+ check &"{-10:<04}", "-010"
+ check &"{-10:>04}", "-010"
+ check &"0x{10:02X}", "0x0A"
+
+ check &"{10:#04X}", "0x0A"
+
+ check &"""{"test":#>5}""", "#test"
+ check &"""{"test":>5}""", " test"
+
+ check &"""{"test":#^7}""", "#test##"
+
+ check &"""{"test": <5}""", "test "
+ check &"""{"test":<5}""", "test "
+ check &"{1f:.3f}", "1.000"
+ check &"Hello, {s}!", "Hello, string!"
+
+ # Tests for identifiers without parenthesis
+ check &"{s} works{s}", "string worksstring"
+ check &"{s:>7}", " string"
+ doAssert(not compiles(&"{s_works}")) # parsed as identifier `s_works`
+
+ # Misc general tests
+ check &"{{}}", "{}"
+ check &"{0}%", "0%"
+ check &"{0}%asdf", "0%asdf"
+ check &("\n{\"\\n\"}\n"), "\n\n\n"
+ check &"""{"abc"}s""", "abcs"
+
+ # String tests
+ check &"""{"abc"}""", "abc"
+ check &"""{"abc":>4}""", " abc"
+ check &"""{"abc":<4}""", "abc "
+ check &"""{"":>4}""", " "
+ check &"""{"":<4}""", " "
+
+ # Int tests
+ check &"{12345}", "12345"
+ check &"{ - 12345}", "-12345"
+ check &"{12345:6}", " 12345"
+ check &"{12345:>6}", " 12345"
+ check &"{12345:4}", "12345"
+ check &"{12345:08}", "00012345"
+ check &"{-12345:08}", "-0012345"
+ check &"{0:0}", "0"
+ check &"{0:02}", "00"
+ check &"{-1:3}", " -1"
+ check &"{-1:03}", "-01"
+ check &"{10}", "10"
+ check &"{16:#X}", "0x10"
+ check &"{16:^#7X}", " 0x10 "
+ check &"{16:^+#7X}", " +0x10 "
+
+ # Hex tests
+ check &"{0:x}", "0"
+ check &"{-0:x}", "0"
+ check &"{255:x}", "ff"
+ check &"{255:X}", "FF"
+ check &"{-255:x}", "-ff"
+ check &"{-255:X}", "-FF"
+ check &"{255:x} uNaffeCteD CaSe", "ff uNaffeCteD CaSe"
+ check &"{255:X} uNaffeCteD CaSe", "FF uNaffeCteD CaSe"
+ check &"{255:4x}", " ff"
+ check &"{255:04x}", "00ff"
+ check &"{-255:4x}", " -ff"
+ check &"{-255:04x}", "-0ff"
+
+ # Float tests
+ check &"{123.456}", "123.456"
+ check &"{-123.456}", "-123.456"
+ check &"{123.456:.3f}", "123.456"
+ check &"{123.456:+.3f}", "+123.456"
+ check &"{-123.456:+.3f}", "-123.456"
+ check &"{-123.456:.3f}", "-123.456"
+ check &"{123.456:1g}", "123.456"
+ check &"{123.456:.1f}", "123.5"
+ check &"{123.456:.0f}", "123."
+ check &"{123.456:>9.3f}", " 123.456"
+ check &"{123.456:9.3f}", " 123.456"
+ check &"{123.456:>9.4f}", " 123.4560"
+ check &"{123.456:>9.0f}", " 123."
+ check &"{123.456:<9.4f}", "123.4560 "
+
+ # Float (scientific) tests
+ check &"{123.456:e}", "1.234560e+02"
+ check &"{123.456:>13e}", " 1.234560e+02"
+ check &"{123.456:<13e}", "1.234560e+02 "
+ check &"{123.456:.1e}", "1.2e+02"
+ check &"{123.456:.2e}", "1.23e+02"
+ check &"{123.456:.3e}", "1.235e+02"
+
+ # Note: times.format adheres to the format protocol. Test that this
+ # works:
+
+ var dt = initDateTime(01, mJan, 2000, 00, 00, 00)
+ check &"{dt:yyyy-MM-dd}", "2000-01-01"
+
+ var tm = fromUnix(0)
+ discard &"{tm}"
+
+ var noww = now()
+ check &"{noww}", $noww
+
+ # Unicode string tests
+ check &"""{"αβγ"}""", "αβγ"
+ check &"""{"αβγ":>5}""", " αβγ"
+ check &"""{"αβγ":<5}""", "αβγ "
+ check &"""a{"a"}α{"α"}€{"€"}𐍈{"𐍈"}""", "aaαα€€𐍈𐍈"
+ check &"""a{"a":2}α{"α":2}€{"€":2}𐍈{"𐍈":2}""", "aa αα €€ 𐍈𐍈 "
+ # Invalid unicode sequences should be handled as plain strings.
+ # Invalid examples taken from: https://stackoverflow.com/a/3886015/1804173
+ let invalidUtf8 = [
+ "\xc3\x28", "\xa0\xa1",
+ "\xe2\x28\xa1", "\xe2\x82\x28",
+ "\xf0\x28\x8c\xbc", "\xf0\x90\x28\xbc", "\xf0\x28\x8c\x28"
+ ]
+ for s in invalidUtf8:
+ check &"{s:>5}", repeat(" ", 5-s.len) & s
+
+ # bug #11089
+ let flfoo: float = 1.0
+ check &"{flfoo}", "1.0"
+
+ # bug #11092
+ check &"{high(int64)}", "9223372036854775807"
+ check &"{low(int64)}", "-9223372036854775808"
+
+ doAssert fmt"{'a'} {'b'}" == "a b"
\ No newline at end of file
diff --git a/tests/stdlib/tstrmiscs.nim b/tests/stdlib/tstrmiscs.nim
new file mode 100644
index 0000000000000..2e9131ff807c8
--- /dev/null
+++ b/tests/stdlib/tstrmiscs.nim
@@ -0,0 +1,22 @@
+import strmisc
+
+
+doAssert expandTabs("\t", 4) == " "
+doAssert expandTabs("\tfoo\t", 4) == " foo "
+doAssert expandTabs("\tfoo\tbar", 4) == " foo bar"
+doAssert expandTabs("\tfoo\tbar\t", 4) == " foo bar "
+doAssert expandTabs("", 4) == ""
+doAssert expandTabs("", 0) == ""
+doAssert expandTabs("\t\t\t", 0) == ""
+
+doAssert partition("foo:bar", ":") == ("foo", ":", "bar")
+doAssert partition("foobarbar", "bar") == ("foo", "bar", "bar")
+doAssert partition("foobarbar", "bank") == ("foobarbar", "", "")
+doAssert partition("foobarbar", "foo") == ("", "foo", "barbar")
+doAssert partition("foofoobar", "bar") == ("foofoo", "bar", "")
+
+doAssert rpartition("foo:bar", ":") == ("foo", ":", "bar")
+doAssert rpartition("foobarbar", "bar") == ("foobar", "bar", "")
+doAssert rpartition("foobarbar", "bank") == ("", "", "foobarbar")
+doAssert rpartition("foobarbar", "foo") == ("", "foo", "barbar")
+doAssert rpartition("foofoobar", "bar") == ("foofoo", "bar", "")
diff --git a/tests/stdlib/tstrscans.nim b/tests/stdlib/tstrscans.nim
index 6f952368c9a58..9d6f51025d6ec 100644
--- a/tests/stdlib/tstrscans.nim
+++ b/tests/stdlib/tstrscans.nim
@@ -98,3 +98,115 @@ block issue15064:
doAssert scanf(" ", "<$+> $*", nick3, msg3)
doAssert nick3 == "abcd"
doAssert msg3 == ""
+
+
+block:
+ proc twoDigits(input: string; x: var int; start: int): int =
+ if start+1 < input.len and input[start] == '0' and input[start+1] == '0':
+ result = 2
+ x = 13
+ else:
+ result = 0
+
+ proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int =
+ result = 0
+ while start+result < input.len and input[start+result] in seps: inc result
+
+ proc demangle(s: string; res: var string; start: int): int =
+ while result+start < s.len and s[result+start] in {'_', '@'}: inc result
+ res = ""
+ while result+start < s.len and s[result+start] > ' ' and s[result+start] != '_':
+ res.add s[result+start]
+ inc result
+ while result+start < s.len and s[result+start] > ' ':
+ inc result
+
+ proc parseGDB(resp: string): seq[string] =
+ const
+ digits = {'0'..'9'}
+ hexdigits = digits + {'a'..'f', 'A'..'F'}
+ whites = {' ', '\t', '\C', '\L'}
+ result = @[]
+ var idx = 0
+ while true:
+ var prc = ""
+ var info = ""
+ if scanp(resp, idx, *`whites`, '#', *`digits`, +`whites`, ?("0x", *`hexdigits`, " in "),
+ demangle($input, prc, $index), *`whites`, '(', * ~ ')', ')',
+ *`whites`, "at ", +(~{'\C', '\L'} -> info.add($_))):
+ result.add prc & " " & info
+ else:
+ break
+
+ var key, val: string
+ var intval: int
+ var floatval: float
+ doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intval, floatVal)
+ doAssert key == "abc"
+ doAssert val == "xyz"
+ doAssert intval == 89
+ doAssert floatVal == 33.25
+
+ var binval: int
+ var octval: int
+ var hexval: int
+ doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
+ doAssert binval == 0b0101
+ doAssert octval == 0o1234
+ doAssert hexval == 0xabcd
+
+ let xx = scanf("$abc", "$$$i", intval)
+ doAssert xx == false
+
+
+ let xx2 = scanf("$1234", "$$$i", intval)
+ doAssert xx2
+
+ let yy = scanf(";.--Breakpoint00 [output]",
+ "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
+ intVal, key)
+ doAssert yy
+ doAssert key == "output"
+ doAssert intVal == 13
+
+ var ident = ""
+ var idx = 0
+ let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{
+ ' ', '\t'}, "x"), ~'U', "Z")
+ doAssert zz
+ doAssert ident == "foobar"
+
+ const digits = {'0'..'9'}
+ var year = 0
+ var idx2 = 0
+ if scanp("201655-8-9", idx2, `digits`{4, 6} -> (year = year * 10 + ord($_) -
+ ord('0')), "-8", "-9"):
+ doAssert year == 201655
+
+ const gdbOut = """
+ #0 @foo_96013_1208911747@8 (x0=...)
+ at c:/users/anwender/projects/nim/temp.nim:11
+ #1 0x00417754 in tempInit000 () at c:/users/anwender/projects/nim/temp.nim:13
+ #2 0x0041768d in NimMainInner ()
+ at c:/users/anwender/projects/nim/lib/system.nim:2605
+ #3 0x004176b1 in NimMain ()
+ at c:/users/anwender/projects/nim/lib/system.nim:2613
+ #4 0x004176db in main (argc=1, args=0x712cc8, env=0x711ca8)
+ at c:/users/anwender/projects/nim/lib/system.nim:2620"""
+ const result = @["foo c:/users/anwender/projects/nim/temp.nim:11",
+ "tempInit000 c:/users/anwender/projects/nim/temp.nim:13",
+ "NimMainInner c:/users/anwender/projects/nim/lib/system.nim:2605",
+ "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613",
+ "main c:/users/anwender/projects/nim/lib/system.nim:2620"]
+ doAssert parseGDB(gdbOut) == result
+
+ # bug #6487
+ var count = 0
+
+ proc test(): string =
+ inc count
+ result = ",123123"
+
+ var a: int
+ discard scanf(test(), ",$i", a)
+ doAssert count == 1
diff --git a/tests/stdlib/tstrtabs.nim b/tests/stdlib/tstrtabs.nim
index 5d7e8c762cf95..d4344f95fc886 100644
--- a/tests/stdlib/tstrtabs.nim
+++ b/tests/stdlib/tstrtabs.nim
@@ -102,3 +102,15 @@ writeLine(stdout, "length of table ", $tab.len)
writeLine(stdout, `%`("$key1 = $key2", tab, {useEnvironment}))
tab.clear
writeLine(stdout, "length of table ", $tab.len)
+
+block:
+ var x = {"k": "v", "11": "22", "565": "67"}.newStringTable
+ assert x["k"] == "v"
+ assert x["11"] == "22"
+ assert x["565"] == "67"
+ x["11"] = "23"
+ assert x["11"] == "23"
+
+ x.clear(modeCaseInsensitive)
+ x["11"] = "22"
+ assert x["11"] == "22"
diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim
index 162b8ea1b0271..149d9bb87d36e 100644
--- a/tests/stdlib/tstrutil.nim
+++ b/tests/stdlib/tstrutil.nim
@@ -457,3 +457,220 @@ hey
assert 0 == indentation ""
assert 0 == indentation " \n \n"
assert 0 == indentation " "
+
+
+block:
+ proc nonStaticTests =
+ doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
+ when not defined(js):
+ doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235." # bugs 8242, 12586
+ doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"
+ doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
+ doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in
+ ["1,0e-11", "1,0e-011"]
+ # bug #6589
+ when not defined(js):
+ doAssert formatFloat(123.456, ffScientific, precision = -1) == "1.234560e+02"
+
+ doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
+ doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb"
+
+ block: # formatSize tests
+ when not defined(js):
+ 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"
+ doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB"
+ doAssert formatSize(4096, includeSpace = true) == "4 KiB"
+ doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB"
+
+ block: # formatEng tests
+ doAssert formatEng(0, 2, trim = false) == "0.00"
+ doAssert formatEng(0, 2) == "0"
+ doAssert formatEng(53, 2, trim = false) == "53.00"
+ doAssert formatEng(0.053, 2, trim = false) == "53.00e-3"
+ doAssert formatEng(0.053, 4, trim = false) == "53.0000e-3"
+ doAssert formatEng(0.053, 4, trim = true) == "53e-3"
+ doAssert formatEng(0.053, 0) == "53e-3"
+ doAssert formatEng(52731234) == "52.731234e6"
+ doAssert formatEng(-52731234) == "-52.731234e6"
+ doAssert formatEng(52731234, 1) == "52.7e6"
+ doAssert formatEng(-52731234, 1) == "-52.7e6"
+ doAssert formatEng(52731234, 1, decimalSep = ',') == "52,7e6"
+ doAssert formatEng(-52731234, 1, decimalSep = ',') == "-52,7e6"
+
+ doAssert formatEng(4100, siPrefix = true, unit = "V") == "4.1 kV"
+ doAssert formatEng(4.1, siPrefix = true, unit = "V",
+ useUnitSpace = true) == "4.1 V"
+ doAssert formatEng(4.1, siPrefix = true) == "4.1" # Note lack of space
+ doAssert formatEng(4100, siPrefix = true) == "4.1 k"
+ doAssert formatEng(4.1, siPrefix = true, unit = "",
+ useUnitSpace = true) == "4.1 " # Includes space
+ doAssert formatEng(4100, siPrefix = true, unit = "") == "4.1 k"
+ doAssert formatEng(4100) == "4.1e3"
+ doAssert formatEng(4100, unit = "V", useUnitSpace = true) == "4.1e3 V"
+ doAssert formatEng(4100, unit = "", useUnitSpace = true) == "4.1e3 "
+ # Don't use SI prefix as number is too big
+ doAssert formatEng(3.1e22, siPrefix = true, unit = "a",
+ useUnitSpace = true) == "31e21 a"
+ # Don't use SI prefix as number is too small
+ doAssert formatEng(3.1e-25, siPrefix = true, unit = "A",
+ useUnitSpace = true) == "310e-27 A"
+
+ proc staticTests =
+ doAssert align("abc", 4) == " abc"
+ doAssert align("a", 0) == "a"
+ doAssert align("1232", 6) == " 1232"
+ doAssert align("1232", 6, '#') == "##1232"
+
+ doAssert alignLeft("abc", 4) == "abc "
+ doAssert alignLeft("a", 0) == "a"
+ doAssert alignLeft("1232", 6) == "1232 "
+ doAssert alignLeft("1232", 6, '#') == "1232##"
+
+ doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] ==
+ "The cat eats fish."
+
+ doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
+ doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
+
+ doAssert "-lda-ldz -ld abc".replaceWord("") == "-lda-ldz -ld abc"
+ doAssert "oo".replace("", "abc") == "oo"
+
+ type MyEnum = enum enA, enB, enC, enuD, enE
+ doAssert parseEnum[MyEnum]("enu_D") == enuD
+
+ doAssert parseEnum("invalid enum value", enC) == enC
+
+ doAssert center("foo", 13) == " foo "
+ doAssert center("foo", 0) == "foo"
+ doAssert center("foo", 3, fillChar = 'a') == "foo"
+ doAssert center("foo", 10, fillChar = '\t') == "\t\t\tfoo\t\t\t\t"
+
+ doAssert count("foofoofoo", "foofoo") == 1
+ doAssert count("foofoofoo", "foofoo", overlapping = true) == 2
+ doAssert count("foofoofoo", 'f') == 3
+ doAssert count("foofoofoobar", {'f', 'b'}) == 4
+
+ doAssert strip(" foofoofoo ") == "foofoofoo"
+ doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
+ doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
+ doAssert strip("stripme but don't strip this stripme",
+ chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
+ " but don't strip this "
+ doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
+ doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
+
+ doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar"
+
+ doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab"
+ doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.",
+ "PEOPLE!")) == "HELLO PEOPLE!"
+ doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa"
+
+ doAssert isAlphaAscii('r')
+ doAssert isAlphaAscii('A')
+ doAssert(not isAlphaAscii('$'))
+
+ doAssert isAlphaNumeric('3')
+ doAssert isAlphaNumeric('R')
+ doAssert(not isAlphaNumeric('!'))
+
+ doAssert isDigit('3')
+ doAssert(not isDigit('a'))
+ doAssert(not isDigit('%'))
+
+ doAssert isSpaceAscii('\t')
+ doAssert isSpaceAscii('\l')
+ doAssert(not isSpaceAscii('A'))
+
+ doAssert(isEmptyOrWhitespace(""))
+ doAssert(isEmptyOrWhitespace(" "))
+ doAssert(isEmptyOrWhitespace("\t\l \v\r\f"))
+ doAssert(not isEmptyOrWhitespace("ABc \td"))
+
+ doAssert isLowerAscii('a')
+ doAssert isLowerAscii('z')
+ doAssert(not isLowerAscii('A'))
+ doAssert(not isLowerAscii('5'))
+ doAssert(not isLowerAscii('&'))
+ doAssert(not isLowerAscii(' '))
+
+ doAssert isUpperAscii('A')
+ doAssert(not isUpperAscii('b'))
+ doAssert(not isUpperAscii('5'))
+ doAssert(not isUpperAscii('%'))
+
+ 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", 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"]
+
+ doAssert(unescape(r"\x013", "", "") == "\x013")
+
+ doAssert join(["foo", "bar", "baz"]) == "foobarbaz"
+ doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz"
+ doAssert join([1, 2, 3]) == "123"
+ doAssert join(@[1, 2, 3], ", ") == "1, 2, 3"
+
+ doAssert """~~!!foo
+~~!!bar
+~~!!baz""".unindent(2, "~~!!") == "foo\nbar\nbaz"
+
+ doAssert """~~!!foo
+~~!!bar
+~~!!baz""".unindent(2, "~~!!aa") == "~~!!foo\n~~!!bar\n~~!!baz"
+ doAssert """~~foo
+~~ bar
+~~ baz""".unindent(4, "~") == "foo\n bar\n baz"
+ doAssert """foo
+bar
+ baz
+ """.unindent(4) == "foo\nbar\nbaz\n"
+ doAssert """foo
+ bar
+ baz
+ """.unindent(2) == "foo\n bar\n baz\n"
+ doAssert """foo
+ bar
+ baz
+ """.unindent(100) == "foo\nbar\nbaz\n"
+
+ doAssert """foo
+ foo
+ bar
+ """.unindent() == "foo\nfoo\nbar\n"
+
+ let s = " this is an example "
+ let s2 = ":this;is;an:example;;"
+
+ doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
+ doAssert s2.split(seps = {':', ';'}) == @["", "this", "is", "an", "example",
+ "", ""]
+ 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 "]
+
+ doAssert s.splitWhitespace() == @["this", "is", "an", "example"]
+ doAssert s.splitWhitespace(maxsplit = 1) == @["this", "is an example "]
+ doAssert s.splitWhitespace(maxsplit = 2) == @["this", "is", "an example "]
+ doAssert s.splitWhitespace(maxsplit = 3) == @["this", "is", "an", "example "]
+ doAssert s.splitWhitespace(maxsplit = 4) == @["this", "is", "an", "example"]
+
+ block: # startsWith / endsWith char tests
+ var s = "abcdef"
+ doAssert s.startsWith('a')
+ doAssert s.startsWith('b') == false
+ doAssert s.endsWith('f')
+ doAssert s.endsWith('a') == false
+ doAssert s.endsWith('\0') == false
+
+ #echo("strutils tests passed")
+
+ nonStaticTests()
+ staticTests()
+ static: staticTests()
\ No newline at end of file
diff --git a/tests/stdlib/ttables.nim b/tests/stdlib/ttables.nim
new file mode 100644
index 0000000000000..656d7be6bc40d
--- /dev/null
+++ b/tests/stdlib/ttables.nim
@@ -0,0 +1,311 @@
+import tables, hashes
+
+type
+ Person = object
+ firstName, lastName: string
+
+proc hash(x: Person): Hash =
+ ## Piggyback on the already available string hash proc.
+ ##
+ ## Without this proc nothing works!
+ result = x.firstName.hash !& x.lastName.hash
+ result = !$result
+
+var
+ salaries = initTable[Person, int]()
+ p1, p2: Person
+p1.firstName = "Jon"
+p1.lastName = "Ross"
+salaries[p1] = 30_000
+p2.firstName = "소진"
+p2.lastName = "박"
+salaries[p2] = 45_000
+var
+ s2 = initOrderedTable[Person, int]()
+ s3 = initCountTable[Person]()
+s2[p1] = 30_000
+s2[p2] = 45_000
+s3[p1] = 30_000
+s3[p2] = 45_000
+
+block: # Ordered table should preserve order after deletion
+ var
+ s4 = initOrderedTable[int, int]()
+ s4[1] = 1
+ s4[2] = 2
+ s4[3] = 3
+
+ var prev = 0
+ for i in s4.values:
+ doAssert(prev < i)
+ prev = i
+
+ s4.del(2)
+ doAssert(2 notin s4)
+ doAssert(s4.len == 2)
+ prev = 0
+ for i in s4.values:
+ doAssert(prev < i)
+ prev = i
+
+block: # Deletion from OrderedTable should account for collision groups. See issue #5057.
+ # The bug is reproducible only with exact keys
+ const key1 = "boy_jackpot.inGamma"
+ const key2 = "boy_jackpot.outBlack"
+
+ var t = {
+ key1: 0,
+ key2: 0
+ }.toOrderedTable()
+
+ t.del(key1)
+ assert(t.len == 1)
+ assert(key2 in t)
+
+var
+ t1 = initCountTable[string]()
+ t2 = initCountTable[string]()
+t1.inc("foo")
+t1.inc("bar", 2)
+t1.inc("baz", 3)
+t2.inc("foo", 4)
+t2.inc("bar")
+t2.inc("baz", 11)
+merge(t1, t2)
+assert(t1["foo"] == 5)
+assert(t1["bar"] == 3)
+assert(t1["baz"] == 14)
+
+let
+ t1r = newCountTable[string]()
+ t2r = newCountTable[string]()
+t1r.inc("foo")
+t1r.inc("bar", 2)
+t1r.inc("baz", 3)
+t2r.inc("foo", 4)
+t2r.inc("bar")
+t2r.inc("baz", 11)
+merge(t1r, t2r)
+assert(t1r["foo"] == 5)
+assert(t1r["bar"] == 3)
+assert(t1r["baz"] == 14)
+
+var
+ t1l = initCountTable[string]()
+ t2l = initCountTable[string]()
+t1l.inc("foo")
+t1l.inc("bar", 2)
+t1l.inc("baz", 3)
+t2l.inc("foo", 4)
+t2l.inc("bar")
+t2l.inc("baz", 11)
+
+block:
+ const testKey = "TESTKEY"
+ let t: CountTableRef[string] = newCountTable[string]()
+
+ # Before, does not compile with error message:
+ #test_counttable.nim(7, 43) template/generic instantiation from here
+ #lib/pure/collections/tables.nim(117, 21) template/generic instantiation from here
+ #lib/pure/collections/tableimpl.nim(32, 27) Error: undeclared field: 'hcode
+ doAssert 0 == t[testKey]
+ t.inc(testKey, 3)
+ doAssert 3 == t[testKey]
+
+block:
+ # Clear tests
+ var clearTable = newTable[int, string]()
+ clearTable[42] = "asd"
+ clearTable[123123] = "piuyqwb "
+ doAssert clearTable[42] == "asd"
+ clearTable.clear()
+ doAssert(not clearTable.hasKey(123123))
+ doAssert clearTable.getOrDefault(42) == ""
+
+block: #5482
+ var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
+ var b = newOrderedTable[string, string](initialSize = 2)
+ b["wrong?"] = "foo"
+ b["wrong?"] = "foo2"
+ assert a == b
+
+block: #5482
+ var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
+ var b = newOrderedTable[string, string](initialSize = 2)
+ b["wrong?"] = "foo"
+ b["wrong?"] = "foo2"
+ assert a == b
+
+block: #5487
+ var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
+ var b = newOrderedTable[string, string]() # notice, default size!
+ b["wrong?"] = "foo"
+ b["wrong?"] = "foo2"
+ assert a == b
+
+block: #5487
+ var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
+ var b = newOrderedTable[string, string]() # notice, default size!
+ b["wrong?"] = "foo"
+ b["wrong?"] = "foo2"
+ assert a == b
+
+block:
+ var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
+ var b = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
+ var c = newOrderedTable[string, string]() # notice, default size!
+ c["wrong?"] = "foo"
+ c["wrong?"] = "foo2"
+ assert a == b
+ assert a == c
+
+block: #6250
+ let
+ a = {3: 1}.toOrderedTable
+ b = {3: 2}.toOrderedTable
+ assert((a == b) == false)
+ assert((b == a) == false)
+
+block: #6250
+ let
+ a = {3: 2}.toOrderedTable
+ b = {3: 2}.toOrderedTable
+ assert((a == b) == true)
+ assert((b == a) == true)
+
+block: # CountTable.smallest
+ let t = toCountTable([0, 0, 5, 5, 5])
+ doAssert t.smallest == (0, 2)
+
+block: #10065
+ let t = toCountTable("abracadabra")
+ doAssert t['z'] == 0
+
+ var t_mut = toCountTable("abracadabra")
+ doAssert t_mut['z'] == 0
+ # the previous read may not have modified the table.
+ doAssert t_mut.hasKey('z') == false
+ t_mut['z'] = 1
+ doAssert t_mut['z'] == 1
+ doAssert t_mut.hasKey('z') == true
+
+block: #12813 #13079
+ var t = toCountTable("abracadabra")
+ doAssert len(t) == 5
+
+ t['a'] = 0 # remove a key
+ doAssert len(t) == 4
+
+block:
+ var tp: Table[string, string] = initTable[string, string]()
+ doAssert "test1" == tp.getOrDefault("test1", "test1")
+ tp["test2"] = "test2"
+ doAssert "test2" == tp.getOrDefault("test2", "test1")
+ var tr: TableRef[string, string] = newTable[string, string]()
+ doAssert "test1" == tr.getOrDefault("test1", "test1")
+ tr["test2"] = "test2"
+ doAssert "test2" == tr.getOrDefault("test2", "test1")
+ var op: OrderedTable[string, string] = initOrderedTable[string, string]()
+ doAssert "test1" == op.getOrDefault("test1", "test1")
+ op["test2"] = "test2"
+ doAssert "test2" == op.getOrDefault("test2", "test1")
+ var orf: OrderedTableRef[string, string] = newOrderedTable[string, string]()
+ doAssert "test1" == orf.getOrDefault("test1", "test1")
+ orf["test2"] = "test2"
+ doAssert "test2" == orf.getOrDefault("test2", "test1")
+
+block tableWithoutInit:
+ var
+ a: Table[string, int]
+ b: Table[string, int]
+ c: Table[string, int]
+ d: Table[string, int]
+ e: Table[string, int]
+
+ a["a"] = 7
+ doAssert a.hasKey("a")
+ doAssert a.len == 1
+ doAssert a["a"] == 7
+ a["a"] = 9
+ doAssert a.len == 1
+ doAssert a["a"] == 9
+
+ doAssert b.hasKeyOrPut("b", 5) == false
+ doAssert b.hasKey("b")
+ doAssert b.hasKeyOrPut("b", 8)
+ doAssert b["b"] == 5
+
+ doAssert c.getOrDefault("a") == 0
+ doAssert c.getOrDefault("a", 3) == 3
+ c["a"] = 6
+ doAssert c.getOrDefault("a", 3) == 6
+
+ doAssert d.mgetOrPut("a", 3) == 3
+ doAssert d.mgetOrPut("a", 6) == 3
+
+ var x = 99
+ doAssert e.pop("a", x) == false
+ doAssert x == 99
+ e["a"] = 77
+ doAssert e.pop("a", x)
+ doAssert x == 77
+
+block orderedTableWithoutInit:
+ var
+ a: OrderedTable[string, int]
+ b: OrderedTable[string, int]
+ c: OrderedTable[string, int]
+ d: OrderedTable[string, int]
+
+ a["a"] = 7
+ doAssert a.hasKey("a")
+ doAssert a.len == 1
+ doAssert a["a"] == 7
+ a["a"] = 9
+ doAssert a.len == 1
+ doAssert a["a"] == 9
+
+ doAssert b.hasKeyOrPut("b", 5) == false
+ doAssert b.hasKey("b")
+ doAssert b.hasKeyOrPut("b", 8)
+ doAssert b["b"] == 5
+
+ doAssert c.getOrDefault("a") == 0
+ doAssert c.getOrDefault("a", 3) == 3
+ c["a"] = 6
+ doAssert c.getOrDefault("a", 3) == 6
+
+ doAssert d.mgetOrPut("a", 3) == 3
+ doAssert d.mgetOrPut("a", 6) == 3
+
+block countTableWithoutInit:
+ var
+ a: CountTable[string]
+ b: CountTable[string]
+ c: CountTable[string]
+ d: CountTable[string]
+ e: CountTable[string]
+
+ a["a"] = 7
+ doAssert a.hasKey("a")
+ doAssert a.len == 1
+ doAssert a["a"] == 7
+ a["a"] = 9
+ doAssert a.len == 1
+ doAssert a["a"] == 9
+
+ doAssert b["b"] == 0
+ b.inc("b")
+ doAssert b["b"] == 1
+
+ doAssert c.getOrDefault("a") == 0
+ doAssert c.getOrDefault("a", 3) == 3
+ c["a"] = 6
+ doAssert c.getOrDefault("a", 3) == 6
+
+ e["f"] = 3
+ merge(d, e)
+ doAssert d.hasKey("f")
+ d.inc("f")
+ merge(d, e)
+ doAssert d["f"] == 7
diff --git a/tests/stdlib/tunicode.nim b/tests/stdlib/tunicode.nim
new file mode 100644
index 0000000000000..a346106f9ff35
--- /dev/null
+++ b/tests/stdlib/tunicode.nim
@@ -0,0 +1,215 @@
+import unicode
+
+
+proc asRune(s: static[string]): Rune =
+ ## Compile-time conversion proc for converting string literals to a Rune
+ ## value. Returns the first Rune of the specified string.
+ ##
+ ## Shortcuts code like ``"å".runeAt(0)`` to ``"å".asRune`` and returns a
+ ## compile-time constant.
+ if s.len == 0: Rune(0)
+ else: s.runeAt(0)
+
+let
+ someString = "öÑ"
+ someRunes = toRunes(someString)
+ compared = (someString == $someRunes)
+doAssert compared == true
+
+proc testReplacements(word: string): string =
+ case word
+ of "two":
+ return "2"
+ of "foo":
+ return "BAR"
+ of "βeta":
+ return "beta"
+ of "alpha":
+ return "αlpha"
+ else:
+ return "12345"
+
+doAssert translate("two not alpha foo βeta", testReplacements) == "2 12345 αlpha BAR beta"
+doAssert translate(" two not foo βeta ", testReplacements) == " 2 12345 BAR beta "
+
+doAssert title("foo bar") == "Foo Bar"
+doAssert title("αlpha βeta γamma") == "Αlpha Βeta Γamma"
+doAssert title("") == ""
+
+doAssert capitalize("βeta") == "Βeta"
+doAssert capitalize("foo") == "Foo"
+doAssert capitalize("") == ""
+
+doAssert swapCase("FooBar") == "fOObAR"
+doAssert swapCase(" ") == " "
+doAssert swapCase("Αlpha Βeta Γamma") == "αLPHA βETA γAMMA"
+doAssert swapCase("a✓B") == "A✓b"
+doAssert swapCase("Јамогујестистаклоитоминештети") == "јАМОГУЈЕСТИСТАКЛОИТОМИНЕШТЕТИ"
+doAssert swapCase("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει") == "ὝΑΛΟΝΦΑΓΕῖΝΔΎΝΑΜΑΙΤΟῦΤΟΟὔΜΕΒΛΆΠΤΕΙ"
+doAssert swapCase("Կրնամապակիուտեևինծիանհանգիստչըներ") == "կՐՆԱՄԱՊԱԿԻՈՒՏԵևԻՆԾԻԱՆՀԱՆԳԻՍՏՉԸՆԵՐ"
+doAssert swapCase("") == ""
+
+doAssert isAlpha("r")
+doAssert isAlpha("α")
+doAssert isAlpha("ϙ")
+doAssert isAlpha("ஶ")
+doAssert(not isAlpha("$"))
+doAssert(not isAlpha(""))
+
+doAssert isAlpha("Βeta")
+doAssert isAlpha("Args")
+doAssert isAlpha("𐌼𐌰𐌲𐌲𐌻𐌴𐍃𐍄𐌰𐌽")
+doAssert isAlpha("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει")
+doAssert isAlpha("Јамогујестистаклоитоминештети")
+doAssert isAlpha("Կրնամապակիուտեևինծիանհանգիստչըներ")
+doAssert(not isAlpha("$Foo✓"))
+doAssert(not isAlpha("⠙⠕⠑⠎⠝⠞"))
+
+doAssert isSpace("\t")
+doAssert isSpace("\l")
+doAssert(not isSpace("Β"))
+doAssert(not isSpace("Βeta"))
+
+doAssert isSpace("\t\l \v\r\f")
+doAssert isSpace(" ")
+doAssert(not isSpace(""))
+doAssert(not isSpace("ΑΓc \td"))
+
+doAssert(not isLower(' '.Rune))
+
+doAssert(not isUpper(' '.Rune))
+
+doAssert toUpper("Γ") == "Γ"
+doAssert toUpper("b") == "B"
+doAssert toUpper("α") == "Α"
+doAssert toUpper("✓") == "✓"
+doAssert toUpper("ϙ") == "Ϙ"
+doAssert toUpper("") == ""
+
+doAssert toUpper("ΑΒΓ") == "ΑΒΓ"
+doAssert toUpper("AAccβ") == "AACCΒ"
+doAssert toUpper("A✓$β") == "A✓$Β"
+
+doAssert toLower("a") == "a"
+doAssert toLower("γ") == "γ"
+doAssert toLower("Γ") == "γ"
+doAssert toLower("4") == "4"
+doAssert toLower("Ϙ") == "ϙ"
+doAssert toLower("") == ""
+
+doAssert toLower("abcdγ") == "abcdγ"
+doAssert toLower("abCDΓ") == "abcdγ"
+doAssert toLower("33aaΓ") == "33aaγ"
+
+doAssert reversed("Reverse this!") == "!siht esreveR"
+doAssert reversed("先秦兩漢") == "漢兩秦先"
+doAssert reversed("as⃝df̅") == "f̅ds⃝a"
+doAssert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞"
+doAssert reversed("ὕαλονϕαγεῖνδύναμαιτοῦτοοὔμεβλάπτει") == "ιετπάλβεμὔοοτῦοτιαμανύδνῖεγαϕνολαὕ"
+doAssert reversed("Јамогујестистаклоитоминештети") == "итетшенимотиолкатситсејугомаЈ"
+doAssert reversed("Կրնամապակիուտեևինծիանհանգիստչըներ") == "րենըչտսիգնահնաիծնիևետւոիկապամանրԿ"
+doAssert len(toRunes("as⃝df̅")) == runeLen("as⃝df̅")
+const test = "as⃝"
+doAssert lastRune(test, test.len-1)[1] == 3
+doAssert graphemeLen("è", 0) == 2
+
+# test for rune positioning and runeSubStr()
+let s = "Hänsel ««: 10,00€"
+
+var t = ""
+for c in s.utf8:
+ t.add c
+
+doAssert(s == t)
+
+doAssert(runeReverseOffset(s, 1) == (20, 18))
+doAssert(runeReverseOffset(s, 19) == (-1, 18))
+
+doAssert(runeStrAtPos(s, 0) == "H")
+doAssert(runeSubStr(s, 0, 1) == "H")
+doAssert(runeStrAtPos(s, 10) == ":")
+doAssert(runeSubStr(s, 10, 1) == ":")
+doAssert(runeStrAtPos(s, 9) == "«")
+doAssert(runeSubStr(s, 9, 1) == "«")
+doAssert(runeStrAtPos(s, 17) == "€")
+doAssert(runeSubStr(s, 17, 1) == "€")
+# echo runeStrAtPos(s, 18) # index error
+
+doAssert(runeSubStr(s, 0) == "Hänsel ««: 10,00€")
+doAssert(runeSubStr(s, -18) == "Hänsel ««: 10,00€")
+doAssert(runeSubStr(s, 10) == ": 10,00€")
+doAssert(runeSubStr(s, 18) == "")
+doAssert(runeSubStr(s, 0, 10) == "Hänsel ««")
+
+doAssert(runeSubStr(s, 12) == "10,00€")
+doAssert(runeSubStr(s, -6) == "10,00€")
+
+doAssert(runeSubStr(s, 12, 5) == "10,00")
+doAssert(runeSubStr(s, 12, -1) == "10,00")
+doAssert(runeSubStr(s, -6, 5) == "10,00")
+doAssert(runeSubStr(s, -6, -1) == "10,00")
+
+doAssert(runeSubStr(s, 0, 100) == "Hänsel ««: 10,00€")
+doAssert(runeSubStr(s, -100, 100) == "Hänsel ««: 10,00€")
+doAssert(runeSubStr(s, 0, -100) == "")
+doAssert(runeSubStr(s, 100, -100) == "")
+
+block splitTests:
+ let s = " this is an example "
+ let s2 = ":this;is;an:example;;"
+ let s3 = ":this×is×an:example××"
+ doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
+ doAssert s2.split(seps = [':'.Rune, ';'.Rune]) == @["", "this", "is", "an",
+ "example", "", ""]
+ doAssert s3.split(seps = [':'.Rune, "×".asRune]) == @["", "this", "is",
+ "an", "example", "", ""]
+ doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "]
+ doAssert s.split(' '.Rune, maxsplit = 1) == @["", "this is an example "]
+ doAssert s3.split("×".runeAt(0)) == @[":this", "is", "an:example", "", ""]
+
+block stripTests:
+ doAssert(strip("") == "")
+ doAssert(strip(" ") == "")
+ doAssert(strip("y") == "y")
+ doAssert(strip(" foofoofoo ") == "foofoofoo")
+ doAssert(strip("sfoofoofoos", runes = ['s'.Rune]) == "foofoofoo")
+
+ block:
+ let stripTestRunes = ['b'.Rune, 'a'.Rune, 'r'.Rune]
+ doAssert(strip("barfoofoofoobar", runes = stripTestRunes) == "foofoofoo")
+ doAssert(strip("sfoofoofoos", leading = false, runes = ['s'.Rune]) == "sfoofoofoo")
+ doAssert(strip("sfoofoofoos", trailing = false, runes = ['s'.Rune]) == "foofoofoos")
+
+ block:
+ let stripTestRunes = ["«".asRune, "»".asRune]
+ doAssert(strip("«TEXT»", runes = stripTestRunes) == "TEXT")
+ doAssert(strip("copyright©", leading = false, runes = ["©".asRune]) == "copyright")
+ doAssert(strip("¿Question?", trailing = false, runes = ["¿".asRune]) == "Question?")
+ doAssert(strip("×text×", leading = false, runes = ["×".asRune]) == "×text")
+ doAssert(strip("×text×", trailing = false, runes = ["×".asRune]) == "text×")
+
+block repeatTests:
+ doAssert repeat('c'.Rune, 5) == "ccccc"
+ doAssert repeat("×".asRune, 5) == "×××××"
+
+block alignTests:
+ doAssert align("abc", 4) == " abc"
+ doAssert align("a", 0) == "a"
+ doAssert align("1232", 6) == " 1232"
+ doAssert align("1232", 6, '#'.Rune) == "##1232"
+ doAssert align("1232", 6, "×".asRune) == "××1232"
+ doAssert alignLeft("abc", 4) == "abc "
+ doAssert alignLeft("a", 0) == "a"
+ doAssert alignLeft("1232", 6) == "1232 "
+ doAssert alignLeft("1232", 6, '#'.Rune) == "1232##"
+ doAssert alignLeft("1232", 6, "×".asRune) == "1232××"
+
+block differentSizes:
+ # upper and lower variants have different number of bytes
+ doAssert toLower("AẞC") == "aßc"
+ doAssert toLower("ȺẞCD") == "ⱥßcd"
+ doAssert toUpper("ⱥbc") == "ȺBC"
+ doAssert toUpper("rsⱦuv") == "RSȾUV"
+ doAssert swapCase("ⱥbCd") == "ȺBcD"
+ doAssert swapCase("XyꟆaB") == "xYᶎAb"
+ doAssert swapCase("aᵹcᲈd") == "AꝽCꙊD"
diff --git a/tests/stdlib/tunidecode.nim b/tests/stdlib/tunidecode.nim
index 576bfa2cb1236..7784fffb46357 100644
--- a/tests/stdlib/tunidecode.nim
+++ b/tests/stdlib/tunidecode.nim
@@ -9,6 +9,5 @@ import std/unidecode # #14112
loadUnidecodeTable("lib/pure/unidecode/unidecode.dat")
-#assert unidecode("\x53\x17\x4E\xB0") == "Bei Jing"
+# assert unidecode("\x53\x17\x4E\xB0") == "Bei Jing"
echo unidecode("Äußerst")
-
diff --git a/tests/stdlib/turi.nim b/tests/stdlib/turi.nim
index 9fb349e88bc3e..62fb17e4d40be 100644
--- a/tests/stdlib/turi.nim
+++ b/tests/stdlib/turi.nim
@@ -6,7 +6,7 @@ discard """
exitcode: 0
timeout: 60.0
"""
-import uri
+include uri
block:
@@ -15,3 +15,286 @@ block:
doAssert url.hostname == "2001:0db8:85a3:0000:0000:8a2e:0370:7334" # true
let newUrl = parseUri($url)
doAssert newUrl.hostname == "2001:0db8:85a3:0000:0000:8a2e:0370:7334" # true
+
+
+block:
+ block:
+ const test1 = "abc\L+def xyz"
+ doAssert encodeUrl(test1) == "abc%0A%2Bdef+xyz"
+ doAssert decodeUrl(encodeUrl(test1)) == test1
+ doAssert encodeUrl(test1, false) == "abc%0A%2Bdef%20xyz"
+ doAssert decodeUrl(encodeUrl(test1, false), false) == test1
+ doAssert decodeUrl(encodeUrl(test1)) == test1
+
+ block:
+ let str = "http://localhost"
+ let test = parseUri(str)
+ doAssert test.path == ""
+
+ block:
+ let str = "http://localhost/"
+ let test = parseUri(str)
+ doAssert test.path == "/"
+
+ block:
+ let str = "http://localhost:8080/test"
+ let test = parseUri(str)
+ doAssert test.scheme == "http"
+ doAssert test.port == "8080"
+ doAssert test.path == "/test"
+ doAssert test.hostname == "localhost"
+ doAssert($test == str)
+
+ block:
+ let str = "foo://username:password@example.com:8042/over/there" &
+ "/index.dtb?type=animal&name=narwhal#nose"
+ let test = parseUri(str)
+ doAssert test.scheme == "foo"
+ doAssert test.username == "username"
+ doAssert test.password == "password"
+ doAssert test.hostname == "example.com"
+ doAssert test.port == "8042"
+ doAssert test.path == "/over/there/index.dtb"
+ doAssert test.query == "type=animal&name=narwhal"
+ doAssert test.anchor == "nose"
+ doAssert($test == str)
+
+ block:
+ # IPv6 address
+ let str = "foo://[::1]:1234/bar?baz=true&qux#quux"
+ let uri = parseUri(str)
+ doAssert uri.scheme == "foo"
+ doAssert uri.hostname == "::1"
+ doAssert uri.port == "1234"
+ doAssert uri.path == "/bar"
+ doAssert uri.query == "baz=true&qux"
+ doAssert uri.anchor == "quux"
+
+ block:
+ let str = "urn:example:animal:ferret:nose"
+ let test = parseUri(str)
+ doAssert test.scheme == "urn"
+ doAssert test.path == "example:animal:ferret:nose"
+ doAssert($test == str)
+
+ block:
+ let str = "mailto:username@example.com?subject=Topic"
+ let test = parseUri(str)
+ doAssert test.scheme == "mailto"
+ doAssert test.username == "username"
+ doAssert test.hostname == "example.com"
+ doAssert test.query == "subject=Topic"
+ doAssert($test == str)
+
+ block:
+ let str = "magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar"
+ let test = parseUri(str)
+ doAssert test.scheme == "magnet"
+ doAssert test.query == "xt=urn:sha1:72hsga62ba515sbd62&dn=foobar"
+ doAssert($test == str)
+
+ block:
+ let str = "/test/foo/bar?q=2#asdf"
+ let test = parseUri(str)
+ doAssert test.scheme == ""
+ doAssert test.path == "/test/foo/bar"
+ doAssert test.query == "q=2"
+ doAssert test.anchor == "asdf"
+ doAssert($test == str)
+
+ block:
+ let str = "test/no/slash"
+ let test = parseUri(str)
+ doAssert test.path == "test/no/slash"
+ doAssert($test == str)
+
+ block:
+ let str = "//git@github.com:dom96/packages"
+ let test = parseUri(str)
+ doAssert test.scheme == ""
+ doAssert test.username == "git"
+ doAssert test.hostname == "github.com"
+ doAssert test.port == "dom96"
+ doAssert test.path == "/packages"
+
+ block:
+ let str = "file:///foo/bar/baz.txt"
+ let test = parseUri(str)
+ doAssert test.scheme == "file"
+ doAssert test.username == ""
+ doAssert test.hostname == ""
+ doAssert test.port == ""
+ doAssert test.path == "/foo/bar/baz.txt"
+
+ # Remove dot segments tests
+ block:
+ doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"
+
+ # Combine tests
+ block:
+ let concat = combine(parseUri("http://google.com/foo/bar/"), parseUri("baz"))
+ doAssert concat.path == "/foo/bar/baz"
+ doAssert concat.hostname == "google.com"
+ doAssert concat.scheme == "http"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo"), parseUri("/baz"))
+ doAssert concat.path == "/baz"
+ doAssert concat.hostname == "google.com"
+ doAssert concat.scheme == "http"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
+ doAssert concat.path == "/foo/bar"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test"), parseUri("/bar"))
+ doAssert concat.path == "/bar"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
+ doAssert concat.path == "/foo/bar"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar"))
+ doAssert concat.path == "/foo/test/bar"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"))
+ doAssert concat.path == "/foo/test/bar/"
+
+ block:
+ let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"),
+ parseUri("baz"))
+ doAssert concat.path == "/foo/test/bar/baz"
+
+ # `/` tests
+ block:
+ let test = parseUri("http://example.com/foo") / "bar/asd"
+ doAssert test.path == "/foo/bar/asd"
+
+ block:
+ let test = parseUri("http://example.com/foo/") / "/bar/asd"
+ doAssert test.path == "/foo/bar/asd"
+
+ # removeDotSegments tests
+ block:
+ # empty test
+ doAssert removeDotSegments("") == ""
+
+ # bug #3207
+ block:
+ doAssert parseUri("http://qq/1").combine(parseUri("https://qqq")).`$` == "https://qqq"
+
+ # bug #4959
+ block:
+ let foo = parseUri("http://example.com") / "/baz"
+ doAssert foo.path == "/baz"
+
+ # bug found on stream 13/10/17
+ block:
+ let foo = parseUri("http://localhost:9515") / "status"
+ doAssert $foo == "http://localhost:9515/status"
+
+ # bug #6649 #6652
+ block:
+ var foo = parseUri("http://example.com")
+ foo.hostname = "example.com"
+ foo.path = "baz"
+ doAssert $foo == "http://example.com/baz"
+
+ foo.hostname = "example.com/"
+ foo.path = "baz"
+ doAssert $foo == "http://example.com/baz"
+
+ foo.hostname = "example.com"
+ foo.path = "/baz"
+ doAssert $foo == "http://example.com/baz"
+
+ foo.hostname = "example.com/"
+ foo.path = "/baz"
+ doAssert $foo == "http://example.com/baz"
+
+ foo.hostname = "example.com/"
+ foo.port = "8000"
+ foo.path = "baz"
+ doAssert $foo == "http://example.com:8000/baz"
+
+ foo = parseUri("file:/dir/file")
+ foo.path = "relative"
+ doAssert $foo == "file:relative"
+
+ # isAbsolute tests
+ block:
+ doAssert "www.google.com".parseUri().isAbsolute() == false
+ doAssert "http://www.google.com".parseUri().isAbsolute() == true
+ doAssert "file:/dir/file".parseUri().isAbsolute() == true
+ doAssert "file://localhost/dir/file".parseUri().isAbsolute() == true
+ doAssert "urn:ISSN:1535-3613".parseUri().isAbsolute() == true
+
+ # path-relative URL *relative
+ doAssert "about".parseUri().isAbsolute == false
+ doAssert "about/staff.html".parseUri().isAbsolute == false
+ doAssert "about/staff.html?".parseUri().isAbsolute == false
+ doAssert "about/staff.html?parameters".parseUri().isAbsolute == false
+
+ # absolute-path-relative URL *relative
+ doAssert "/".parseUri().isAbsolute == false
+ doAssert "/about".parseUri().isAbsolute == false
+ doAssert "/about/staff.html".parseUri().isAbsolute == false
+ doAssert "/about/staff.html?".parseUri().isAbsolute == false
+ doAssert "/about/staff.html?parameters".parseUri().isAbsolute == false
+
+ # scheme-relative URL *relative
+ doAssert "//username:password@example.com:8888".parseUri().isAbsolute == false
+ doAssert "//username@example.com".parseUri().isAbsolute == false
+ doAssert "//example.com".parseUri().isAbsolute == false
+ doAssert "//example.com/".parseUri().isAbsolute == false
+ doAssert "//example.com/about".parseUri().isAbsolute == false
+ doAssert "//example.com/about/staff.html".parseUri().isAbsolute == false
+ doAssert "//example.com/about/staff.html?".parseUri().isAbsolute == false
+ doAssert "//example.com/about/staff.html?parameters".parseUri().isAbsolute == false
+
+ # absolute URL *absolute
+ doAssert "https://username:password@example.com:8888".parseUri().isAbsolute == true
+ doAssert "https://username@example.com".parseUri().isAbsolute == true
+ doAssert "https://example.com".parseUri().isAbsolute == true
+ doAssert "https://example.com/".parseUri().isAbsolute == true
+ doAssert "https://example.com/about".parseUri().isAbsolute == true
+ doAssert "https://example.com/about/staff.html".parseUri().isAbsolute == true
+ doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true
+ doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true
+
+ # encodeQuery tests
+ block:
+ doAssert encodeQuery({:}) == ""
+ doAssert encodeQuery({"foo": "bar"}) == "foo=bar"
+ doAssert encodeQuery({"foo": "bar & baz"}) == "foo=bar+%26+baz"
+ doAssert encodeQuery({"foo": "bar & baz"}, usePlus = false) == "foo=bar%20%26%20baz"
+ doAssert encodeQuery({"foo": ""}) == "foo"
+ doAssert encodeQuery({"foo": ""}, omitEq = false) == "foo="
+ doAssert encodeQuery({"a": "1", "b": "", "c": "3"}) == "a=1&b&c=3"
+ doAssert encodeQuery({"a": "1", "b": "", "c": "3"}, omitEq = false) == "a=1&b=&c=3"
+
+ block:
+ var foo = parseUri("http://example.com") / "foo" ? {"bar": "1", "baz": "qux"}
+ var foo1 = parseUri("http://example.com/foo?bar=1&baz=qux")
+ doAssert foo == foo1
+
+ block:
+ var foo = parseUri("http://example.com") / "foo" ? {"do": "do", "bar": ""}
+ var foo1 = parseUri("http://example.com/foo?do=do&bar")
+ doAssert foo == foo1
+
+ block dataUriBase64:
+ doAssert getDataUri("", "text/plain") == "data:text/plain;charset=utf-8;base64,"
+ doAssert getDataUri(" ", "text/plain") == "data:text/plain;charset=utf-8;base64,IA=="
+ doAssert getDataUri("c\xf7>", "text/plain") == "data:text/plain;charset=utf-8;base64,Y/c+"
+ doAssert getDataUri("Hello World", "text/plain") == "data:text/plain;charset=utf-8;base64,SGVsbG8gV29ybGQ="
+ doAssert getDataUri("leasure.", "text/plain") == "data:text/plain;charset=utf-8;base64,bGVhc3VyZS4="
+ doAssert getDataUri("""!@#$%^&*()_+""", "text/plain") == "data:text/plain;charset=utf-8;base64,IUAjJCVeJiooKV8r"
+ doAssert(getDataUri("the quick brown dog jumps over the lazy fox", "text/plain") ==
+ "data:text/plain;charset=utf-8;base64,dGhlIHF1aWNrIGJyb3duIGRvZyBqdW1wcyBvdmVyIHRoZSBsYXp5IGZveA==")
+ doAssert(getDataUri("""The present is theirs
+ The future, for which I really worked, is mine.""", "text/plain") ==
+ "data:text/plain;charset=utf-8;base64,VGhlIHByZXNlbnQgaXMgdGhlaXJzCiAgICAgIFRoZSBmdXR1cmUsIGZvciB3aGljaCBJIHJlYWxseSB3b3JrZWQsIGlzIG1pbmUu")