improve tests for collections (#16328)

* improve tests for collections

* remove remaining code blocks in deques.nim

* improve runnableExamples
This commit is contained in:
Timothee Cour
2020-12-12 00:33:29 -08:00
committed by GitHub
parent 0b73106ccf
commit b1c232aca1
6 changed files with 227 additions and 242 deletions

View File

@@ -18,35 +18,32 @@
##
## As such, a check to see if the deque is empty is needed before any
## access, unless your program logic guarantees it indirectly.
##
## .. code-block:: Nim
## import deques
##
## var a = initDeque[int]()
##
## doAssertRaises(IndexDefect, echo a[0])
##
## for i in 1 .. 5:
## a.addLast(10*i)
## assert $a == "[10, 20, 30, 40, 50]"
##
## assert a.peekFirst == 10
## assert a.peekLast == 50
## assert len(a) == 5
##
## assert a.popFirst == 10
## assert a.popLast == 50
## assert len(a) == 3
##
## a.addFirst(11)
## a.addFirst(22)
## a.addFirst(33)
## assert $a == "[33, 22, 11, 20, 30, 40]"
##
## a.shrink(fromFirst = 1, fromLast = 2)
## assert $a == "[22, 11, 20]"
##
##
runnableExamples:
var a = initDeque[int]()
doAssertRaises(IndexDefect, echo a[0])
for i in 1 .. 5:
a.addLast(10*i)
assert $a == "[10, 20, 30, 40, 50]"
assert a.peekFirst == 10
assert a.peekLast == 50
assert len(a) == 5
assert a.popFirst == 10
assert a.popLast == 50
assert len(a) == 3
a.addFirst(11)
a.addFirst(22)
a.addFirst(33)
assert $a == "[33, 22, 11, 20, 30, 40]"
a.shrink(fromFirst = 1, fromLast = 2)
assert $a == "[22, 11, 20]"
## **See also:**
## * `lists module <lists.html>`_ for singly and doubly linked lists and rings
## * `channels module <channels.html>`_ for inter-thread communication
@@ -211,21 +208,14 @@ proc `[]=`*[T](deq: var Deque[T], i: BackwardsIndex, x: T) {.inline.} =
iterator items*[T](deq: Deque[T]): T =
## Yields every element of `deq`.
##
## **Examples:**
##
## .. code-block::
## var a = initDeque[int]()
## for i in 1 .. 3:
## a.addLast(10*i)
##
## for x in a: # the same as: for x in items(a):
## echo x
##
## # 10
## # 20
## # 30
##
runnableExamples:
var a = initDeque[int]()
for i in 1 .. 3:
a.addLast(10*i)
from sugar import collect
doAssert collect(for x in a: x) == [10, 20, 30]
# same as above:
doAssert collect(for x in items(a): x) == [10, 20, 30]
var i = deq.head
for c in 0 ..< deq.count:
yield deq.data[i]
@@ -249,21 +239,12 @@ iterator mitems*[T](deq: var Deque[T]): var T =
iterator pairs*[T](deq: Deque[T]): tuple[key: int, val: T] =
## Yields every (position, value) of `deq`.
##
## **Examples:**
##
## .. code-block::
## var a = initDeque[int]()
## for i in 1 .. 3:
## a.addLast(10*i)
##
## for k, v in pairs(a):
## echo "key: ", k, ", value: ", v
##
## # key: 0, value: 10
## # key: 1, value: 20
## # key: 2, value: 30
##
runnableExamples:
var a = initDeque[int]()
for i in 1 .. 3:
a.addLast(10*i)
from sugar import collect
doAssert collect(for k, v in pairs(a): (k, v)) == @[(0, 10), (1, 20), (2, 30)]
var i = deq.head
for c in 0 ..< deq.count:
yield (c, deq.data[i])
@@ -274,10 +255,11 @@ proc contains*[T](deq: Deque[T], item: T): bool {.inline.} =
##
## Usually used via the ``in`` operator.
## It is the equivalent of ``deq.find(item) >= 0``.
##
## .. code-block:: Nim
## if x in q:
## assert q.contains(x)
runnableExamples:
var q = [7, 9].toDeque
assert 7 in q
assert q.contains 7
assert 8 notin q
for e in deq:
if e == item: return true
return false

View File

@@ -1,9 +1,10 @@
discard """
output: ""
targets: "c js"
"""
import sets, tables, deques, lists, critbits, sequtils
# see also: tdeques, tlists, tcritbits
import sets, tables, sequtils
block tapply:
var x = @[1, 2, 3]
@@ -12,19 +13,6 @@ block tapply:
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.
@@ -75,6 +63,8 @@ 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"}"""
@@ -83,55 +73,6 @@ else:
let tabStr = $({"1": 1, "2": 2}.toTable)
doAssert (tabStr == """{"2": 2, "1": 1}""" or tabStr == """{"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 = ""

View File

@@ -1,3 +1,7 @@
discard """
targets: "c js"
"""
import std/[sequtils,critbits]
template main =
@@ -65,5 +69,19 @@ template main =
discard strings.containsOrIncl("foo", 3)
doAssert strings["foo"] == 3
block tcritbitsToString:
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'}"""
main()
static: main()

View File

@@ -1,111 +0,0 @@
import deques
var deq = initDeque[int](1)
deq.addLast(4)
deq.addFirst(9)
deq.addFirst(123)
var first = deq.popFirst()
deq.addLast(56)
assert(deq.peekLast() == 56)
deq.addLast(6)
assert(deq.peekLast() == 6)
var second = deq.popFirst()
deq.addLast(789)
assert(deq.peekLast() == 789)
assert first == 123
assert second == 9
assert($deq == "[4, 56, 6, 789]")
assert deq == [4, 56, 6, 789].toDeque
assert deq[0] == deq.peekFirst and deq.peekFirst == 4
#assert deq[^1] == deq.peekLast and deq.peekLast == 789
deq[0] = 42
deq[deq.len - 1] = 7
assert 6 in deq and 789 notin deq
assert deq.find(6) >= 0
assert deq.find(789) < 0
block:
var d = initDeque[int](1)
d.addLast 7
d.addLast 8
d.addLast 10
d.addFirst 5
d.addFirst 2
d.addFirst 1
d.addLast 20
d.shrink(fromLast = 2)
doAssert($d == "[1, 2, 5, 7, 8]")
d.shrink(2, 1)
doAssert($d == "[5, 7]")
d.shrink(2, 2)
doAssert d.len == 0
for i in -2 .. 10:
if i in deq:
assert deq.contains(i) and deq.find(i) >= 0
else:
assert(not deq.contains(i) and deq.find(i) < 0)
when compileOption("boundChecks"):
try:
echo deq[99]
assert false
except IndexDefect:
discard
try:
assert deq.len == 4
for i in 0 ..< 5: deq.popFirst()
assert false
except IndexDefect:
discard
# grabs some types of resize error.
deq = initDeque[int]()
for i in 1 .. 4: deq.addLast i
deq.popFirst()
deq.popLast()
for i in 5 .. 8: deq.addFirst i
assert $deq == "[8, 7, 6, 5, 2, 3]"
# Similar to proc from the documentation example
proc foo(a, b: Positive) = # assume random positive values for `a` and `b`.
var deq = initDeque[int]()
assert deq.len == 0
for i in 1 .. a: deq.addLast i
if b < deq.len: # checking before indexed access.
assert deq[b] == b + 1
# The following two lines don't need any checking on access due to the logic
# of the program, but that would not be the case if `a` could be 0.
assert deq.peekFirst == 1
assert deq.peekLast == a
while deq.len > 0: # checking if the deque is empty
assert deq.popFirst() > 0
#foo(0,0)
foo(8, 5)
foo(10, 9)
foo(1, 1)
foo(2, 1)
foo(1, 5)
foo(3, 2)
import sets
block t13310:
proc main() =
var q = initDeque[HashSet[int16]](2)
q.addFirst([1'i16].toHashSet)
q.addFirst([2'i16].toHashSet)
q.addFirst([3'i16].toHashSet)
assert $q == "[{3}, {2}, {1}]"
static:
main()

139
tests/stdlib/tdeques.nim Normal file
View File

@@ -0,0 +1,139 @@
discard """
targets: "c js"
"""
import std/deques
block:
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:
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']"
block:
var deq = initDeque[int](1)
deq.addLast(4)
deq.addFirst(9)
deq.addFirst(123)
var first = deq.popFirst()
deq.addLast(56)
assert(deq.peekLast() == 56)
deq.addLast(6)
assert(deq.peekLast() == 6)
var second = deq.popFirst()
deq.addLast(789)
assert(deq.peekLast() == 789)
assert first == 123
assert second == 9
assert($deq == "[4, 56, 6, 789]")
assert deq == [4, 56, 6, 789].toDeque
assert deq[0] == deq.peekFirst and deq.peekFirst == 4
#assert deq[^1] == deq.peekLast and deq.peekLast == 789
deq[0] = 42
deq[deq.len - 1] = 7
assert 6 in deq and 789 notin deq
assert deq.find(6) >= 0
assert deq.find(789) < 0
block:
var d = initDeque[int](1)
d.addLast 7
d.addLast 8
d.addLast 10
d.addFirst 5
d.addFirst 2
d.addFirst 1
d.addLast 20
d.shrink(fromLast = 2)
doAssert($d == "[1, 2, 5, 7, 8]")
d.shrink(2, 1)
doAssert($d == "[5, 7]")
d.shrink(2, 2)
doAssert d.len == 0
for i in -2 .. 10:
if i in deq:
assert deq.contains(i) and deq.find(i) >= 0
else:
assert(not deq.contains(i) and deq.find(i) < 0)
when compileOption("boundChecks"):
try:
echo deq[99]
assert false
except IndexDefect:
discard
try:
assert deq.len == 4
for i in 0 ..< 5: deq.popFirst()
assert false
except IndexDefect:
discard
# grabs some types of resize error.
deq = initDeque[int]()
for i in 1 .. 4: deq.addLast i
deq.popFirst()
deq.popLast()
for i in 5 .. 8: deq.addFirst i
assert $deq == "[8, 7, 6, 5, 2, 3]"
# Similar to proc from the documentation example
proc foo(a, b: Positive) = # assume random positive values for `a` and `b`.
var deq = initDeque[int]()
assert deq.len == 0
for i in 1 .. a: deq.addLast i
if b < deq.len: # checking before indexed access.
assert deq[b] == b + 1
# The following two lines don't need any checking on access due to the logic
# of the program, but that would not be the case if `a` could be 0.
assert deq.peekFirst == 1
assert deq.peekLast == a
while deq.len > 0: # checking if the deque is empty
assert deq.popFirst() > 0
#foo(0,0)
foo(8, 5)
foo(10, 9)
foo(1, 1)
foo(2, 1)
foo(1, 5)
foo(3, 2)
import sets
block t13310:
proc main() =
var q = initDeque[HashSet[int16]](2)
q.addFirst([1'i16].toHashSet)
q.addFirst([2'i16].toHashSet)
q.addFirst([3'i16].toHashSet)
assert $q == "[{3}, {2}, {1}]"
static:
main()

View File

@@ -1,5 +1,5 @@
discard """
output: '''true'''
targets: "c js"
"""
import lists
@@ -62,6 +62,22 @@ block DoublyLinkedRingTest1:
assert($L == "[]")
assert(4 notin L)
echo "true"
block tlistsToString:
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']"""