summary refs log tree commit diff stats
path: root/tests/collections
diff options
context:
space:
mode:
Diffstat (limited to 'tests/collections')
-rw-r--r--tests/collections/tactiontable.nim37
-rw-r--r--tests/collections/tcollections.nim105
-rw-r--r--tests/collections/tcollections_to_string.nim115
-rw-r--r--tests/collections/thashsets.nim382
-rw-r--r--tests/collections/tseq.nim242
-rw-r--r--tests/collections/ttables.nim457
-rw-r--r--tests/collections/ttablesthreads.nim276
7 files changed, 1614 insertions, 0 deletions
diff --git a/tests/collections/tactiontable.nim b/tests/collections/tactiontable.nim
new file mode 100644
index 000000000..3f15a70bd
--- /dev/null
+++ b/tests/collections/tactiontable.nim
@@ -0,0 +1,37 @@
+discard """
+  output: '''
+action 3 arg
+action 3 arg
+'''
+"""
+
+import tables
+
+proc action1(arg: string) =
+  echo "action 1 ", arg
+
+proc action2(arg: string) =
+  echo "action 2 ", arg
+
+proc action3(arg: string) =
+  echo "action 3 ", arg
+
+proc action4(arg: string) =
+  echo "action 4 ", arg
+
+var
+  actionTable1 = {
+    "A": action1,
+    "B": action2,
+    "C": action3,
+    "D": action4}.toTable
+
+const
+  actionTable2 = {
+    "A": action1,
+    "B": action2,
+    "C": action3,
+    "D": action4}.toTable
+
+actionTable1["C"]("arg")
+actionTable2["C"]("arg")
diff --git a/tests/collections/tcollections.nim b/tests/collections/tcollections.nim
new file mode 100644
index 000000000..7677f7c1a
--- /dev/null
+++ b/tests/collections/tcollections.nim
@@ -0,0 +1,105 @@
+discard """
+  targets: "c js"
+"""
+
+# see also: tdeques, tlists, tcritbits
+
+import sets, tables, sequtils
+
+block tapply:
+  var x = @[1, 2, 3]
+  x.apply(proc(x: var int) = x = x+10)
+  x.apply(proc(x: int): int = x+100)
+  x.applyIt(it+5000)
+  doAssert x == @[5111, 5112, 5113]
+
+block tmapit:
+  var x = @[1, 2, 3]
+  # This mapIt call will run with preallocation because ``len`` is available.
+  var y = x.mapIt($(it+10))
+  doAssert y == @["11", "12", "13"]
+
+  type structureWithoutLen = object
+    a: array[5, int]
+
+  iterator items(s: structureWithoutLen): int {.inline.} =
+    yield s.a[0]
+    yield s.a[1]
+    yield s.a[2]
+    yield s.a[3]
+    yield s.a[4]
+
+  var st: structureWithoutLen
+  st.a[0] = 0
+  st.a[1] = 1
+  st.a[2] = 2
+  st.a[3] = 3
+  st.a[4] = 4
+
+  # this will run without preallocating the result
+  # since ``len`` is not available
+  var r = st.mapIt($(it+10))
+  doAssert r == @["10", "11", "12", "13", "14"]
+
+
+
+# Collections to string:
+
+# Tests for tuples
+doAssert $(1, 2, 3) == "(1, 2, 3)"
+doAssert $("1", "2", "3") == """("1", "2", "3")"""
+doAssert $('1', '2', '3') == """('1', '2', '3')"""
+
+# Tests for seqs
+doAssert $(@[1, 2, 3]) == "@[1, 2, 3]"
+doAssert $(@["1", "2", "3"]) == """@["1", "2", "3"]"""
+doAssert $(@['1', '2', '3']) == """@['1', '2', '3']"""
+
+# Tests for sets
+doAssert $(toHashSet([1])) == "{1}"
+doAssert $(toHashSet(["1"])) == """{"1"}"""
+doAssert $(toHashSet(['1'])) == """{'1'}"""
+doAssert $(toOrderedSet([1, 2, 3])) == "{1, 2, 3}"
+doAssert $(toOrderedSet(["1", "2", "3"])) == """{"1", "2", "3"}"""
+doAssert $(toOrderedSet(['1', '2', '3'])) == """{'1', '2', '3'}"""
+
+# see also: tcritbitsToString, tlistsToString
+
+# Tests for tables
+when defined(nimIntHash1):
+  doAssert $({1: "1", 2: "2"}.toTable) == """{1: "1", 2: "2"}"""
+else:
+  doAssert $({1: "1", 2: "2"}.toTable) == """{2: "2", 1: "1"}"""
+let tabStr = $({"1": 1, "2": 2}.toTable)
+doAssert (tabStr == """{"2": 2, "1": 1}""" or tabStr == """{"1": 1, "2": 2}""")
+
+# Test escaping behavior
+block:
+  var s = ""
+  s.addQuoted('\0')
+  s.addQuoted('\31')
+  s.addQuoted('\127')
+  doAssert s == "'\\x00''\\x1F''\\x7F'"
+block:
+  var s = ""
+  s.addQuoted('\\')
+  s.addQuoted('\'')
+  s.addQuoted('\"')
+  doAssert s == """'\\''\'''\"'"""
+block:
+  var s = ""
+  s.addQuoted("å")
+  s.addQuoted("ä")
+  s.addQuoted("ö")
+  s.addEscapedChar('\xFF')
+  doAssert s == """"å""ä""ö"\xFF"""
+
+# Test customized element representation
+type CustomString = object
+
+proc addQuoted(s: var string, x: CustomString) =
+  s.add("<CustomString>")
+
+block:
+  let s = @[CustomString()]
+  doAssert $s == "@[<CustomString>]"
diff --git a/tests/collections/tcollections_to_string.nim b/tests/collections/tcollections_to_string.nim
new file mode 100644
index 000000000..62ba87334
--- /dev/null
+++ b/tests/collections/tcollections_to_string.nim
@@ -0,0 +1,115 @@
+discard """
+  exitcode: 0
+  output: ""
+"""
+import sets
+import tables
+import deques
+import lists
+import critbits
+
+# Tests for tuples
+doAssert $(1, 2, 3) == "(1, 2, 3)"
+doAssert $("1", "2", "3") == """("1", "2", "3")"""
+doAssert $('1', '2', '3') == """('1', '2', '3')"""
+
+# Tests for seqs
+doAssert $(@[1, 2, 3]) == "@[1, 2, 3]"
+doAssert $(@["1", "2", "3"]) == """@["1", "2", "3"]"""
+doAssert $(@['1', '2', '3']) == """@['1', '2', '3']"""
+
+# Tests for sets
+doAssert $(toHashSet([1])) == "{1}"
+doAssert $(toHashSet(["1"])) == """{"1"}"""
+doAssert $(toHashSet(['1'])) == """{'1'}"""
+doAssert $(toOrderedSet([1, 2, 3])) == "{1, 2, 3}"
+doAssert $(toOrderedSet(["1", "2", "3"])) == """{"1", "2", "3"}"""
+doAssert $(toOrderedSet(['1', '2', '3'])) == """{'1', '2', '3'}"""
+
+# Tests for tables
+when defined(nimIntHash1):
+  doAssert $({1: "1", 2: "2"}.toTable) == """{1: "1", 2: "2"}"""
+else:
+  doAssert $({1: "1", 2: "2"}.toTable) == """{2: "2", 1: "1"}"""
+doAssert $({"1": 1, "2": 2}.toTable) == """{"1": 1, "2": 2}"""
+
+# Tests for deques
+block:
+  var d = initDeque[int]()
+  d.addLast(1)
+  doAssert $d == "[1]"
+block:
+  var d = initDeque[string]()
+  d.addLast("1")
+  doAssert $d == """["1"]"""
+block:
+  var d = initDeque[char]()
+  d.addLast('1')
+  doAssert $d == "['1']"
+
+# Tests for lists
+block:
+  var l = initDoublyLinkedList[int]()
+  l.append(1)
+  l.append(2)
+  l.append(3)
+  doAssert $l == "[1, 2, 3]"
+block:
+  var l = initDoublyLinkedList[string]()
+  l.append("1")
+  l.append("2")
+  l.append("3")
+  doAssert $l == """["1", "2", "3"]"""
+block:
+  var l = initDoublyLinkedList[char]()
+  l.append('1')
+  l.append('2')
+  l.append('3')
+  doAssert $l == """['1', '2', '3']"""
+
+# Tests for critbits
+block:
+  var t: CritBitTree[int]
+  t["a"] = 1
+  doAssert $t == """{"a": 1}"""
+block:
+  var t: CritBitTree[string]
+  t["a"] = "1"
+  doAssert $t == """{"a": "1"}"""
+block:
+  var t: CritBitTree[char]
+  t["a"] = '1'
+  doAssert $t == """{"a": '1'}"""
+
+
+# Test escaping behavior
+block:
+  var s = ""
+  s.addQuoted('\0')
+  s.addQuoted('\31')
+  s.addQuoted('\127')
+  doAssert s == "'\\x00''\\x1F''\\x7F'"
+block:
+  var s = ""
+  s.addQuoted('\\')
+  s.addQuoted('\'')
+  s.addQuoted('\"')
+  doAssert s == """'\\''\'''\"'"""
+block:
+  var s = ""
+  s.addQuoted("å")
+  s.addQuoted("ä")
+  s.addQuoted("ö")
+  s.addEscapedChar('\xFF')
+  doAssert s == """"å""ä""ö"\xFF"""
+
+# Test customized element representation
+type CustomString = object
+
+proc addQuoted(s: var string, x: CustomString) =
+  s.add("<CustomString>")
+
+block:
+  let s = @[CustomString()]
+  doAssert $s == "@[<CustomString>]"
+
diff --git a/tests/collections/thashsets.nim b/tests/collections/thashsets.nim
new file mode 100644
index 000000000..359eaa51e
--- /dev/null
+++ b/tests/collections/thashsets.nim
@@ -0,0 +1,382 @@
+import sets, hashes, algorithm
+
+
+block setEquality:
+  var
+    a = initHashSet[int]()
+    b = initHashSet[int]()
+    c = initHashSet[string]()
+
+  for i in 0..5: a.incl(i)
+  for i in 1..6: b.incl(i)
+  for i in 0..5: c.incl($i)
+
+  doAssert map(a, proc(x: int): int = x + 1) == b
+  doAssert map(a, proc(x: int): string = $x) == c
+
+
+block setsContainingTuples:
+  var set = initHashSet[tuple[i: int, i64: int64, f: float]]()
+  set.incl( (i: 123, i64: 123'i64, f: 3.14) )
+  doAssert set.contains( (i: 123, i64: 123'i64, f: 3.14) )
+  doAssert( not set.contains( (i: 456, i64: 789'i64, f: 2.78) ) )
+
+
+block setWithTuplesWithSeqs:
+  var s = initHashSet[tuple[s: seq[int]]]()
+  s.incl( (s: @[1, 2, 3]) )
+  doAssert s.contains( (s: @[1, 2, 3]) )
+  doAssert( not s.contains((s: @[4, 5, 6])) )
+
+
+block setWithSequences:
+  var s = initHashSet[seq[int]]()
+  s.incl( @[1, 2, 3] )
+  doAssert s.contains(@[1, 2, 3])
+  doAssert( not s.contains(@[4, 5, 6]) )
+
+block setClearWorked:
+  var s = initHashSet[char]()
+
+  for c in "this is a test":
+    s.incl(c)
+
+  doAssert len(s) == 7
+  clear(s)
+  doAssert len(s) == 0
+
+  s.incl('z')
+  for c in "this is a test":
+    s.incl(c)
+
+  doAssert len(s) == 8
+
+block orderedSetClearWorked:
+  var s = initOrderedSet[char]()
+
+  for c in "eat at joes":
+    s.incl(c)
+
+  var r = ""
+
+  for c in items(s):
+    add(r, c)
+
+  doAssert r == "eat jos"
+  clear(s)
+
+  s.incl('z')
+  for c in "eat at joes":
+    s.incl(c)
+
+  r = ""
+  for c in items(s):
+    add(r, c)
+
+  doAssert r == "zeat jos"
+
+block hashForHashedSet:
+  let
+    seq1 = "This is the test."
+    seq2 = "the test is This."
+    s1 = seq1.toHashSet()
+    s2 = seq2.toHashSet()
+  doAssert s1 == s2
+  doAssert hash(s1) == hash(s2)
+
+block hashForOrderdSet:
+  let
+    str = "This is the test."
+    rstr = str.reversed
+
+  var
+    s1 = initOrderedSet[char]()
+    s2 = initOrderedSet[char]()
+    r = initOrderedSet[char]()
+    expected: Hash
+    added: seq[char] = @[]
+    reversed: Hash
+    radded: seq[char] = @[]
+
+  expected = 0
+  for c in str:
+    if (not (c in added)):
+      expected = expected !& hash(c)
+      added.add(c)
+    s1.incl(c)
+    s2.incl(c)
+  expected = !$expected
+  doAssert hash(s1) == expected
+  doAssert hash(s1) == hash(s2)
+  doAssert hash(s1) != hash(r)
+
+  reversed = 0
+  for c in rstr:
+    if (not (c in radded)):
+      reversed = reversed !& hash(c)
+      radded.add(c)
+    r.incl(c)
+  reversed = !$reversed
+  doAssert hash(r) == reversed
+  doAssert hash(s1) != reversed
+
+
+proc testModule() =
+  ## Internal micro test to validate docstrings and such.
+  block lenTest:
+    var values: HashSet[int]
+    doAssert values.len == 0
+    doAssert values.card == 0
+
+  block setIterator:
+    type pair = tuple[a, b: int]
+    var a, b = initHashSet[pair]()
+    a.incl((2, 3))
+    a.incl((3, 2))
+    a.incl((2, 3))
+    for x, y in a.items:
+      b.incl((x - 2, y + 1))
+    doAssert a.len == b.card
+    doAssert a.len == 2
+    #echo b
+
+  block setContains:
+    var values = initHashSet[int]()
+    doAssert(not values.contains(2))
+    values.incl(2)
+    doAssert values.contains(2)
+    values.excl(2)
+    doAssert(not values.contains(2))
+
+    values.incl(4)
+    var others = toHashSet([6, 7])
+    values.incl(others)
+    doAssert values.len == 3
+
+    values.init
+    doAssert values.containsOrIncl(2) == false
+    doAssert values.containsOrIncl(2) == true
+    var
+      a = toHashSet([1, 2])
+      b = toHashSet([1])
+    b.incl(2)
+    doAssert a == b
+
+  block exclusions:
+    var s = toHashSet([2, 3, 6, 7])
+    s.excl(2)
+    s.excl(2)
+    doAssert s.len == 3
+
+    var
+      numbers = toHashSet([1, 2, 3, 4, 5])
+      even = toHashSet([2, 4, 6, 8])
+    numbers.excl(even)
+    #echo numbers
+    # --> {1, 3, 5}
+
+  block toSeqAndString:
+    var a = toHashSet([2, 7, 5])
+    var b = initHashSet[int](a.len)
+    for x in [2, 7, 5]: b.incl(x)
+    doAssert($a == $b)
+    #echo a
+    #echo toHashSet(["no", "esc'aping", "is \" provided"])
+
+  #block orderedToSeqAndString:
+  #  echo toOrderedSet([2, 4, 5])
+  #  echo toOrderedSet(["no", "esc'aping", "is \" provided"])
+
+  block setOperations:
+    var
+      a = toHashSet(["a", "b"])
+      b = toHashSet(["b", "c"])
+      c = union(a, b)
+    doAssert c == toHashSet(["a", "b", "c"])
+    var d = intersection(a, b)
+    doAssert d == toHashSet(["b"])
+    var e = difference(a, b)
+    doAssert e == toHashSet(["a"])
+    var f = symmetricDifference(a, b)
+    doAssert f == toHashSet(["a", "c"])
+    doAssert d < a and d < b
+    doAssert((a < a) == false)
+    doAssert d <= a and d <= b
+    doAssert((a <= a))
+    # Alias test.
+    doAssert a + b == toHashSet(["a", "b", "c"])
+    doAssert a * b == toHashSet(["b"])
+    doAssert a - b == toHashSet(["a"])
+    doAssert a -+- b == toHashSet(["a", "c"])
+    doAssert disjoint(a, b) == false
+    doAssert disjoint(a, b - a) == true
+
+  block mapSet:
+    var a = toHashSet([1, 2, 3])
+    var b = a.map(proc (x: int): string = $x)
+    doAssert b == toHashSet(["1", "2", "3"])
+
+  block lenTest:
+    var values: OrderedSet[int]
+    doAssert values.len == 0
+    doAssert values.card == 0
+
+  block setIterator:
+    type pair = tuple[a, b: int]
+    var a, b = initOrderedSet[pair]()
+    a.incl((2, 3))
+    a.incl((3, 2))
+    a.incl((2, 3))
+    for x, y in a.items:
+      b.incl((x - 2, y + 1))
+    doAssert a.len == b.card
+    doAssert a.len == 2
+
+  block setPairsIterator:
+    var s = toOrderedSet([1, 3, 5, 7])
+    var items = newSeq[tuple[a: int, b: int]]()
+    for idx, item in s: items.add((idx, item))
+    doAssert items == @[(0, 1), (1, 3), (2, 5), (3, 7)]
+
+  block exclusions:
+    var s = toOrderedSet([1, 2, 3, 6, 7, 4])
+
+    s.excl(3)
+    s.excl(3)
+    s.excl(1)
+    s.excl(4)
+
+    var items = newSeq[int]()
+    for item in s: items.add item
+    doAssert items == @[2, 6, 7]
+
+  block: #9005
+    var s = initOrderedSet[(int, int)]()
+    for i in 0 .. 30: incl(s, (i, 0))
+    for i in 0 .. 30: excl(s, (i, 0))
+    doAssert s.len == 0
+
+  #block orderedSetIterator:
+  #  var a = initOrderedSet[int]()
+  #  for value in [9, 2, 1, 5, 1, 8, 4, 2]:
+  #    a.incl(value)
+  #  for value in a.items:
+  #    echo "Got ", value
+
+  block setContains:
+    var values = initOrderedSet[int]()
+    doAssert(not values.contains(2))
+    values.incl(2)
+    doAssert values.contains(2)
+
+  block toSeqAndString:
+    var a = toOrderedSet([2, 4, 5])
+    var b = initOrderedSet[int]()
+    for x in [2, 4, 5]: b.incl(x)
+    doAssert($a == $b)
+    doAssert(a == b) # https://github.com/Araq/Nim/issues/1413
+
+  block initBlocks:
+    var a: OrderedSet[int]
+    a.init(4)
+    a.incl(2)
+    a.init
+    doAssert a.len == 0
+    a = initOrderedSet[int](4)
+    a.incl(2)
+    doAssert a.len == 1
+
+    var b: HashSet[int]
+    b.init(4)
+    b.incl(2)
+    b.init
+    doAssert b.len == 0
+    b = initHashSet[int](4)
+    b.incl(2)
+    doAssert b.len == 1
+
+  block missingOrExcl:
+    var s = toOrderedSet([2, 3, 6, 7])
+    doAssert s.missingOrExcl(4) == true
+    doAssert s.missingOrExcl(6) == false
+
+  block orderedSetEquality:
+    type pair = tuple[a, b: int]
+
+    var aa = initOrderedSet[pair]()
+    var bb = initOrderedSet[pair]()
+
+    var x = (a: 1, b: 2)
+    var y = (a: 3, b: 4)
+
+    aa.incl(x)
+    aa.incl(y)
+
+    bb.incl(x)
+    bb.incl(y)
+    doAssert aa == bb
+
+  block setsWithoutInit:
+    var
+      a: HashSet[int]
+      b: HashSet[int]
+      c: HashSet[int]
+      d: HashSet[int]
+      e: HashSet[int]
+
+    doAssert a.containsOrIncl(3) == false
+    doAssert a.contains(3)
+    doAssert a.len == 1
+    doAssert a.containsOrIncl(3)
+    a.incl(3)
+    doAssert a.len == 1
+    a.incl(6)
+    doAssert a.len == 2
+
+    b.incl(5)
+    doAssert b.len == 1
+    b.excl(5)
+    b.excl(c)
+    doAssert b.missingOrExcl(5)
+    doAssert b.disjoint(c)
+
+    d = b + c
+    doAssert d.len == 0
+    d = b * c
+    doAssert d.len == 0
+    d = b - c
+    doAssert d.len == 0
+    d = b -+- c
+    doAssert d.len == 0
+
+    doAssert (d < e) == false
+    doAssert d <= e
+    doAssert d == e
+
+  block setsWithoutInit:
+    var
+      a: OrderedSet[int]
+      b: OrderedSet[int]
+      c: OrderedSet[int]
+      d: HashSet[int]
+
+
+    doAssert a.containsOrIncl(3) == false
+    doAssert a.contains(3)
+    doAssert a.len == 1
+    doAssert a.containsOrIncl(3)
+    a.incl(3)
+    doAssert a.len == 1
+    a.incl(6)
+    doAssert a.len == 2
+
+    b.incl(5)
+    doAssert b.len == 1
+    doAssert b.missingOrExcl(5) == false
+    doAssert b.missingOrExcl(5)
+
+    doAssert c.missingOrExcl(9)
+    d.incl(c)
+    doAssert d.len == 0
+
+testModule()
diff --git a/tests/collections/tseq.nim b/tests/collections/tseq.nim
new file mode 100644
index 000000000..0f8084c78
--- /dev/null
+++ b/tests/collections/tseq.nim
@@ -0,0 +1,242 @@
+discard """
+  matrix: "--mm:refc; --mm:orc"
+  output: '''
+Hithere, what's your name?Hathere, what's your name?
+fA13msg1falsefB14msg2truefC15msg3false
+Zip: [{"Field0": 1, "Field1": 2}, {"Field0": 3, "Field1": 4}, {"Field0": 5, "Field1": 6}]
+Filter Iterator: 3
+Filter Iterator: 5
+Filter Iterator: 7
+Filter: [3, 5, 7]
+FilterIt: [1, 3, 7]
+Concat: [1, 3, 5, 7, 2, 4, 6]
+Deduplicate: [1, 2, 3, 4, 5, 7]
+@[()]
+Minmax: (1, 7)
+2345623456
+'''
+"""
+
+block tseq2:
+  proc `*`(a, b: seq[int]): seq[int] =
+    # allocate a new sequence:
+    newSeq(result, len(a))
+    # multiply two int sequences:
+    for i in 0..len(a)-1: result[i] = a[i] * b[i]
+
+  doAssert(@[1, 2, 3] * @[1, 2, 3] == @[1, 4, 9])
+
+
+
+block tseqcon:
+  const nestedFixed = true
+
+  type
+    TRec {.final.} = object
+      x, y: int
+      s: string
+      seq: seq[string]
+    TRecSeq = seq[TRec]
+
+  proc test() =
+    var s, b: seq[string]
+    s = @[]
+    add(s, "Hi")
+    add(s, "there, ")
+    add(s, "what's your name?")
+
+    b = s # deep copying here!
+    b[0][1] = 'a'
+
+    for i in 0 .. len(s)-1:
+      write(stdout, s[i])
+    for i in 0 .. len(b)-1:
+      write(stdout, b[i])
+
+  when nestedFixed:
+    proc nested() =
+      var
+        s: seq[seq[string]]
+      for i in 0..10_000: # test if the garbage collector
+        # now works with sequences
+        s = @[
+          @["A", "B", "C", "D"],
+          @["E", "F", "G", "H"],
+          @["I", "J", "K", "L"],
+          @["M", "N", "O", "P"]]
+
+  test()
+  when nestedFixed:
+    nested()
+  echo ""
+
+
+
+import os
+block tseqcon2:
+  proc rec_dir(dir: string): seq[string] =
+    result = @[]
+    for kind, path in walk_dir(dir):
+      if kind == pcDir:
+        add(result, rec_dir(path))
+      else:
+        add(result, path)
+
+
+
+block tseqtuple:
+  type
+    TMsg = tuple[
+      file: string,
+      line: int,
+      msg: string,
+      err: bool]
+
+  var s: seq[TMsg] = @[]
+
+  s.add(("fA", 13, "msg1", false))
+  s.add(("fB", 14, "msg2", true))
+  s.add(("fC", 15, "msg3", false))
+
+  for file, line, msg, err in items(s):
+    stdout.write(file)
+    stdout.write($line)
+    stdout.write(msg)
+    stdout.write($err)
+  echo ""
+
+
+import sequtils, marshal
+block tsequtils:
+  proc testFindWhere(item : int) : bool =
+    if item != 1: return true
+
+  var seq1: seq[int] = @[]
+
+  seq1.add(1)
+  seq1.add(3)
+  seq1.add(5)
+  seq1.add(7)
+
+  var seq2: seq[int] = @[2, 4, 6]
+  var final = zip(seq1, seq2)
+
+  echo "Zip: ", $$(final)
+
+  #Test findWhere as a iterator
+
+  for itms in filter(seq1, testFindWhere):
+    echo "Filter Iterator: ", $$(itms)
+
+
+  #Test findWhere as a proc
+
+  var fullseq: seq[int] = filter(seq1, testFindWhere)
+
+  echo "Filter: ", $$(fullseq)
+
+  #Test findIt as a template
+
+  var finditval: seq[int] = filterIt(seq1, it!=5)
+
+  echo "FilterIt: ", $$(finditval)
+
+  var concatseq = concat(seq1,seq2)
+  echo "Concat: ", $$(concatseq)
+
+  var seq3 = @[1,2,3,4,5,5,5,7]
+  var dedupseq = deduplicate(seq3)
+  echo "Deduplicate: ", $$(dedupseq)
+  # bug #4973
+  type
+    SomeObj = object
+    OtherObj = object
+      field: SomeObj
+
+  let aSeq = @[OtherObj(field: SomeObj())]
+  let someObjSeq = aSeq.mapIt(it.field)
+  echo someObjSeq
+
+  block minmax:
+    doAssert minmax(@[0]) == (0, 0)
+    doAssert minmax(@[0, 1]) == (0, 1)
+    doAssert minmax(@[1, 0]) == (0, 1)
+    doAssert minmax(@[8,2,1,7,3,9,4,0,5]) == (0, 9)
+    echo "Minmax: ", $(minmax(concat(seq1, seq2)))
+
+
+when not defined(nimseqsv2):
+  block tshallowseq:
+    proc xxx() =
+      var x: seq[int] = @[1, 2, 3]
+      var y: seq[int]
+      system.shallowCopy(y, x)
+      y[1] = 42
+      doAssert y == @[1, 42, 3]
+      doAssert x == @[1, 42, 3]
+    xxx()
+
+
+  block tshallowemptyseq:
+    proc test() =
+      var nilSeq: seq[int] = @[]
+      var emptySeq: seq[int] = newSeq[int]()
+      block:
+        var t = @[1,2,3]
+        when defined(gcRefc):
+          shallow(nilSeq)
+        t = nilSeq
+        doAssert t == @[]
+      block:
+        var t = @[1,2,3]
+        when defined(gcRefc):
+          shallow(emptySeq)
+        t = emptySeq
+        doAssert t == @[]
+      block:
+        var t = @[1,2,3]
+        shallowCopy(t, nilSeq)
+        doAssert t == @[]
+      block:
+        var t = @[1,2,3]
+        shallowCopy(t, emptySeq)
+        doAssert t == @[]
+    test()
+
+
+import strutils
+block ttoseq:
+  for x in toSeq(countup(2, 6)):
+    stdout.write(x)
+  for x in items(toSeq(countup(2, 6))):
+    stdout.write(x)
+  var y: typeof("a b c".split)
+  y = "xzy"
+  stdout.write("\n")
+
+block tseqmapitchain:
+  doAssert @[101, 102] == [1, 2].mapIt(func (x: int): int = it + x).mapIt(it(100))
+
+
+for i in 0..100:
+  # fix #14655
+  var test = newSeqOfCap[uint32](1)
+  test.setLen(1)
+  doAssert test[0] == 0, $(test[0], i)
+
+
+# bug #22560
+doAssert len(newSeqOfCap[int](42)) == 0
+
+block: # bug #17197
+  type Matrix = seq[seq[int]]
+
+  proc needlemanWunsch(sequence1: string, sequence2: string, gap_penal: int8, match: int8, indel_penal: int8): bool =
+    let seq2_len = sequence2.len
+
+    var grid: Matrix
+    for i in sequence1:
+      grid.add(newSeqOfCap[seq[int]](seq2_len))
+    result = true
+
+  doAssert needlemanWunsch("ABC", "DEFG", 1, 2, 3)
diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim
new file mode 100644
index 000000000..95f9418a0
--- /dev/null
+++ b/tests/collections/ttables.nim
@@ -0,0 +1,457 @@
+discard """
+output: '''
+done tableadds
+And we get here
+1
+2
+3
+'''
+joinable: false
+targets: "c cpp js"
+"""
+
+# xxx wrap in a template to test in VM, see https://github.com/timotheecour/Nim/issues/534#issuecomment-769565033
+
+import hashes, sequtils, tables, algorithm
+
+proc sortedPairs[T](t: T): auto = toSeq(t.pairs).sorted
+template sortedItems(t: untyped): untyped = sorted(toSeq(t))
+
+block tableDollar:
+  # other tests should use `sortedPairs` to be robust to future table/hash
+  # implementation changes
+  doAssert ${1: 'a', 2: 'b'}.toTable in ["{1: 'a', 2: 'b'}", "{2: 'b', 1: 'a'}"]
+
+# test should not be joined because it takes too long.
+block tableadds:
+  proc main =
+    var tab = newTable[string, string]()
+    for i in 0..1000:
+      tab["key"] = "value " & $i
+
+  main()
+  echo "done tableadds"
+
+
+block tcounttable:
+  # bug #2625
+  const s_len = 32
+  var substr_counts: CountTable[string] = initCountTable[string]()
+  var my_string = "Hello, this is sadly broken for strings over 64 characters. Note that it *does* appear to work for short strings."
+  for i in 0..(my_string.len - s_len):
+    let s = my_string[i..i+s_len-1]
+    substr_counts[s] = 1
+    # substr_counts[s] = substr_counts[s] + 1  # Also breaks, + 2 as well, etc.
+    # substr_counts.inc(s)  # This works
+    #echo "Iteration ", i
+
+  echo "And we get here"
+
+
+block thashes:
+  # Test with int
+  block:
+    var t = initTable[int,int]()
+    t[0] = 42
+    t[1] = t[0] + 1
+    doAssert(t[0] == 42)
+    doAssert(t[1] == 43)
+    let t2 = {1: 1, 2: 2}.toTable
+    doAssert(t2[2] == 2)
+
+  # Test with char
+  block:
+    var t = initTable[char,int]()
+    t['0'] = 42
+    t['1'] = t['0'] + 1
+    doAssert(t['0'] == 42)
+    doAssert(t['1'] == 43)
+    let t2 = {'1': 1, '2': 2}.toTable
+    doAssert(t2['2'] == 2)
+
+  # Test with enum
+  block:
+    type
+      E = enum eA, eB, eC
+    var t = initTable[E,int]()
+    t[eA] = 42
+    t[eB] = t[eA] + 1
+    doAssert(t[eA] == 42)
+    doAssert(t[eB] == 43)
+    let t2 = {eA: 1, eB: 2}.toTable
+    doAssert(t2[eB] == 2)
+
+  # Test with range
+  block:
+    type
+      R = range[0..9]
+    var t = initTable[R,int]() # causes warning, why?
+    t[1] = 42 # causes warning, why?
+    t[2] = t[1] + 1
+    doAssert(t[1] == 42)
+    doAssert(t[2] == 43)
+    let t2 = {1.R: 1, 2.R: 2}.toTable
+    doAssert(t2[2.R] == 2)
+
+  # Test which combines the generics for tuples + ordinals
+  block:
+    type
+      E = enum eA, eB, eC
+    var t = initTable[(string, E, int, char), int]()
+    t[("a", eA, 0, '0')] = 42
+    t[("b", eB, 1, '1')] = t[("a", eA, 0, '0')] + 1
+    doAssert(t[("a", eA, 0, '0')] == 42)
+    doAssert(t[("b", eB, 1, '1')] == 43)
+    let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable
+    doAssert(t2[("b", eB, 1, '1')] == 2)
+
+  # Test to check if overloading is possible
+  # Unfortunately, this does not seem to work for int
+  # The same test with a custom hash(s: string) does
+  # work though.
+  block:
+    proc hash(x: int): Hash {.inline.} =
+      echo "overloaded hash"
+      result = x
+    var t = initTable[int, int]()
+    t[0] = 0
+
+  # Check hashability of all integer types (issue #5429)
+  block:
+    let intTables = (
+      newTable[int, string](),
+      newTable[int8, string](),
+      newTable[int16, string](),
+      newTable[int32, string](),
+      newTable[int64, string](),
+      newTable[uint, string](),
+      newTable[uint8, string](),
+      newTable[uint16, string](),
+      newTable[uint32, string](),
+      newTable[uint64, string](),
+    )
+  echo "1"
+
+
+block tindexby:
+  doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
+
+  var tbl1 = initTable[int, int]()
+  tbl1[1] = 1
+  tbl1[2] = 2
+  doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table"
+
+  type
+    TElem = object
+      foo: int
+      bar: string
+
+  let
+    elem1 = TElem(foo: 1, bar: "bar")
+    elem2 = TElem(foo: 2, bar: "baz")
+
+  var tbl2 = initTable[string, TElem]()
+  tbl2["bar"] = elem1
+  tbl2["baz"] = elem2
+  doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table"
+
+
+block tableconstr:
+  # Test if the new table constructor syntax works:
+
+  template ignoreExpr(e) =
+    discard
+
+  # test first class '..' syntactical citizen:
+  ignoreExpr x <> 2..4
+  # test table constructor:
+  ignoreExpr({:})
+  ignoreExpr({2: 3, "key": "value"})
+
+  # NEW:
+  doAssert 56 in 50..100
+
+  doAssert 56 in 0..60
+
+
+block ttables2:
+  proc TestHashIntInt() =
+    var tab = initTable[int,int]()
+    let n = 10
+    for i in 1..n:
+      tab[i] = i
+    for i in 1..n:
+      var x = tab[i]
+      if x != i : echo "not found ", i
+
+  TestHashIntInt()
+
+  # bug #2107
+
+  var delTab = initTable[int,int](4)
+
+  for i in 1..4:
+    delTab[i] = i
+    delTab.del(i)
+  delTab[5] = 5
+
+
+  echo "2"
+
+block tablesref:
+  const
+    data = {
+      "34": 123456, "12": 789,
+      "90": 343, "0": 34404,
+      "1": 344004, "2": 344774,
+      "3": 342244, "4": 3412344,
+      "5": 341232144, "6": 34214544,
+      "7": 3434544, "8": 344544,
+      "9": 34435644, "---00": 346677844,
+      "10": 34484, "11": 34474, "19": 34464,
+      "20": 34454, "30": 34141244, "40": 344114,
+      "50": 344490, "60": 344491, "70": 344492,
+      "80": 344497}
+
+    sorteddata = {
+      "---00": 346677844,
+      "0": 34404,
+      "1": 344004,
+      "10": 34484,
+      "11": 34474,
+      "12": 789,
+      "19": 34464,
+      "2": 344774, "20": 34454,
+      "3": 342244, "30": 34141244,
+      "34": 123456,
+      "4": 3412344, "40": 344114,
+      "5": 341232144, "50": 344490,
+      "6": 34214544, "60": 344491,
+      "7": 3434544, "70": 344492,
+      "8": 344544, "80": 344497,
+      "9": 34435644,
+      "90": 343}
+
+  block tableTest1:
+    var t = newTable[tuple[x, y: int], string]()
+    t[(0,0)] = "00"
+    t[(1,0)] = "10"
+    t[(0,1)] = "01"
+    t[(1,1)] = "11"
+    for x in 0..1:
+      for y in 0..1:
+        doAssert t[(x,y)] == $x & $y
+    doAssert t.sortedPairs ==
+      @[((x: 0, y: 0), "00"), ((x: 0, y: 1), "01"), ((x: 1, y: 0), "10"), ((x: 1, y: 1), "11")]
+
+  block tableTest2:
+    var t = newTable[string, float]()
+    t["test"] = 1.2345
+    t["111"] = 1.000043
+    t["123"] = 1.23
+    t.del("111")
+
+    t["012"] = 67.9
+    t["123"] = 1.5 # test overwriting
+
+    doAssert t["123"] == 1.5
+    try:
+      echo t["111"] # deleted
+    except KeyError:
+      discard
+    doAssert(not hasKey(t, "111"))
+    doAssert "111" notin t
+
+    for key, val in items(data): t[key] = val.toFloat
+    for key, val in items(data): doAssert t[key] == val.toFloat
+
+
+  block orderedTableTest1:
+    var t = newOrderedTable[string, int](2)
+    for key, val in items(data): t[key] = val
+    for key, val in items(data): doAssert t[key] == val
+    var i = 0
+    # `pairs` needs to yield in insertion order:
+    for key, val in pairs(t):
+      doAssert key == data[i][0]
+      doAssert val == data[i][1]
+      inc(i)
+
+    for key, val in mpairs(t): val = 99
+    for val in mvalues(t): doAssert val == 99
+
+  block countTableTest1:
+    var s = data.toTable
+    var t = newCountTable[string]()
+    var r = newCountTable[string]()
+    for x in [t, r]:
+      for k in s.keys:
+        x.inc(k)
+        doAssert x[k] == 1
+      x.inc("90", 3)
+      x.inc("12", 2)
+      x.inc("34", 1)
+    doAssert t.largest()[0] == "90"
+
+    t.sort()
+    r.sort(SortOrder.Ascending)
+    var ps1 = toSeq t.pairs
+    var ps2 = toSeq r.pairs
+    ps2.reverse()
+    for ps in [ps1, ps2]:
+      var i = 0
+      for (k, v) in ps:
+        case i
+        of 0: doAssert k == "90" and v == 4
+        of 1: doAssert k == "12" and v == 3
+        of 2: doAssert k == "34" and v == 2
+        else: break
+        inc i
+
+  block smallestLargestNamedFieldsTest: # bug #14918
+    const a = [7, 8, 8]
+
+    proc testNamedFields(t: CountTable | CountTableRef) =
+      doAssert t.smallest.key == 7
+      doAssert t.smallest.val == 1
+      doAssert t.largest.key == 8
+      doAssert t.largest.val == 2
+
+    let t1 = toCountTable(a)
+    testNamedFields(t1)
+    let t2 = newCountTable(a)
+    testNamedFields(t2)
+
+  block SyntaxTest:
+    var x = newTable[int, string]({:})
+    discard x
+
+  block nilTest:
+    var i, j: TableRef[int, int] = nil
+    doAssert i == j
+    j = newTable[int, int]()
+    doAssert i != j
+    doAssert j != i
+    i = newTable[int, int]()
+    doAssert i == j
+
+  proc orderedTableSortTest() =
+    var t = newOrderedTable[string, int](2)
+    for key, val in items(data): t[key] = val
+    for key, val in items(data): doAssert t[key] == val
+    proc cmper(x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)
+    t.sort(cmper)
+    var i = 0
+    # `pairs` needs to yield in sorted order:
+    for key, val in pairs(t):
+      doAssert key == sorteddata[i][0]
+      doAssert val == sorteddata[i][1]
+      inc(i)
+    t.sort(cmper, order=SortOrder.Descending)
+    i = 0
+    for key, val in pairs(t):
+      doAssert key == sorteddata[high(data)-i][0]
+      doAssert val == sorteddata[high(data)-i][1]
+      inc(i)
+
+    # check that lookup still works:
+    for key, val in pairs(t):
+      doAssert val == t[key]
+    # check that insert still works:
+    t["newKeyHere"] = 80
+
+  block anonZipTest:
+    let keys = @['a','b','c']
+    let values = @[1, 2, 3]
+    doAssert zip(keys, values).toTable.sortedPairs == @[('a', 1), ('b', 2), ('c', 3)]
+
+  block clearTableTest:
+    var t = newTable[string, float]()
+    t["test"] = 1.2345
+    t["111"] = 1.000043
+    t["123"] = 1.23
+    doAssert t.len() != 0
+    t.clear()
+    doAssert t.len() == 0
+
+  block clearOrderedTableTest:
+    var t = newOrderedTable[string, int](2)
+    for key, val in items(data): t[key] = val
+    doAssert t.len() != 0
+    t.clear()
+    doAssert t.len() == 0
+
+  block clearCountTableTest:
+    var t = newCountTable[string]()
+    t.inc("90", 3)
+    t.inc("12", 2)
+    t.inc("34", 1)
+    doAssert t.len() != 0
+    t.clear()
+    doAssert t.len() == 0
+
+  orderedTableSortTest()
+  echo "3"
+
+
+block: # https://github.com/nim-lang/Nim/issues/13496
+  template testDel(body) =
+    block:
+      body
+      when t is CountTable|CountTableRef:
+        t.inc(15, 1)
+        t.inc(19, 2)
+        t.inc(17, 3)
+        t.inc(150, 4)
+        t.del(150)
+      else:
+        t[15] = 1
+        t[19] = 2
+        t[17] = 3
+        t[150] = 4
+        t.del(150)
+      doAssert t.len == 3
+      doAssert sortedItems(t.values) == @[1, 2, 3]
+      doAssert sortedItems(t.keys) == @[15, 17, 19]
+      doAssert sortedPairs(t) == @[(15, 1), (17, 3), (19, 2)]
+      var s = newSeq[int]()
+      for v in t.values: s.add(v)
+      doAssert s.len == 3
+      doAssert sortedItems(s) == @[1, 2, 3]
+      when t is OrderedTable|OrderedTableRef:
+        doAssert toSeq(t.keys) == @[15, 19, 17]
+        doAssert toSeq(t.values) == @[1,2,3]
+        doAssert toSeq(t.pairs) == @[(15, 1), (19, 2), (17, 3)]
+
+  testDel(): (var t: Table[int, int])
+  testDel(): (let t = newTable[int, int]())
+  testDel(): (var t: OrderedTable[int, int])
+  testDel(): (let t = newOrderedTable[int, int]())
+  testDel(): (var t: CountTable[int])
+  testDel(): (let t = newCountTable[int]())
+
+
+block testNonPowerOf2:
+  var a = initTable[int, int](7)
+  a[1] = 10
+  doAssert a[1] == 10
+
+  var b = initTable[int, int](9)
+  b[1] = 10
+  doAssert b[1] == 10
+
+block emptyOrdered:
+  var t1: OrderedTable[int, string]
+  var t2: OrderedTable[int, string]
+  doAssert t1 == t2
+
+block: # Table[ref, int]
+  type A = ref object
+    x: int
+  var t: OrderedTable[A, int]
+  let a1 = A(x: 3)
+  let a2 = A(x: 3)
+  t[a1] = 10
+  t[a2] = 11
+  doAssert t[a1] == 10
+  doAssert t[a2] == 11
diff --git a/tests/collections/ttablesthreads.nim b/tests/collections/ttablesthreads.nim
new file mode 100644
index 000000000..2a4e1bf42
--- /dev/null
+++ b/tests/collections/ttablesthreads.nim
@@ -0,0 +1,276 @@
+discard """
+  cmd: "nim c --threads:on $file"
+  output: '''true'''
+"""
+
+import hashes, tables, sharedtables, algorithm, sequtils
+
+proc sortedPairs[T](t: T): auto = toSeq(t.pairs).sorted
+
+const
+  data = {
+    "34": 123456, "12": 789,
+    "90": 343, "0": 34404,
+    "1": 344004, "2": 344774,
+    "3": 342244, "4": 3412344,
+    "5": 341232144, "6": 34214544,
+    "7": 3434544, "8": 344544,
+    "9": 34435644, "---00": 346677844,
+    "10": 34484, "11": 34474, "19": 34464,
+    "20": 34454, "30": 34141244, "40": 344114,
+    "50": 344490, "60": 344491, "70": 344492,
+    "80": 344497}
+
+  sorteddata = {
+    "---00": 346677844,
+    "0": 34404,
+    "1": 344004,
+    "10": 34484,
+    "11": 34474,
+    "12": 789,
+    "19": 34464,
+    "2": 344774, "20": 34454,
+    "3": 342244, "30": 34141244,
+    "34": 123456,
+    "4": 3412344, "40": 344114,
+    "5": 341232144, "50": 344490,
+    "6": 34214544, "60": 344491,
+    "7": 3434544, "70": 344492,
+    "8": 344544, "80": 344497,
+    "9": 34435644,
+    "90": 343}
+
+block tableTest1:
+  var t = initTable[tuple[x, y: int], string]()
+  t[(0,0)] = "00"
+  t[(1,0)] = "10"
+  t[(0,1)] = "01"
+  t[(1,1)] = "11"
+  for x in 0..1:
+    for y in 0..1:
+      doAssert t[(x,y)] == $x & $y
+  doAssert t.sortedPairs == @[((x: 0, y: 0), "00"), ((x: 0, y: 1), "01"), ((x: 1, y: 0), "10"), ((x: 1, y: 1), "11")]
+
+block tableTest2:
+  var t = initTable[string, float]()
+  t["test"] = 1.2345
+  t["111"] = 1.000043
+  t["123"] = 1.23
+  t.del("111")
+
+  t["012"] = 67.9
+  t["123"] = 1.5 # test overwriting
+
+  doAssert t["123"] == 1.5
+  try:
+    echo t["111"] # deleted
+  except KeyError:
+    discard
+  doAssert(not hasKey(t, "111"))
+
+  doAssert "123" in t
+  doAssert("111" notin t)
+
+  for key, val in items(data): t[key] = val.toFloat
+  for key, val in items(data): doAssert t[key] == val.toFloat
+
+  doAssert(not t.hasKeyOrPut("456", 4.0))     # test absent key
+  doAssert t.hasKeyOrPut("012", 3.0)          # test present key
+  var x = t.mgetOrPut("111", 1.5)           # test absent key
+  x = x * 2
+  doAssert x == 3.0
+  x = t.mgetOrPut("test", 1.5)              # test present key
+  x = x * 2
+  doAssert x == 2 * 1.2345
+
+block orderedTableTest1:
+  var t = initOrderedTable[string, int](2)
+  for key, val in items(data): t[key] = val
+  for key, val in items(data): doAssert t[key] == val
+  var i = 0
+  # `pairs` needs to yield in insertion order:
+  for key, val in pairs(t):
+    doAssert key == data[i][0]
+    doAssert val == data[i][1]
+    inc(i)
+
+  for key, val in mpairs(t): val = 99
+  for val in mvalues(t): doAssert val == 99
+
+block orderedTableTest2:
+  var
+    s = initOrderedTable[string, int]()
+    t = initOrderedTable[string, int]()
+  doAssert s == t
+  for key, val in items(data): t[key] = val
+  doAssert s != t
+  for key, val in items(sorteddata): s[key] = val
+  doAssert s != t
+  t.clear()
+  doAssert s != t
+  for key, val in items(sorteddata): t[key] = val
+  doAssert s == t
+
+block countTableTest1:
+  var s = data.toTable
+  var t = initCountTable[string]()
+
+  for k in s.keys: t.inc(k)
+  for k in t.keys: doAssert t[k] == 1
+  t.inc("90", 3)
+  t.inc("12", 2)
+  t.inc("34", 1)
+  doAssert t.largest()[0] == "90"
+
+  t.sort()
+  var i = 0
+  for k, v in t.pairs:
+    case i
+    of 0: doAssert k == "90" and v == 4
+    of 1: doAssert k == "12" and v == 3
+    of 2: doAssert k == "34" and v == 2
+    else: break
+    inc i
+
+block countTableTest2:
+  var
+    s = initCountTable[int]()
+    t = initCountTable[int]()
+  doAssert s == t
+  s.inc(1)
+  doAssert s != t
+  t.inc(2)
+  doAssert s != t
+  t.inc(1)
+  doAssert s != t
+  s.inc(2)
+  doAssert s == t
+  s.inc(1)
+  doAssert s != t
+  t.inc(1)
+  doAssert s == t
+
+block mpairsTableTest1:
+  var t = initTable[string, int]()
+  t["a"] = 1
+  t["b"] = 2
+  t["c"] = 3
+  t["d"] = 4
+  for k, v in t.mpairs:
+    if k == "a" or k == "c":
+      v = 9
+
+  for k, v in t.pairs:
+    if k == "a" or k == "c":
+      doAssert v == 9
+    else:
+      doAssert v != 1 and v != 3
+
+block SyntaxTest:
+  var x = toTable[int, string]({:})
+
+block zeroHashKeysTest:
+  proc doZeroHashValueTest[T, K, V](t: T, nullHashKey: K, value: V) =
+    let initialLen = t.len
+    var testTable = t
+    testTable[nullHashKey] = value
+    doAssert testTable[nullHashKey] == value
+    doAssert testTable.len == initialLen + 1
+    testTable.del(nullHashKey)
+    doAssert testTable.len == initialLen
+
+  # with empty table
+  doZeroHashValueTest(toTable[int,int]({:}), 0, 42)
+  doZeroHashValueTest(toTable[string,int]({:}), "", 23)
+  doZeroHashValueTest(toOrderedTable[int,int]({:}), 0, 42)
+  doZeroHashValueTest(toOrderedTable[string,int]({:}), "", 23)
+
+  # with non-empty table
+  doZeroHashValueTest(toTable[int,int]({1:2}), 0, 42)
+  doZeroHashValueTest(toTable[string,string]({"foo": "bar"}), "", "zero")
+  doZeroHashValueTest(toOrderedTable[int,int]({3:4}), 0, 42)
+  doZeroHashValueTest(toOrderedTable[string,string]({"egg": "sausage"}),
+      "", "spam")
+
+block clearTableTest:
+  var t = data.toTable
+  doAssert t.len() != 0
+  t.clear()
+  doAssert t.len() == 0
+
+block clearOrderedTableTest:
+  var t = data.toOrderedTable
+  doAssert t.len() != 0
+  t.clear()
+  doAssert t.len() == 0
+
+block clearCountTableTest:
+  var t = initCountTable[string]()
+  t.inc("90", 3)
+  t.inc("12", 2)
+  t.inc("34", 1)
+  doAssert t.len() != 0
+  t.clear()
+  doAssert t.len() == 0
+
+block withKeyTest:
+  var t: SharedTable[int, int]
+  t.init()
+  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
+    doAssert(v == 0)
+    pairExists = true
+    v = 42
+  doAssert(t.mget(1) == 42)
+  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
+    doAssert(v == 42)
+    pairExists = false
+  try:
+    discard t.mget(1)
+    doAssert(false, "KeyError expected")
+  except KeyError:
+    discard
+  t.withKey(2) do (k: int, v: var int, pairExists: var bool):
+    pairExists = false
+  try:
+    discard t.mget(2)
+    doAssert(false, "KeyError expected")
+  except KeyError:
+    discard
+
+block takeTest:
+  var t = initTable[string, int]()
+  t["key"] = 123
+
+  var val = 0
+  doAssert(t.take("key", val))
+  doAssert(val == 123)
+
+  val = -1
+  doAssert(not t.take("key", val))
+  doAssert(val == -1)
+
+  doAssert(not t.take("otherkey", val))
+  doAssert(val == -1)
+
+proc orderedTableSortTest() =
+  var t = initOrderedTable[string, int](2)
+  for key, val in items(data): t[key] = val
+  for key, val in items(data): doAssert t[key] == val
+  t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key))
+  var i = 0
+  # `pairs` needs to yield in sorted order:
+  for key, val in pairs(t):
+    doAssert key == sorteddata[i][0]
+    doAssert val == sorteddata[i][1]
+    inc(i)
+
+  # check that lookup still works:
+  for key, val in pairs(t):
+    doAssert val == t[key]
+  # check that insert still works:
+  t["newKeyHere"] = 80
+
+
+orderedTableSortTest()
+echo "true"
+