diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/async/tasyncdiscard.nim | 2 | ||||
-rw-r--r-- | tests/async/tasynctry.nim | 10 | ||||
-rw-r--r-- | tests/ccgbugs/tmissingvolatile.nim | 2 | ||||
-rw-r--r-- | tests/ccgbugs/twrong_string_asgn.nim | 2 | ||||
-rw-r--r-- | tests/closure/tdeeplynested.nim | 20 | ||||
-rw-r--r-- | tests/enum/tenum.nim | 6 | ||||
-rw-r--r-- | tests/float/tfloat4.nim | 32 | ||||
-rw-r--r-- | tests/float/tfloat5.nim | 15 | ||||
-rw-r--r-- | tests/float/tfloat6.nim | 21 | ||||
-rw-r--r-- | tests/float/tfloat7.nim | 26 | ||||
-rw-r--r-- | tests/gc/thavlak.nim | 457 | ||||
-rw-r--r-- | tests/gc/tlists.nim | 37 | ||||
-rw-r--r-- | tests/js/test2.nim | 13 | ||||
-rw-r--r-- | tests/js/testtojsstr.nim | 8 | ||||
-rw-r--r-- | tests/macros/tgettypeinst.nim | 122 | ||||
-rw-r--r-- | tests/parser/tdo.nim | 79 | ||||
-rw-r--r-- | tests/stdlib/tparscfg.nim | 58 | ||||
-rw-r--r-- | tests/stdlib/trstgen.nim | 139 | ||||
-rw-r--r-- | tests/template/t2do.nim | 7 | ||||
-rw-r--r-- | tests/testament/categories.nim | 3 | ||||
-rw-r--r-- | tests/trmacros/tstatic_t_bug.nim | 24 | ||||
-rw-r--r-- | tests/typerel/temptynode.nim | 16 |
22 files changed, 1052 insertions, 47 deletions
diff --git a/tests/async/tasyncdiscard.nim b/tests/async/tasyncdiscard.nim index 71aba29e2..e7c87ad42 100644 --- a/tests/async/tasyncdiscard.nim +++ b/tests/async/tasyncdiscard.nim @@ -36,4 +36,4 @@ proc main {.async.} = discard await g() echo 6 -asyncCheck main() +waitFor(main()) diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim index f77198e2e..5930f296f 100644 --- a/tests/async/tasynctry.nim +++ b/tests/async/tasynctry.nim @@ -48,7 +48,7 @@ proc catch() {.async.} = except OSError, EInvalidField: assert false -asyncCheck catch() +waitFor catch() proc test(): Future[bool] {.async.} = result = false @@ -92,13 +92,13 @@ proc test4(): Future[int] {.async.} = result = 2 var x = test() -assert x.read +assert x.waitFor() x = test2() -assert x.read +assert x.waitFor() var y = test3() -assert y.read == 2 +assert y.waitFor() == 2 y = test4() -assert y.read == 2 +assert y.waitFor() == 2 diff --git a/tests/ccgbugs/tmissingvolatile.nim b/tests/ccgbugs/tmissingvolatile.nim index 4d25e5c22..d61778ed4 100644 --- a/tests/ccgbugs/tmissingvolatile.nim +++ b/tests/ccgbugs/tmissingvolatile.nim @@ -1,7 +1,7 @@ discard """ output: "1" cmd: r"nim c --hints:on $options -d:release $file" - ccodecheck: "'NI volatile state;'" + ccodecheck: "'NI volatile state0;'" """ # bug #1539 diff --git a/tests/ccgbugs/twrong_string_asgn.nim b/tests/ccgbugs/twrong_string_asgn.nim index b62e70e7c..669b7f8f5 100644 --- a/tests/ccgbugs/twrong_string_asgn.nim +++ b/tests/ccgbugs/twrong_string_asgn.nim @@ -16,4 +16,4 @@ x.callback = proc () = finished = true -while not finished: discard +while not finished: poll() diff --git a/tests/closure/tdeeplynested.nim b/tests/closure/tdeeplynested.nim new file mode 100644 index 000000000..ddf4fa6a4 --- /dev/null +++ b/tests/closure/tdeeplynested.nim @@ -0,0 +1,20 @@ +discard """ + output: '''int: 108''' +""" + +# bug #4070 + +proc id(f: (proc())): auto = + return f + +proc foo(myinteger: int): (iterator(): int) = + return iterator(): int {.closure.} = + proc bar() = + proc kk() = + echo "int: ", myinteger + + kk() + + id(bar)() + +discard foo(108)() diff --git a/tests/enum/tenum.nim b/tests/enum/tenum.nim index b081212e6..6d9bdd539 100644 --- a/tests/enum/tenum.nim +++ b/tests/enum/tenum.nim @@ -6,3 +6,9 @@ type var en: E en = a + +# Bug #4066 +import macros +macro genEnum(): untyped = newNimNode(nnkEnumTy).add(newEmptyNode(), newIdentNode("geItem1")) +type GeneratedEnum = genEnum() +doAssert(type(geItem1) is GeneratedEnum) diff --git a/tests/float/tfloat4.nim b/tests/float/tfloat4.nim index 960c4e5f7..006b4d88f 100644 --- a/tests/float/tfloat4.nim +++ b/tests/float/tfloat4.nim @@ -1,3 +1,8 @@ +discard """ + file: "tfloat4.nim" + output: "passed all tests." + exitcode: 0 +""" import math, strutils proc c_sprintf(buf, fmt: cstring) {.importc:"sprintf", header: "<stdio.h>", varargs.} @@ -11,8 +16,9 @@ proc floatToStr(f: float64): string = return add(result, ch) + let testFloats = [ - "0", "-1", "1", "1.", ".3", "3.3", "-.3", "-99.99", + "0", "-0", "0.", "0.0", "-0.", "-0.0", "-1", "1", "1.", ".3", "3.3", "-.3", "-99.99", "1.1e10", "-2e100", "1.234e-10", "1.234e+10", "-inf", "inf", "+inf", "3.14159265358979323846264338327950288", @@ -25,18 +31,20 @@ let testFloats = [ ] for num in testFloats: - assert num.parseFloat.floatToStr.parseFloat == num.parseFloat + doAssert num.parseFloat.floatToStr.parseFloat == num.parseFloat -assert "0".parseFloat == 0.0 -assert "-.1".parseFloat == -0.1 -assert "2.5e1".parseFloat == 25.0 -assert "1e10".parseFloat == 10_000_000_000.0 -assert "0.000_005".parseFloat == 5.000_000e-6 -assert "1.234_567e+2".parseFloat == 123.4567 -assert "1e1_00".parseFloat == "1e100".parseFloat -assert "3.1415926535897932384626433".parseFloat == +doAssert "0".parseFloat == 0.0 +doAssert "-.1".parseFloat == -0.1 +doAssert "2.5e1".parseFloat == 25.0 +doAssert "1e10".parseFloat == 10_000_000_000.0 +doAssert "0.000_005".parseFloat == 5.000_000e-6 +doAssert "1.234_567e+2".parseFloat == 123.4567 +doAssert "1e1_00".parseFloat == "1e100".parseFloat +doAssert "3.1415926535897932384626433".parseFloat == 3.1415926535897932384626433 -assert "2.71828182845904523536028747".parseFloat == +doAssert "2.71828182845904523536028747".parseFloat == 2.71828182845904523536028747 -assert 0.00097656250000000021684043449710088680149056017398834228515625 == +doAssert 0.00097656250000000021684043449710088680149056017398834228515625 == "0.00097656250000000021684043449710088680149056017398834228515625".parseFloat + +echo("passed all tests.") diff --git a/tests/float/tfloat5.nim b/tests/float/tfloat5.nim new file mode 100644 index 000000000..aa7dc6c53 --- /dev/null +++ b/tests/float/tfloat5.nim @@ -0,0 +1,15 @@ +discard """ + file: "tfloat5.nim" + output: '''0 : 0.0 +0 : 0.0 +0 : 0.0 +0 : 0.0''' +""" + +import parseutils + +var f: float +echo "*".parseFloat(f), " : ", f +echo "/".parseFloat(f), " : ", f +echo "+".parseFloat(f), " : ", f +echo "-".parseFloat(f), " : ", f diff --git a/tests/float/tfloat6.nim b/tests/float/tfloat6.nim new file mode 100644 index 000000000..721abd721 --- /dev/null +++ b/tests/float/tfloat6.nim @@ -0,0 +1,21 @@ +discard """ + file: "tfloat6.nim" + output: '''1e-06 : 1e-06 +1e-06 : 1e-06 +0.001 : 0.001 +1e-06 : 1e-06 +1e-06 : 1e-06 +10.000001 : 10.000001 +100.000001 : 100.000001''' +""" + +import strutils + +echo "0.00_0001".parseFloat(), " : ", 1E-6 +echo "0.00__00_01".parseFloat(), " : ", 1E-6 +echo "0.0_01".parseFloat(), " : ", 0.001 +echo "0.00_000_1".parseFloat(), " : ", 1E-6 +echo "0.00000_1".parseFloat(), " : ", 1E-6 + +echo "1_0.00_0001".parseFloat(), " : ", 10.000001 +echo "1__00.00_0001".parseFloat(), " : ", 1_00.000001 diff --git a/tests/float/tfloat7.nim b/tests/float/tfloat7.nim new file mode 100644 index 000000000..2337d1dd4 --- /dev/null +++ b/tests/float/tfloat7.nim @@ -0,0 +1,26 @@ +discard """ + file: "tfloat6.nim" + output: '''passed. +passed. +passed. +passed. +passed. +passed. +passed.''' +""" + +import strutils +template expect_fail(x: expr) = + try: + discard x + echo("expected to fail!") + except ValueError: + echo("passed.") + +expect_fail("1_0._00_0001".parseFloat()) +expect_fail("_1_0_00.0001".parseFloat()) +expect_fail("10.00.01".parseFloat()) +expect_fail("10.00E_01".parseFloat()) +expect_fail("10.00E_01".parseFloat()) +expect_fail("10.00E".parseFloat()) +expect_fail("10.00A".parseFloat()) diff --git a/tests/gc/thavlak.nim b/tests/gc/thavlak.nim new file mode 100644 index 000000000..efab49e36 --- /dev/null +++ b/tests/gc/thavlak.nim @@ -0,0 +1,457 @@ +discard """ + output: '''Welcome to LoopTesterApp, Nim edition +Constructing Simple CFG... +15000 dummy loops +Constructing CFG... +Performing Loop Recognition +1 Iteration +Another 50 iterations... +.................................................. +Found 1 loops (including artificial root node) (50)''' +""" + +# bug #3184 + +import tables +import sequtils +import sets + +type + BasicBlock = object + inEdges: seq[ref BasicBlock] + outEdges: seq[ref BasicBlock] + name: int + +proc newBasicBlock(name: int): ref BasicBlock = + new(result) + result.inEdges = newSeq[ref BasicBlock]() + result.outEdges = newSeq[ref BasicBlock]() + result.name = name + +proc hash(x: ref BasicBlock): int {.inline.} = + result = x.name + +type + BasicBlockEdge = object + fr: ref BasicBlock + to: ref BasicBlock + + Cfg = object + basicBlockMap: Table[int, ref BasicBlock] + edgeList: seq[BasicBlockEdge] + startNode: ref BasicBlock + +proc newCfg(): Cfg = + result.basicBlockMap = initTable[int, ref BasicBlock]() + result.edgeList = newSeq[BasicBlockEdge]() + +proc createNode(self: var Cfg, name: int): ref BasicBlock = + result = self.basicBlockMap.getOrDefault(name) + if result == nil: + result = newBasicBlock(name) + self.basicBlockMap.add name, result + + if self.startNode == nil: + self.startNode = result + +proc addEdge(self: var Cfg, edge: BasicBlockEdge) = + self.edgeList.add(edge) + +proc getNumNodes(self: Cfg): int = + self.basicBlockMap.len + +proc newBasicBlockEdge(cfg: var Cfg, fromName: int, toName: int): BasicBlockEdge = + result.fr = cfg.createNode(fromName) + result.to = cfg.createNode(toName) + result.fr.outEdges.add(result.to) + result.to.inEdges.add(result.fr) + cfg.addEdge(result) + +type + SimpleLoop = object + basicBlocks: seq[ref BasicBlock] # TODO: set here + children: seq[ref SimpleLoop] # TODO: set here + parent: ref SimpleLoop + header: ref BasicBlock + isRoot: bool + isReducible: bool + counter: int + nestingLevel: int + depthLevel: int + +proc newSimpleLoop(): ref SimpleLoop = + new(result) + result.basicBlocks = newSeq[ref BasicBlock]() + result.children = newSeq[ref SimpleLoop]() + result.parent = nil + result.header = nil + result.isRoot = false + result.isReducible = true + result.counter = 0 + result.nestingLevel = 0 + result.depthLevel = 0 + +proc addNode(self: ref SimpleLoop, bb: ref BasicBlock) = + self.basicBlocks.add bb + +proc addChildLoop(self: ref SimpleLoop, loop: ref SimpleLoop) = + self.children.add loop + +proc setParent(self: ref SimpleLoop, parent: ref SimpleLoop) = + self.parent = parent + self.parent.addChildLoop(self) + +proc setHeader(self: ref SimpleLoop, bb: ref BasicBlock) = + self.basicBlocks.add(bb) + self.header = bb + +proc setNestingLevel(self: ref SimpleLoop, level: int) = + self.nestingLevel = level + if level == 0: self.isRoot = true + +var loop_counter: int = 0 + +type + Lsg = object + loops: seq[ref SimpleLoop] + root: ref SimpleLoop + +proc createNewLoop(self: var Lsg): ref SimpleLoop = + result = newSimpleLoop() + loop_counter += 1 + result.counter = loop_counter + +proc addLoop(self: var Lsg, l: ref SimpleLoop) = + self.loops.add l + +proc newLsg(): Lsg = + result.loops = newSeq[ref SimpleLoop]() + result.root = result.createNewLoop() + result.root.setNestingLevel(0) + result.addLoop(result.root) + +proc getNumLoops(self: Lsg): int = + self.loops.len + +type + UnionFindNode = object + parent: ref UnionFindNode + bb: ref BasicBlock + l: ref SimpleLoop + dfsNumber: int + +proc newUnionFindNode(): ref UnionFindNode = + new(result) + when false: + result.parent = nil + result.bb = nil + result.l = nil + result.dfsNumber = 0 + +proc initNode(self: ref UnionFindNode, bb: ref BasicBlock, dfsNumber: int) = + self.parent = self + self.bb = bb + self.dfsNumber = dfsNumber + +proc findSet(self: ref UnionFindNode): ref UnionFindNode = + var nodeList = newSeq[ref UnionFindNode]() + result = self + + while result != result.parent: + var parent = result.parent + if parent != parent.parent: nodeList.add result + result = parent + + for iter in nodeList: iter.parent = result.parent + +proc union(self: ref UnionFindNode, unionFindNode: ref UnionFindNode) = + self.parent = unionFindNode + + +const + BB_TOP = 0 # uninitialized + BB_NONHEADER = 1 # a regular BB + BB_REDUCIBLE = 2 # reducible loop + BB_SELF = 3 # single BB loop + BB_IRREDUCIBLE = 4 # irreducible loop + BB_DEAD = 5 # a dead BB + BB_LAST = 6 # Sentinel + + # # Marker for uninitialized nodes. + UNVISITED = -1 + + # # Safeguard against pathologic algorithm behavior. + MAXNONBACKPREDS = (32 * 1024) + +type + HavlakLoopFinder = object + cfg: Cfg + lsg: Lsg + +proc newHavlakLoopFinder(cfg: Cfg, lsg: Lsg): HavlakLoopFinder = + result.cfg = cfg + result.lsg = lsg + +proc isAncestor(w: int, v: int, last: seq[int]): bool = + w <= v and v <= last[w] + +proc dfs(currentNode: ref BasicBlock, nodes: var seq[ref UnionFindNode], number: var Table[ref BasicBlock, int], last: var seq[int], current: int): int = + var stack = @[(currentNode, current)] + while stack.len > 0: + let (currentNode, current) = stack.pop() + nodes[current].initNode(currentNode, current) + number[currentNode] = current + + result = current + for target in currentNode.outEdges: + if number[target] == UNVISITED: + stack.add((target, result+1)) + #result = dfs(target, nodes, number, last, result + 1) + last[number[currentNode]] = result + +proc findLoops(self: var HavlakLoopFinder): int = + var startNode = self.cfg.startNode + if startNode == nil: return 0 + var size = self.cfg.getNumNodes + + var nonBackPreds = newSeq[HashSet[int]]() + var backPreds = newSeq[seq[int]]() + var number = initTable[ref BasicBlock, int]() + var header = newSeq[int](size) + var types = newSeq[int](size) + var last = newSeq[int](size) + var nodes = newSeq[ref UnionFindNode]() + + for i in 1..size: + nonBackPreds.add initSet[int](1) + backPreds.add newSeq[int]() + nodes.add newUnionFindNode() + + # Step a: + # - initialize all nodes as unvisited. + # - depth-first traversal and numbering. + # - unreached BB's are marked as dead. + # + for v in self.cfg.basicBlockMap.values: number[v] = UNVISITED + var res = dfs(startNode, nodes, number, last, 0) + + # Step b: + # - iterate over all nodes. + # + # A backedge comes from a descendant in the DFS tree, and non-backedges + # from non-descendants (following Tarjan). + # + # - check incoming edges 'v' and add them to either + # - the list of backedges (backPreds) or + # - the list of non-backedges (nonBackPreds) + # + for w in 0 .. <size: + header[w] = 0 + types[w] = BB_NONHEADER + + var nodeW = nodes[w].bb + if nodeW != nil: + for nodeV in nodeW.inEdges: + var v = number[nodeV] + if v != UNVISITED: + if isAncestor(w, v, last): + backPreds[w].add v + else: + nonBackPreds[w].incl v + else: + types[w] = BB_DEAD + + # Start node is root of all other loops. + header[0] = 0 + + # Step c: + # + # The outer loop, unchanged from Tarjan. It does nothing except + # for those nodes which are the destinations of backedges. + # For a header node w, we chase backward from the sources of the + # backedges adding nodes to the set P, representing the body of + # the loop headed by w. + # + # By running through the nodes in reverse of the DFST preorder, + # we ensure that inner loop headers will be processed before the + # headers for surrounding loops. + + for w in countdown(size - 1, 0): + # this is 'P' in Havlak's paper + var nodePool = newSeq[ref UnionFindNode]() + + var nodeW = nodes[w].bb + if nodeW != nil: # dead BB + # Step d: + for v in backPreds[w]: + if v != w: + nodePool.add nodes[v].findSet + else: + types[w] = BB_SELF + + # Copy nodePool to workList. + # + var workList = newSeq[ref UnionFindNode]() + for x in nodePool: workList.add x + + if nodePool.len != 0: types[w] = BB_REDUCIBLE + + # work the list... + # + while workList.len > 0: + var x = workList[0] + workList.del(0) + + # Step e: + # + # Step e represents the main difference from Tarjan's method. + # Chasing upwards from the sources of a node w's backedges. If + # there is a node y' that is not a descendant of w, w is marked + # the header of an irreducible loop, there is another entry + # into this loop that avoids w. + # + + # The algorithm has degenerated. Break and + # return in this case. + # + var nonBackSize = nonBackPreds[x.dfsNumber].len + if nonBackSize > MAXNONBACKPREDS: return 0 + + for iter in nonBackPreds[x.dfsNumber]: + var y = nodes[iter] + var ydash = y.findSet + + if not isAncestor(w, ydash.dfsNumber, last): + types[w] = BB_IRREDUCIBLE + nonBackPreds[w].incl ydash.dfsNumber + else: + if ydash.dfsNumber != w and not nodePool.contains(ydash): + workList.add ydash + nodePool.add ydash + + # Collapse/Unionize nodes in a SCC to a single node + # For every SCC found, create a loop descriptor and link it in. + # + if (nodePool.len > 0) or (types[w] == BB_SELF): + var l = self.lsg.createNewLoop + + l.setHeader(nodeW) + l.isReducible = types[w] != BB_IRREDUCIBLE + + # At this point, one can set attributes to the loop, such as: + # + # the bottom node: + # iter = backPreds(w).begin(); + # loop bottom is: nodes(iter).node; + # + # the number of backedges: + # backPreds(w).size() + # + # whether this loop is reducible: + # types(w) != BB_IRREDUCIBLE + # + nodes[w].l = l + + for node in nodePool: + # Add nodes to loop descriptor. + header[node.dfsNumber] = w + node.union(nodes[w]) + + # Nested loops are not added, but linked together. + var node_l = node.l + if node_l != nil: + node_l.setParent(l) + else: + l.addNode(node.bb) + + self.lsg.addLoop(l) + + result = self.lsg.getNumLoops + + +type + LoopTesterApp = object + cfg: Cfg + lsg: Lsg + +proc newLoopTesterApp(): LoopTesterApp = + result.cfg = newCfg() + result.lsg = newLsg() + +proc buildDiamond(self: var LoopTesterApp, start: int): int = + var bb0 = start + var x1 = newBasicBlockEdge(self.cfg, bb0, bb0 + 1) + var x2 = newBasicBlockEdge(self.cfg, bb0, bb0 + 2) + var x3 = newBasicBlockEdge(self.cfg, bb0 + 1, bb0 + 3) + var x4 = newBasicBlockEdge(self.cfg, bb0 + 2, bb0 + 3) + result = bb0 + 3 + +proc buildConnect(self: var LoopTesterApp, start1: int, end1: int) = + var x1 = newBasicBlockEdge(self.cfg, start1, end1) + +proc buildStraight(self: var LoopTesterApp, start: int, n: int): int = + for i in 0..n-1: + self.buildConnect(start + i, start + i + 1) + result = start + n + +proc buildBaseLoop(self: var LoopTesterApp, from1: int): int = + var header = self.buildStraight(from1, 1) + var diamond1 = self.buildDiamond(header) + var d11 = self.buildStraight(diamond1, 1) + var diamond2 = self.buildDiamond(d11) + var footer = self.buildStraight(diamond2, 1) + + self.buildConnect(diamond2, d11) + self.buildConnect(diamond1, header) + self.buildConnect(footer, from1) + result = self.buildStraight(footer, 1) + +proc run(self: var LoopTesterApp) = + echo "Welcome to LoopTesterApp, Nim edition" + echo "Constructing Simple CFG..." + + var x1 = self.cfg.createNode(0) + var x2 = self.buildBaseLoop(0) + var x3 = self.cfg.createNode(1) + self.buildConnect(0, 2) + + echo "15000 dummy loops" + + for i in 1..15000: + var h = newHavlakLoopFinder(self.cfg, newLsg()) + var res = h.findLoops + + echo "Constructing CFG..." + var n = 2 + + for parlooptrees in 1..10: + var x6 = self.cfg.createNode(n + 1) + self.buildConnect(2, n + 1) + n += 1 + for i in 1..100: + var top = n + n = self.buildStraight(n, 1) + for j in 1..25: n = self.buildBaseLoop(n) + var bottom = self.buildStraight(n, 1) + self.buildConnect n, top + n = bottom + self.buildConnect(n, 1) + + echo "Performing Loop Recognition\n1 Iteration" + + var h = newHavlakLoopFinder(self.cfg, newLsg()) + var loops = h.findLoops + + echo "Another 50 iterations..." + + var sum = 0 + for i in 1..50: + write stdout, "." + flushFile(stdout) + var hlf = newHavlakLoopFinder(self.cfg, newLsg()) + sum += hlf.findLoops + #echo getOccupiedMem() + echo "\nFound ", loops, " loops (including artificial root node) (", sum, ")" + +var l = newLoopTesterApp() +l.run diff --git a/tests/gc/tlists.nim b/tests/gc/tlists.nim new file mode 100644 index 000000000..26b32396c --- /dev/null +++ b/tests/gc/tlists.nim @@ -0,0 +1,37 @@ +discard """ + output: '''Success''' +""" + +# bug #3793 + +import os +import math +import lists +import strutils + +proc mkleak() = + # allocate 10 MB via linked lists + let numberOfLists = 100 + for i in countUp(1, numberOfLists): + var leakList = initDoublyLinkedList[string]() + let numberOfLeaks = 50000 + for j in countUp(1, numberOfLeaks): + let leakSize = 200 + let leaked = newString(leakSize) + leakList.append(leaked) + +proc mkManyLeaks() = + for i in 0..0: + when false: echo getOccupiedMem() + mkleak() + when false: echo getOccupiedMem() + # Force a full collection. This should free all of the + # lists and bring the memory usage down to a few MB's. + GC_fullCollect() + when false: echo getOccupiedMem() + if getOccupiedMem() > 8 * 200 * 50_000 * 2: + echo GC_getStatistics() + quit "leaking" + echo "Success" + +mkManyLeaks() diff --git a/tests/js/test2.nim b/tests/js/test2.nim index f6976d058..0f460d6f8 100644 --- a/tests/js/test2.nim +++ b/tests/js/test2.nim @@ -1,7 +1,8 @@ discard """ output: '''foo js 3.14 -7''' +7 +1''' """ # This file tests the JavaScript generator @@ -29,3 +30,13 @@ proc test(x: C, T: typedesc): T = cast[T](x) echo 7.test(int8) + +# #4222 +const someConst = [ "1"] + +proc procThatRefersToConst() # Forward decl +procThatRefersToConst() # Call bar before it is defined + +proc procThatRefersToConst() = + var i = 0 # Use a var index, otherwise nim will constfold foo[0] + echo someConst[i] # JS exception here: foo is still not initialized (undefined) diff --git a/tests/js/testtojsstr.nim b/tests/js/testtojsstr.nim new file mode 100644 index 000000000..03ac89e20 --- /dev/null +++ b/tests/js/testtojsstr.nim @@ -0,0 +1,8 @@ +discard """ + output = "И\n" +""" + +let s: string = "И\n" +let cs = s.cstring + +echo $s diff --git a/tests/macros/tgettypeinst.nim b/tests/macros/tgettypeinst.nim new file mode 100644 index 000000000..22e03a119 --- /dev/null +++ b/tests/macros/tgettypeinst.nim @@ -0,0 +1,122 @@ +discard """ +""" + +import macros, strUtils + +proc symToIdent(x: NimNode): NimNode = + case x.kind: + of nnkCharLit..nnkUInt64Lit: + result = newNimNode(x.kind) + result.intVal = x.intVal + of nnkFloatLit..nnkFloat64Lit: + result = newNimNode(x.kind) + result.floatVal = x.floatVal + of nnkStrLit..nnkTripleStrLit: + result = newNimNode(x.kind) + result.strVal = x.strVal + of nnkIdent, nnkSym: + result = newIdentNode($x) + else: + result = newNimNode(x.kind) + for c in x: + result.add symToIdent(c) + +macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed = + let inst = x.getTypeInst + let impl = x.getTypeImpl + let inst0r = inst0.symToIdent.treeRepr + let instr = inst.symToIdent.treeRepr + #echo inst0r + #echo instr + doAssert(instr == inst0r) + var impl0 = + if implX.kind == nnkNilLit: inst0 + else: implX[0][2] + let impl0r = impl0.symToIdent.treerepr + let implr = impl.symToIdent.treerepr + #echo impl0r + #echo implr + doAssert(implr == impl0r) + template echoString(s:string) = echo s.replace("\n","\n ") + result = newStmtList() + #result.add getAst(echoString(" " & inst0.repr)) + #result.add getAst(echoString(" " & inst.repr)) + #result.add getAst(echoString(" " & impl0.repr)) + #result.add getAst(echoString(" " & impl.repr)) + if recurse: + template testDecl(n, m :typed) = + testV(n, false): + type _ = m + result.add getAst(testDecl(inst.symToIdent, impl.symToIdent)) + +template testV(inst, recurse, impl) = + block: + #echo "testV(" & astToStr(inst) & ", " & $recurse & "):" & astToStr(impl) + var x: inst + testX(x, inst, recurse, impl) +template testT(inst, recurse) = + block: + type myType = inst + testV(myType, recurse): + type _ = inst + +template test(inst) = + testT(inst, false) + testV(inst, true, nil) +template test(inst, impl) = testV(inst, true, impl) + +type + Model = object of RootObj + User = object of Model + name : string + password : string + + Tree = object of RootObj + value : int + left,right : ref Tree + + MyEnum = enum + valueA, valueB, valueC + + MySet = set[MyEnum] + MySeq = seq[int] + MyIntPtr = ptr int + MyIntRef = ref int + + GenericObject[T] = object + value:T + Foo[N:static[int],T] = object + Bar[N:static[int],T] = object + #baz:Foo[N+1,GenericObject[T]] + baz:Foo[N,GenericObject[T]] + +test(bool) +test(char) +test(int) +test(float) +test(ptr int) +test(ref int) +test(array[1..10,Bar[2,Foo[3,float]]]) +test(distinct Bar[2,Foo[3,float]]) +test(tuple[a:int,b:Foo[-1,float]]) +#test(MyEnum): +# type _ = enum +# valueA, valueB, valueC +test(set[MyEnum]) +test(seq[int]) +test(Bar[2,Foo[3,float]]): + type _ = object + baz: Foo[2, GenericObject[Foo[3, float]]] +test(Model): + type _ = object of RootObj +test(User): + type _ = object of Model + name: string + password: string +test(Tree): + type _ = object of RootObj + value: int + left: ref Tree + right: ref Tree +test(proc (a: int, b: Foo[2,float])) +test(proc (a: int, b: Foo[2,float]): Bar[3,int]) diff --git a/tests/parser/tdo.nim b/tests/parser/tdo.nim new file mode 100644 index 000000000..7bd1f7411 --- /dev/null +++ b/tests/parser/tdo.nim @@ -0,0 +1,79 @@ +discard """ + output: '''true +true +true +true inner B''' +""" + +template withValue(a, b, c, d, e: untyped) = + if c: + d + else: + e + +template withValue(a, b, c, d: untyped) = + if c: + d + +const + EVENT_READ = 1 + EVENT_WRITE = 2 + FLAG_HANDLE = 3 + EVENT_MASK = 3 + +var s: string + +proc main = + var value = false + var fd = 8888 + var event = 0 + s.withValue(fd, value) do: + if value: + var oe = (EVENT_MASK) + if (oe xor event) != 0: + if (oe and EVENT_READ) != 0 and (event and EVENT_READ) == 0: + discard + if (oe and EVENT_WRITE) != 0 and (event and EVENT_WRITE) == 0: + discard + if (oe and EVENT_READ) == 0 and (event and EVENT_READ) != 0: + discard + if (oe and EVENT_WRITE) == 0 and (event and EVENT_WRITE) != 0: + discard + else: + raise newException(ValueError, "error") + do: + raise newException(ValueError, "Descriptor is not registered in queue") + +proc main2 = + var unused = 8 + # test 'then' branch: + s.withValue(unused, true) do: + echo "true" + do: + echo "false" + + # test overloading: + s.withValue(unused, false) do: + echo "cannot come here" + + # test 'else' branch: + s.withValue(unused, false) do: + echo "false" + do: + echo "true" + + # test proper nesting: + s.withValue(unused, false) do: + echo "false" + s.withValue(unused, false) do: + echo "false inner A" + do: + echo "true inner A" + do: + echo "true" + s.withValue(unused, false) do: + echo "false inner B" + do: + echo "true inner B" + +main2() diff --git a/tests/stdlib/tparscfg.nim b/tests/stdlib/tparscfg.nim index 4c11ccf61..7022d071b 100644 --- a/tests/stdlib/tparscfg.nim +++ b/tests/stdlib/tparscfg.nim @@ -1,25 +1,37 @@ +import parsecfg -import - os, parsecfg, strutils, streams +## Creating a configuration file. +var dict1=newConfig() +dict1.setSectionKey("","charset","utf-8") +dict1.setSectionKey("Package","name","hello") +dict1.setSectionKey("Package","--threads","on") +dict1.setSectionKey("Author","name","lihf8515") +dict1.setSectionKey("Author","qq","10214028") +dict1.setSectionKey("Author","email","lihaifeng@wxm.com") +dict1.writeConfig("config.ini") + +## Reading a configuration file. +var dict2 = loadConfig("config.ini") +var charset = dict2.getSectionValue("","charset") +var threads = dict2.getSectionValue("Package","--threads") +var pname = dict2.getSectionValue("Package","name") +var name = dict2.getSectionValue("Author","name") +var qq = dict2.getSectionValue("Author","qq") +var email = dict2.getSectionValue("Author","email") +echo charset +echo threads +echo pname +echo name +echo qq +echo email + +## Modifying a configuration file. +var dict3 = loadConfig("config.ini") +dict3.setSectionKey("Author","name","lhf") +dict3.writeConfig("config.ini") + +## Deleting a section key in a configuration file. +var dict4 = loadConfig("config.ini") +dict4.delSectionKey("Author","email") +dict4.writeConfig("config.ini") -var f = newFileStream(paramStr(1), fmRead) -if f != nil: - var p: TCfgParser - open(p, f, paramStr(1)) - while true: - var e = next(p) - case e.kind - of cfgEof: - echo("EOF!") - break - of cfgSectionStart: ## a ``[section]`` has been parsed - echo("new section: " & e.section) - of cfgKeyValuePair: - echo("key-value-pair: " & e.key & ": " & e.value) - of cfgOption: - echo("command: " & e.key & ": " & e.value) - of cfgError: - echo(e.msg) - close(p) -else: - echo("cannot open: " & paramStr(1)) diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim new file mode 100644 index 000000000..c702ccc2a --- /dev/null +++ b/tests/stdlib/trstgen.nim @@ -0,0 +1,139 @@ +# tests for rstgen module. + +import ../../lib/packages/docutils/rstgen +import unittest + +suite "YAML syntax highlighting": + test "Basics": + let input = """.. code-block:: yaml + %YAML 1.2 + --- + a string: string + a list: + - item 1 + - item 2 + a map: + ? key + : value + ...""" + let output = rstTohtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="Directive">%YAML 1.2</span> +<span class="Keyword">---</span> +<span class="StringLit">a string</span><span class="Punctuation">:</span> <span class="StringLit">string</span> +<span class="StringLit">a list</span><span class="Punctuation">:</span> + <span class="Punctuation">-</span> <span class="StringLit">item 1</span> + <span class="Punctuation">-</span> <span class="StringLit">item 2</span> +<span class="StringLit">a map</span><span class="Punctuation">:</span> +<span class="Punctuation">?</span> <span class="StringLit">key</span> +<span class="Punctuation">:</span> <span class="StringLit">value</span> +<span class="Keyword">...</span></pre>""" + + test "Block scalars": + let input = """.. code-block:: yaml + a literal block scalar: | + some text + # not a comment + # a comment, since less indented + # another comment + a folded block scalar: >2 + some text + # not a comment since indented as specified + # a comment + another literal block scalar: + |+ # comment after header + allowed, since more indented than parent""" + let output = rstToHtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="StringLit">a literal block scalar</span><span class="Punctuation">:</span> <span class="Command">|</span><span class="Command"></span><span class="LongStringLit"> + some text + # not a comment + </span><span class="Comment"># a comment, since less indented</span> + <span class="Comment"># another comment</span> +<span class="StringLit">a folded block scalar</span><span class="Punctuation">:</span> <span class="Command">>2</span><span class="Command"></span><span class="LongStringLit"> + some text + # not a comment since indented as specified + </span><span class="Comment"># a comment</span> +<span class="StringLit">another literal block scalar</span><span class="Punctuation">:</span> + <span class="Command">|+</span> <span class="Comment"># comment after header</span><span class="LongStringLit"> + allowed, since more indented than parent</span></pre>""" + + test "Directives": + let input = """.. code-block:: yaml + %YAML 1.2 + --- + %not a directive + ... + %a directive + ... + a string + % not a directive + ... + %TAG ! !foo:""" + let output = rstToHtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="Directive">%YAML 1.2</span> +<span class="Keyword">---</span> +<span class="StringLit">%not a directive</span> +<span class="Keyword">...</span> +<span class="Directive">%a directive</span> +<span class="Keyword">...</span> +<span class="StringLit">a string</span> +<span class="StringLit">% not a directive</span> +<span class="Keyword">...</span> +<span class="Directive">%TAG ! !foo:</span></pre>""" + + test "Flow Style and Numbers": + let input = """.. code-block:: yaml + { + "quoted string": 42, + 'single quoted string': false, + [ list, "with", 'entries' ]: 73.32e-73, + more numbers: [-783, 11e78], + not numbers: [ 42e, 0023, +32.37, 8 ball] + }""" + let output = rstToHtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="Punctuation">{</span> + <span class="StringLit">"</span><span class="StringLit">quoted string"</span><span class="Punctuation">:</span> <span class="DecNumber">42</span><span class="Punctuation">,</span> + <span class="StringLit">'single quoted string'</span><span class="Punctuation">:</span> <span class="StringLit">false</span><span class="Punctuation">,</span> + <span class="Punctuation">[</span> <span class="StringLit">list</span><span class="Punctuation">,</span> <span class="StringLit">"</span><span class="StringLit">with"</span><span class="Punctuation">,</span> <span class="StringLit">'entries'</span> <span class="Punctuation">]</span><span class="Punctuation">:</span> <span class="FloatNumber">73.32e-73</span><span class="Punctuation">,</span> + <span class="StringLit">more numbers</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="DecNumber">-783</span><span class="Punctuation">,</span> <span class="FloatNumber">11e78</span><span class="Punctuation">]</span><span class="Punctuation">,</span> + <span class="StringLit">not numbers</span><span class="Punctuation">:</span> <span class="Punctuation">[</span> <span class="StringLit">42e</span><span class="Punctuation">,</span> <span class="StringLit">0023</span><span class="Punctuation">,</span> <span class="StringLit">+32.37</span><span class="Punctuation">,</span> <span class="StringLit">8 ball</span><span class="Punctuation">]</span> +<span class="Punctuation">}</span></pre>""" + + test "Anchors, Aliases, Tags": + let input = """.. code-block:: yaml + --- !!map + !!str string: !<tag:yaml.org,2002:int> 42 + ? &anchor !!seq []: + : !localtag foo + alias: *anchor + """ + let output = rstToHtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="Keyword">---</span> <span class="TagStart">!!map</span> +<span class="TagStart">!!str</span> <span class="StringLit">string</span><span class="Punctuation">:</span> <span class="TagStart">!<tag:yaml.org,2002:int></span> <span class="DecNumber">42</span> +<span class="Punctuation">?</span> <span class="Label">&anchor</span> <span class="TagStart">!!seq</span> <span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Punctuation">:</span> +<span class="Punctuation">:</span> <span class="TagStart">!localtag</span> <span class="StringLit">foo</span> +<span class="StringLit">alias</span><span class="Punctuation">:</span> <span class="Reference">*anchor</span></pre>""" + + test "Edge cases": + let input = """.. code-block:: yaml + ... + %a string: + a:string:not:a:map + ... + not a list: + -2 + -3 + -4 + example.com/not/a#comment: + ?not a map key + """ + let output = rstToHtml(input, {}, defaultConfig()) + assert output == """<pre class = "listing"><span class="Keyword">...</span> + <span class="StringLit">%a string</span><span class="Punctuation">:</span> + <span class="StringLit">a:string:not:a:map</span> +<span class="Keyword">...</span> +<span class="StringLit">not a list</span><span class="Punctuation">:</span> + <span class="DecNumber">-2</span> + <span class="DecNumber">-3</span> + <span class="DecNumber">-4</span> +<span class="StringLit">example.com/not/a#comment</span><span class="Punctuation">:</span> + <span class="StringLit">?not a map key</span></pre>""" \ No newline at end of file diff --git a/tests/template/t2do.nim b/tests/template/t2do.nim index b87e3328c..ec364c5f3 100644 --- a/tests/template/t2do.nim +++ b/tests/template/t2do.nim @@ -15,8 +15,9 @@ template toFloatHelper(result: expr; tooSmall, tooLarge: stmt) {.immediate.} = tooLarge proc toFloat*(a: int): float = - toFloatHelper(result) - do: raise newException(ValueError, "number too small"): - raise newException(ValueError, "number too large") + toFloatHelper(result) do: + raise newException(ValueError, "number too small") + do: + raise newException(ValueError, "number too large") echo toFloat(8) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 150c55edc..cf09aaae0 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -152,6 +152,9 @@ proc gcTests(r: var TResults, cat: Category, options: string) = testWithoutBoehm "closureleak" testWithoutMs "refarrayleak" + testWithoutBoehm "tlists" + testWithoutBoehm "thavlak" + test "stackrefleak" test "cyclecollector" diff --git a/tests/trmacros/tstatic_t_bug.nim b/tests/trmacros/tstatic_t_bug.nim new file mode 100644 index 000000000..cdfa53514 --- /dev/null +++ b/tests/trmacros/tstatic_t_bug.nim @@ -0,0 +1,24 @@ +discard """ + output: "optimized" +""" +# bug #4227 +type Vector64[N: static[int]] = array[N, int] + +proc `*`*[N: static[int]](a: Vector64[N]; b: float64): Vector64[N] = + result = a + +proc `+=`*[N: static[int]](a: var Vector64[N]; b: Vector64[N]) = + echo "regular" + +proc linearCombinationMut[N: static[int]](a: float64, v: var Vector64[N], w: Vector64[N]) {. inline .} = + echo "optimized" + +template rewriteLinearCombinationMut*{v += `*`(w, a)}(a: float64, v: var Vector64, w: Vector64): auto = + linearCombinationMut(a, v, w) + +proc main() = + const scaleVal = 9.0 + var a, b: Vector64[7] + a += b * scaleval + +main() diff --git a/tests/typerel/temptynode.nim b/tests/typerel/temptynode.nim new file mode 100644 index 000000000..91e45f3ca --- /dev/null +++ b/tests/typerel/temptynode.nim @@ -0,0 +1,16 @@ +discard """ + line: 16 + errormsg: "type mismatch: got (empty)" +""" + +# bug #950 + +import macros + +proc blah(x: proc (a, b: int): int) = + echo x(5, 5) + +macro test(): stmt = + result = newNimNode(nnkEmpty) + +blah(test()) |