mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-13 06:43:52 +00:00
move tests to testament (#16101)
* move tests to testament
* minor
* fix random
* disable test random
(cherry picked from commit cbc793b30b)
This commit is contained in:
@@ -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 <http://www.cplusplus.com/reference/algorithm/rotate/>`_.
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -480,46 +480,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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1078,128 +1078,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
|
||||
|
||||
@@ -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.}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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.}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -645,57 +645,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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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", "")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -2975,220 +2975,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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 "
|
||||
|
||||
285
lib/pure/uri.nim
285
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!")
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
15
tests/stdlib/tcookies.nim
Normal file
15
tests/stdlib/tcookies.nim
Normal file
@@ -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"
|
||||
61
tests/stdlib/tcritbits.nim
Normal file
61
tests/stdlib/tcritbits.nim
Normal file
@@ -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"
|
||||
19
tests/stdlib/tenumerate.nim
Normal file
19
tests/stdlib/tenumerate.nim
Normal file
@@ -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)]
|
||||
8
tests/stdlib/tfenv.nim
Normal file
8
tests/stdlib/tfenv.nim
Normal file
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
7
tests/stdlib/tmd5.nim
Normal file
7
tests/stdlib/tmd5.nim
Normal file
@@ -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")
|
||||
16
tests/stdlib/tmonotimes.nim
Normal file
16
tests/stdlib/tmonotimes.nim
Normal file
@@ -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
|
||||
@@ -13,4 +13,146 @@ type
|
||||
let js = """{"foo": {"test": "123"}}"""
|
||||
let parsed = parseJson(js)
|
||||
let a = parsed.to(Test)
|
||||
echo $(%*a)
|
||||
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
|
||||
|
||||
31
tests/stdlib/tparsecsv.nim
Normal file
31
tests/stdlib/tparsecsv.nim
Normal file
@@ -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")
|
||||
43
tests/stdlib/tparseutils.nim
Normal file
43
tests/stdlib/tparseutils.nim
Normal file
@@ -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
|
||||
5
tests/stdlib/tpunycode.nim
Normal file
5
tests/stdlib/tpunycode.nim
Normal file
@@ -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"
|
||||
59
tests/stdlib/trandom.nim
Normal file
59
tests/stdlib/trandom.nim
Normal file
@@ -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()
|
||||
98
tests/stdlib/trationals.nim
Normal file
98
tests/stdlib/trationals.nim
Normal file
@@ -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
|
||||
13
tests/stdlib/tsha1.nim
Normal file
13
tests/stdlib/tsha1.nim
Normal file
@@ -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")
|
||||
46
tests/stdlib/tstats.nim
Normal file
46
tests/stdlib/tstats.nim
Normal file
@@ -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()))
|
||||
@@ -62,3 +62,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
|
||||
|
||||
@@ -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"
|
||||
22
tests/stdlib/tstrmiscs.nim
Normal file
22
tests/stdlib/tstrmiscs.nim
Normal file
@@ -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", "")
|
||||
@@ -98,3 +98,115 @@ block issue15064:
|
||||
doAssert scanf("<abcd> ", "<$+> $*", 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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
311
tests/stdlib/ttables.nim
Normal file
311
tests/stdlib/ttables.nim
Normal file
@@ -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
|
||||
215
tests/stdlib/tunicode.nim
Normal file
215
tests/stdlib/tunicode.nim
Normal file
@@ -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"
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user