123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- discard """
- output: '''
- done tableadds
- And we get here
- 1
- 2
- 3
- '''
- joinable: false
- targets: "c cpp js"
- matrix: "-d:nimEnableHashRef"
- """
- # 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 = 100_000
- for i in 1..n:
- tab[i] = i
- for i in 1..n:
- var x = tab[i]
- if x != i : echo "not found ", i
- proc run1() =
- for i in 1 .. 50:
- 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 "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
|