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/tableadds.nim13
-rw-r--r--tests/collections/tapply.nim11
-rw-r--r--tests/collections/tcollections.nim56
-rw-r--r--tests/collections/tcounttable.nim19
-rw-r--r--tests/collections/tdeques.nim17
-rw-r--r--tests/collections/thashes.nim90
-rw-r--r--tests/collections/tindexby.nim22
-rw-r--r--tests/collections/tmapit.nim33
-rw-r--r--tests/collections/tsets.nim5
-rw-r--r--tests/collections/ttableconstr.nim16
-rw-r--r--tests/collections/ttables.nim642
-rw-r--r--tests/collections/ttables2.nim30
-rw-r--r--tests/collections/ttablesref.nim171
-rw-r--r--tests/collections/ttablesref2.nim20
-rw-r--r--tests/collections/ttablesthreads.nim275
15 files changed, 704 insertions, 716 deletions
diff --git a/tests/collections/tableadds.nim b/tests/collections/tableadds.nim
deleted file mode 100644
index 71f1fad7d..000000000
--- a/tests/collections/tableadds.nim
+++ /dev/null
@@ -1,13 +0,0 @@
-discard """
-  output: '''done'''
-"""
-
-import tables
-
-proc main =
-  var tab = newTable[string, string]()
-  for i in 0..1000:
-    tab.add "key", "value " & $i
-
-main()
-echo "done"
diff --git a/tests/collections/tapply.nim b/tests/collections/tapply.nim
deleted file mode 100644
index 2b7464216..000000000
--- a/tests/collections/tapply.nim
+++ /dev/null
@@ -1,11 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import sequtils
-
-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)
-echo x == @[5111, 5112, 5113]
diff --git a/tests/collections/tcollections.nim b/tests/collections/tcollections.nim
new file mode 100644
index 000000000..ff6673bba
--- /dev/null
+++ b/tests/collections/tcollections.nim
@@ -0,0 +1,56 @@
+discard """
+  file: "tcollections.nim"
+  output: '''
+'''
+"""
+
+import deques, 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 tdeques:
+  proc index(self: Deque[int], idx: Natural): int =
+    self[idx]
+
+  proc main =
+    var testDeque = initDeque[int]()
+    testDeque.addFirst(1)
+    assert testDeque.index(0) == 1
+
+  main()
+
+
+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"]
diff --git a/tests/collections/tcounttable.nim b/tests/collections/tcounttable.nim
deleted file mode 100644
index ebbb1c8e5..000000000
--- a/tests/collections/tcounttable.nim
+++ /dev/null
@@ -1,19 +0,0 @@
-discard """
-  output: "And we get here"
-"""
-
-# bug #2625
-
-const s_len = 32
-
-import tables
-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"
diff --git a/tests/collections/tdeques.nim b/tests/collections/tdeques.nim
deleted file mode 100644
index 664ce4324..000000000
--- a/tests/collections/tdeques.nim
+++ /dev/null
@@ -1,17 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import deques
-
-
-proc index(self: Deque[int], idx: Natural): int =
-  self[idx]
-
-proc main =
-  var testDeque = initDeque[int]()
-  testDeque.addFirst(1)
-  assert testDeque.index(0) == 1
-
-main()
-echo "true"
diff --git a/tests/collections/thashes.nim b/tests/collections/thashes.nim
deleted file mode 100644
index 5cc3cc8bb..000000000
--- a/tests/collections/thashes.nim
+++ /dev/null
@@ -1,90 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import tables
-from hashes import Hash
-
-# Test with int
-block:
-  var t = initTable[int,int]()
-  t[0] = 42
-  t[1] = t[0] + 1
-  assert(t[0] == 42)
-  assert(t[1] == 43)
-  let t2 = {1: 1, 2: 2}.toTable
-  assert(t2[2] == 2)
-
-# Test with char
-block:
-  var t = initTable[char,int]()
-  t['0'] = 42
-  t['1'] = t['0'] + 1
-  assert(t['0'] == 42)
-  assert(t['1'] == 43)
-  let t2 = {'1': 1, '2': 2}.toTable
-  assert(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
-  assert(t[eA] == 42)
-  assert(t[eB] == 43)
-  let t2 = {eA: 1, eB: 2}.toTable
-  assert(t2[eB] == 2)
-
-# Test with range
-block:
-  type
-    R = range[1..10]
-  var t = initTable[R,int]() # causes warning, why?
-  t[1] = 42 # causes warning, why?
-  t[2] = t[1] + 1
-  assert(t[1] == 42)
-  assert(t[2] == 43)
-  let t2 = {1.R: 1, 2.R: 2}.toTable
-  assert(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
-  assert(t[("a", eA, 0, '0')] == 42)
-  assert(t[("b", eB, 1, '1')] == 43)
-  let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable
-  assert(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 "true"
diff --git a/tests/collections/tindexby.nim b/tests/collections/tindexby.nim
deleted file mode 100644
index 88c0b263e..000000000
--- a/tests/collections/tindexby.nim
+++ /dev/null
@@ -1,22 +0,0 @@
-import tables
-
-doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
-
-var tbl1 = initTable[int, int]()
-tbl1.add(1,1)
-tbl1.add(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.add("bar", elem1)
-tbl2.add("baz", elem2)
-doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table"
diff --git a/tests/collections/tmapit.nim b/tests/collections/tmapit.nim
deleted file mode 100644
index b2afa9429..000000000
--- a/tests/collections/tmapit.nim
+++ /dev/null
@@ -1,33 +0,0 @@
-discard """
-  output: '''true
-true'''
-"""
-
-import sequtils
-
-var x = @[1, 2, 3]
-# This mapIt call will run with preallocation because ``len`` is available.
-var y = x.mapIt($(it+10))
-echo 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))
-echo r == @["10", "11", "12", "13", "14"]
diff --git a/tests/collections/tsets.nim b/tests/collections/tsets.nim
index 61e14260a..cd4401511 100644
--- a/tests/collections/tsets.nim
+++ b/tests/collections/tsets.nim
@@ -1,6 +1,5 @@
-import sets
-import hashes
-import algorithm
+import sets, hashes, algorithm
+
 
 block setEquality:
   var
diff --git a/tests/collections/ttableconstr.nim b/tests/collections/ttableconstr.nim
deleted file mode 100644
index 884378a76..000000000
--- a/tests/collections/ttableconstr.nim
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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:
-assert 56 in 50..100
-
-assert 56 in ..60
-
diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim
index 7fe4c79b1..cb31a8652 100644
--- a/tests/collections/ttables.nim
+++ b/tests/collections/ttables.nim
@@ -1,275 +1,375 @@
 discard """
-  cmd: "nim c --threads:on $file"
-  output: '''true'''
+  file: "ttables.nim"
+  output: '''
+done
+And we get here
+true
+true
+true
+true
+'''
 """
-
-import hashes, tables, sharedtables
-
-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:
-      assert t[(x,y)] == $x & $y
-  assert($t ==
-    "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (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
-
-  assert t["123"] == 1.5
-  try:
-    echo t["111"] # deleted
-  except KeyError:
-    discard
-  assert(not hasKey(t, "111"))
-
-  assert "123" in t
-  assert("111" notin t)
-
-  for key, val in items(data): t[key] = val.toFloat
-  for key, val in items(data): assert t[key] == val.toFloat
-
-  assert(not t.hasKeyOrPut("456", 4.0))     # test absent key
-  assert t.hasKeyOrPut("012", 3.0)          # test present key
-  var x = t.mgetOrPut("111", 1.5)           # test absent key
-  x = x * 2
-  assert x == 3.0
-  x = t.mgetOrPut("test", 1.5)              # test present key
-  x = x * 2
-  assert 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): assert t[key] == val
-  var i = 0
-  # `pairs` needs to yield in insertion order:
-  for key, val in pairs(t):
-    assert key == data[i][0]
-    assert val == data[i][1]
-    inc(i)
-
-  for key, val in mpairs(t): val = 99
-  for val in mvalues(t): assert val == 99
-
-block orderedTableTest2:
-  var
-    s = initOrderedTable[string, int]()
-    t = initOrderedTable[string, int]()
-  assert s == t
-  for key, val in items(data): t[key] = val
-  assert s != t
-  for key, val in items(sorteddata): s[key] = val
-  assert s != t
-  t.clear()
-  assert s != t
-  for key, val in items(sorteddata): t[key] = val
-  assert 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: assert t[k] == 1
-  t.inc("90", 3)
-  t.inc("12", 2)
-  t.inc("34", 1)
-  assert t.largest()[0] == "90"
-
-  t.sort()
-  var i = 0
-  for k, v in t.pairs:
-    case i
-    of 0: assert k == "90" and v == 4
-    of 1: assert k == "12" and v == 3
-    of 2: assert k == "34" and v == 2
-    else: break
-    inc i
-
-block countTableTest2:
-  var
-    s = initCountTable[int]()
-    t = initCountTable[int]()
-  assert s == t
-  s.inc(1)
-  assert s != t
-  t.inc(2)
-  assert s != t
-  t.inc(1)
-  assert s != t
-  s.inc(2)
-  assert s == t
-  s.inc(1)
-  assert s != t
-  t.inc(1)
-  assert 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":
-      assert v == 9
-    else:
-      assert 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
-    assert testTable[nullHashKey] == value
-    assert testTable.len == initialLen + 1
-    testTable.del(nullHashKey)
-    assert 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
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-block clearOrderedTableTest:
-  var t = data.toOrderedTable
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-block clearCountTableTest:
-  var t = initCountTable[string]()
-  t.inc("90", 3)
-  t.inc("12", 2)
-  t.inc("34", 1)
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-block withKeyTest:
-  var t: SharedTable[int, int]
-  t.init()
-  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
-    assert(v == 0)
-    pairExists = true
-    v = 42
-  assert(t.mget(1) == 42)
-  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
-    assert(v == 42)
-    pairExists = false
-  try:
-    discard t.mget(1)
-    assert(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)
-    assert(false, "KeyError expected")
-  except KeyError:
+import hashes, sequtils, tables
+
+
+block tableadds:
+  proc main =
+    var tab = newTable[string, string]()
+    for i in 0..1000:
+      tab.add "key", "value " & $i
+
+  main()
+  echo "done"
+
+
+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
+    assert(t[0] == 42)
+    assert(t[1] == 43)
+    let t2 = {1: 1, 2: 2}.toTable
+    assert(t2[2] == 2)
+
+  # Test with char
+  block:
+    var t = initTable[char,int]()
+    t['0'] = 42
+    t['1'] = t['0'] + 1
+    assert(t['0'] == 42)
+    assert(t['1'] == 43)
+    let t2 = {'1': 1, '2': 2}.toTable
+    assert(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
+    assert(t[eA] == 42)
+    assert(t[eB] == 43)
+    let t2 = {eA: 1, eB: 2}.toTable
+    assert(t2[eB] == 2)
+
+  # Test with range
+  block:
+    type
+      R = range[1..10]
+    var t = initTable[R,int]() # causes warning, why?
+    t[1] = 42 # causes warning, why?
+    t[2] = t[1] + 1
+    assert(t[1] == 42)
+    assert(t[2] == 43)
+    let t2 = {1.R: 1, 2.R: 2}.toTable
+    assert(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
+    assert(t[("a", eA, 0, '0')] == 42)
+    assert(t[("b", eB, 1, '1')] == 43)
+    let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable
+    assert(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 "true"
+
+
+block tindexby:
+  doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
+
+  var tbl1 = initTable[int, int]()
+  tbl1.add(1,1)
+  tbl1.add(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.add("bar", elem1)
+  tbl2.add("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
 
-block takeTest:
-  var t = initTable[string, int]()
-  t["key"] = 123
-
-  var val = 0
-  assert(t.take("key", val))
-  assert(val == 123)
-
-  val = -1
-  assert(not t.take("key", val))
-  assert(val == -1)
-
-  assert(not t.take("otherkey", val))
-  assert(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): assert 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"
-
+  # test first class '..' syntactical citizen:
+  ignoreExpr x <> 2..4
+  # test table constructor:
+  ignoreExpr({:})
+  ignoreExpr({2: 3, "key": "value"})
+
+  # NEW:
+  assert 56 in 50..100
+
+  assert 56 in ..60
+
+
+block ttables2:
+  proc TestHashIntInt() =
+    var tab = initTable[int,int]()
+    for i in 1..1_000_000:
+      tab[i] = i
+    for i in 1..1_000_000:
+      var x = tab[i]
+      if x != i : echo "not found ", i
+
+  proc run1() =         # occupied Memory stays constant, but
+    for i in 1 .. 50:   # aborts at run: 44 on win32 with 3.2GB with out of memory
+      TestHashIntInt()
+
+  # bug #2107
+
+  var delTab = initTable[int,int](4)
+
+  for i in 1..4:
+    delTab[i] = i
+    delTab.del(i)
+  delTab[5] = 5
+
+
+  run1()
+  echo "true"
+
+
+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:
+        assert t[(x,y)] == $x & $y
+    assert($t ==
+      "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (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
+
+    assert t["123"] == 1.5
+    try:
+      echo t["111"] # deleted
+    except KeyError:
+      discard
+    assert(not hasKey(t, "111"))
+    assert "111" notin t
+
+    for key, val in items(data): t[key] = val.toFloat
+    for key, val in items(data): assert 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): assert t[key] == val
+    var i = 0
+    # `pairs` needs to yield in insertion order:
+    for key, val in pairs(t):
+      assert key == data[i][0]
+      assert val == data[i][1]
+      inc(i)
+
+    for key, val in mpairs(t): val = 99
+    for val in mvalues(t): assert val == 99
+
+  block countTableTest1:
+    var s = data.toTable
+    var t = newCountTable[string]()
+    for k in s.keys: t.inc(k)
+    for k in t.keys: assert t[k] == 1
+    t.inc("90", 3)
+    t.inc("12", 2)
+    t.inc("34", 1)
+    assert t.largest()[0] == "90"
+
+    t.sort()
+    var i = 0
+    for k, v in t.pairs:
+      case i
+      of 0: assert k == "90" and v == 4
+      of 1: assert k == "12" and v == 3
+      of 2: assert k == "34" and v == 2
+      else: break
+      inc i
+
+  block SyntaxTest:
+    var x = newTable[int, string]({:})
+    discard x
+
+  block nilTest:
+    var i, j: TableRef[int, int] = nil
+    assert i == j
+    j = newTable[int, int]()
+    assert i != j
+    assert j != i
+    i = newTable[int, int]()
+    assert 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): assert 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
+
+  block anonZipTest:
+    let keys = @['a','b','c']
+    let values = @[1, 2, 3]
+    doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values)
+
+  block clearTableTest:
+    var t = newTable[string, float]()
+    t["test"] = 1.2345
+    t["111"] = 1.000043
+    t["123"] = 1.23
+    assert t.len() != 0
+    t.clear()
+    assert t.len() == 0
+
+  block clearOrderedTableTest:
+    var t = newOrderedTable[string, int](2)
+    for key, val in items(data): t[key] = val
+    assert t.len() != 0
+    t.clear()
+    assert t.len() == 0
+
+  block clearCountTableTest:
+    var t = newCountTable[string]()
+    t.inc("90", 3)
+    t.inc("12", 2)
+    t.inc("34", 1)
+    assert t.len() != 0
+    t.clear()
+    assert t.len() == 0
+
+  orderedTableSortTest()
+  echo "true"
+
+
+block tablesref2:
+  proc TestHashIntInt() =
+    var tab = newTable[int,int]()
+    for i in 1..1_000_000:
+      tab[i] = i
+    for i in 1..1_000_000:
+      var x = tab[i]
+      if x != i : echo "not found ", i
+
+  proc run1() =         # occupied Memory stays constant, but
+    for i in 1 .. 50:   # aborts at run: 44 on win32 with 3.2GB with out of memory
+      TestHashIntInt()
+
+  run1()
+  echo "true"
diff --git a/tests/collections/ttables2.nim b/tests/collections/ttables2.nim
deleted file mode 100644
index 6f3fa841a..000000000
--- a/tests/collections/ttables2.nim
+++ /dev/null
@@ -1,30 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import tables
-
-proc TestHashIntInt() =
-  var tab = initTable[int,int]()
-  for i in 1..1_000_000:
-    tab[i] = i
-  for i in 1..1_000_000:
-    var x = tab[i]
-    if x != i : echo "not found ", i
-
-proc run1() =         # occupied Memory stays constant, but
-  for i in 1 .. 50:   # aborts at run: 44 on win32 with 3.2GB with out of memory
-    TestHashIntInt()
-
-# bug #2107
-
-var delTab = initTable[int,int](4)
-
-for i in 1..4:
-  delTab[i] = i
-  delTab.del(i)
-delTab[5] = 5
-
-
-run1()
-echo "true"
diff --git a/tests/collections/ttablesref.nim b/tests/collections/ttablesref.nim
deleted file mode 100644
index a4030e0dc..000000000
--- a/tests/collections/ttablesref.nim
+++ /dev/null
@@ -1,171 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import hashes, tables, sequtils
-
-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:
-      assert t[(x,y)] == $x & $y
-  assert($t ==
-    "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (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
-
-  assert t["123"] == 1.5
-  try:
-    echo t["111"] # deleted
-  except KeyError:
-    discard
-  assert(not hasKey(t, "111"))
-  assert "111" notin t
-
-  for key, val in items(data): t[key] = val.toFloat
-  for key, val in items(data): assert 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): assert t[key] == val
-  var i = 0
-  # `pairs` needs to yield in insertion order:
-  for key, val in pairs(t):
-    assert key == data[i][0]
-    assert val == data[i][1]
-    inc(i)
-
-  for key, val in mpairs(t): val = 99
-  for val in mvalues(t): assert val == 99
-
-block countTableTest1:
-  var s = data.toTable
-  var t = newCountTable[string]()
-  for k in s.keys: t.inc(k)
-  for k in t.keys: assert t[k] == 1
-  t.inc("90", 3)
-  t.inc("12", 2)
-  t.inc("34", 1)
-  assert t.largest()[0] == "90"
-
-  t.sort()
-  var i = 0
-  for k, v in t.pairs:
-    case i
-    of 0: assert k == "90" and v == 4
-    of 1: assert k == "12" and v == 3
-    of 2: assert k == "34" and v == 2
-    else: break
-    inc i
-
-block SyntaxTest:
-  var x = newTable[int, string]({:})
-  discard x
-
-block nilTest:
-  var i, j: TableRef[int, int] = nil
-  assert i == j
-  j = newTable[int, int]()
-  assert i != j
-  assert j != i
-  i = newTable[int, int]()
-  assert 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): assert 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
-
-block anonZipTest:
-  let keys = @['a','b','c']
-  let values = @[1, 2, 3]
-  doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values)
-
-block clearTableTest:
-  var t = newTable[string, float]()
-  t["test"] = 1.2345
-  t["111"] = 1.000043
-  t["123"] = 1.23
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-block clearOrderedTableTest:
-  var t = newOrderedTable[string, int](2)
-  for key, val in items(data): t[key] = val
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-block clearCountTableTest:
-  var t = newCountTable[string]()
-  t.inc("90", 3)
-  t.inc("12", 2)
-  t.inc("34", 1)
-  assert t.len() != 0
-  t.clear()
-  assert t.len() == 0
-
-orderedTableSortTest()
-echo "true"
-
diff --git a/tests/collections/ttablesref2.nim b/tests/collections/ttablesref2.nim
deleted file mode 100644
index 939de2b84..000000000
--- a/tests/collections/ttablesref2.nim
+++ /dev/null
@@ -1,20 +0,0 @@
-discard """
-  output: '''true'''
-"""
-
-import tables
-
-proc TestHashIntInt() =
-  var tab = newTable[int,int]()
-  for i in 1..1_000_000:
-    tab[i] = i
-  for i in 1..1_000_000:
-    var x = tab[i]
-    if x != i : echo "not found ", i
-
-proc run1() =         # occupied Memory stays constant, but
-  for i in 1 .. 50:   # aborts at run: 44 on win32 with 3.2GB with out of memory
-    TestHashIntInt()
-
-run1()
-echo "true"
diff --git a/tests/collections/ttablesthreads.nim b/tests/collections/ttablesthreads.nim
new file mode 100644
index 000000000..7fe4c79b1
--- /dev/null
+++ b/tests/collections/ttablesthreads.nim
@@ -0,0 +1,275 @@
+discard """
+  cmd: "nim c --threads:on $file"
+  output: '''true'''
+"""
+
+import hashes, tables, sharedtables
+
+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:
+      assert t[(x,y)] == $x & $y
+  assert($t ==
+    "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (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
+
+  assert t["123"] == 1.5
+  try:
+    echo t["111"] # deleted
+  except KeyError:
+    discard
+  assert(not hasKey(t, "111"))
+
+  assert "123" in t
+  assert("111" notin t)
+
+  for key, val in items(data): t[key] = val.toFloat
+  for key, val in items(data): assert t[key] == val.toFloat
+
+  assert(not t.hasKeyOrPut("456", 4.0))     # test absent key
+  assert t.hasKeyOrPut("012", 3.0)          # test present key
+  var x = t.mgetOrPut("111", 1.5)           # test absent key
+  x = x * 2
+  assert x == 3.0
+  x = t.mgetOrPut("test", 1.5)              # test present key
+  x = x * 2
+  assert 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): assert t[key] == val
+  var i = 0
+  # `pairs` needs to yield in insertion order:
+  for key, val in pairs(t):
+    assert key == data[i][0]
+    assert val == data[i][1]
+    inc(i)
+
+  for key, val in mpairs(t): val = 99
+  for val in mvalues(t): assert val == 99
+
+block orderedTableTest2:
+  var
+    s = initOrderedTable[string, int]()
+    t = initOrderedTable[string, int]()
+  assert s == t
+  for key, val in items(data): t[key] = val
+  assert s != t
+  for key, val in items(sorteddata): s[key] = val
+  assert s != t
+  t.clear()
+  assert s != t
+  for key, val in items(sorteddata): t[key] = val
+  assert 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: assert t[k] == 1
+  t.inc("90", 3)
+  t.inc("12", 2)
+  t.inc("34", 1)
+  assert t.largest()[0] == "90"
+
+  t.sort()
+  var i = 0
+  for k, v in t.pairs:
+    case i
+    of 0: assert k == "90" and v == 4
+    of 1: assert k == "12" and v == 3
+    of 2: assert k == "34" and v == 2
+    else: break
+    inc i
+
+block countTableTest2:
+  var
+    s = initCountTable[int]()
+    t = initCountTable[int]()
+  assert s == t
+  s.inc(1)
+  assert s != t
+  t.inc(2)
+  assert s != t
+  t.inc(1)
+  assert s != t
+  s.inc(2)
+  assert s == t
+  s.inc(1)
+  assert s != t
+  t.inc(1)
+  assert 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":
+      assert v == 9
+    else:
+      assert 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
+    assert testTable[nullHashKey] == value
+    assert testTable.len == initialLen + 1
+    testTable.del(nullHashKey)
+    assert 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
+  assert t.len() != 0
+  t.clear()
+  assert t.len() == 0
+
+block clearOrderedTableTest:
+  var t = data.toOrderedTable
+  assert t.len() != 0
+  t.clear()
+  assert t.len() == 0
+
+block clearCountTableTest:
+  var t = initCountTable[string]()
+  t.inc("90", 3)
+  t.inc("12", 2)
+  t.inc("34", 1)
+  assert t.len() != 0
+  t.clear()
+  assert t.len() == 0
+
+block withKeyTest:
+  var t: SharedTable[int, int]
+  t.init()
+  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
+    assert(v == 0)
+    pairExists = true
+    v = 42
+  assert(t.mget(1) == 42)
+  t.withKey(1) do (k: int, v: var int, pairExists: var bool):
+    assert(v == 42)
+    pairExists = false
+  try:
+    discard t.mget(1)
+    assert(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)
+    assert(false, "KeyError expected")
+  except KeyError:
+    discard
+
+block takeTest:
+  var t = initTable[string, int]()
+  t["key"] = 123
+
+  var val = 0
+  assert(t.take("key", val))
+  assert(val == 123)
+
+  val = -1
+  assert(not t.take("key", val))
+  assert(val == -1)
+
+  assert(not t.take("otherkey", val))
+  assert(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): assert 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"
+