summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/assert/tunittests.nim3
-rw-r--r--tests/async/tasync_forward.nim9
-rw-r--r--tests/async/tgeneric_async.nim9
-rw-r--r--tests/async/tioselectors.nim408
-rw-r--r--tests/async/tioselectors.nim.cfg1
-rw-r--r--tests/async/tnewasyncudp.nim102
-rw-r--r--tests/async/treturn_await.nim23
-rw-r--r--tests/ccgbugs/tuplecast.nim8
-rw-r--r--tests/closure/uclosures.nim15
-rw-r--r--tests/converter/tconverter_with_varargs.nim18
-rw-r--r--tests/generics/t88.nim25
-rw-r--r--tests/generics/tforward_generic.nim28
-rw-r--r--tests/js/tstring_assignment.nim11
-rw-r--r--tests/macros/tcomplexecho.nim42
-rw-r--r--tests/macros/tvarargsuntyped.nim79
-rw-r--r--tests/metatype/tautoproc.nim2
-rw-r--r--tests/metatype/tmodulo.nim20
-rw-r--r--tests/metatype/tvoid_must_not_match.nim21
-rw-r--r--tests/method/tgeneric_methods.nim24
-rw-r--r--tests/method/tmultim6.nim20
-rw-r--r--tests/modules/texplicit_system_import.nim9
-rw-r--r--tests/newconfig/mymath.nim4
-rw-r--r--tests/newconfig/tfoo.nim6
-rw-r--r--tests/newconfig/tfoo.nims5
-rw-r--r--tests/osproc/passenv.nim32
-rw-r--r--tests/overload/tissue4475.nim6
-rw-r--r--tests/stdlib/thtmlparser2814.nim44
-rw-r--r--tests/stdlib/tos.nim92
-rw-r--r--tests/stdlib/tsplit.nim2
-rw-r--r--tests/stdlib/tunittest.nim6
-rw-r--r--tests/tuples/tconver_tuple.nim23
-rw-r--r--tests/tuples/twrong_generic_caching.nim4
-rw-r--r--tests/typerel/tclosure_nil_as_default.nim11
-rw-r--r--tests/typerel/temptynode.nim2
-rw-r--r--tests/typerel/tgeneric_subtype_regression.nim19
-rw-r--r--tests/types/tassignemptytuple.nim11
-rw-r--r--tests/vm/tvmmisc.nim16
37 files changed, 1135 insertions, 25 deletions
diff --git a/tests/assert/tunittests.nim b/tests/assert/tunittests.nim
index cbbfe63c6..de917511c 100644
--- a/tests/assert/tunittests.nim
+++ b/tests/assert/tunittests.nim
@@ -1 +1,4 @@
+discard """
+output: ""
+"""
 import "../template/utemplates", "../closure/uclosures"
diff --git a/tests/async/tasync_forward.nim b/tests/async/tasync_forward.nim
new file mode 100644
index 000000000..ffb7acafd
--- /dev/null
+++ b/tests/async/tasync_forward.nim
@@ -0,0 +1,9 @@
+
+import asyncdispatch
+
+# bug #1970
+
+proc foo {.async.}
+
+proc foo {.async.} =
+  discard
diff --git a/tests/async/tgeneric_async.nim b/tests/async/tgeneric_async.nim
new file mode 100644
index 000000000..af6370181
--- /dev/null
+++ b/tests/async/tgeneric_async.nim
@@ -0,0 +1,9 @@
+
+import asyncdispatch
+
+when true:
+  # bug #2377
+  proc test[T](v: T) {.async.} =
+    echo $v
+
+  asyncCheck test[int](1)
diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim
new file mode 100644
index 000000000..ed2fea84f
--- /dev/null
+++ b/tests/async/tioselectors.nim
@@ -0,0 +1,408 @@
+discard """
+  file: "tioselectors.nim"
+  output: "All tests passed!"
+"""
+import ioselectors
+
+const hasThreadSupport = compileOption("threads")
+
+template processTest(t, x: untyped) =
+  #stdout.write(t)
+  #stdout.flushFile()
+  if not x: echo(t & " FAILED\r\n")
+
+when not defined(windows):
+  import os, posix, osproc, nativesockets, times
+
+  const supportedPlatform = defined(macosx) or defined(freebsd) or
+                            defined(netbsd) or defined(openbsd) or
+                            defined(linux)
+
+  proc socket_notification_test(): bool =
+    proc create_test_socket(): SocketHandle =
+      var sock = posix.socket(posix.AF_INET, posix.SOCK_STREAM,
+                              posix.IPPROTO_TCP)
+      var x: int = fcntl(sock, F_GETFL, 0)
+      if x == -1: raiseOSError(osLastError())
+      else:
+        var mode = x or O_NONBLOCK
+        if fcntl(sock, F_SETFL, mode) == -1:
+          raiseOSError(osLastError())
+      result = sock
+
+    var client_message = "SERVER HELLO =>"
+    var server_message = "CLIENT HELLO"
+    var buffer : array[128, char]
+
+    var selector = newSelector[int]()
+    var client_socket = create_test_socket()
+    var server_socket = create_test_socket()
+
+    registerHandle(selector, server_socket, {Event.Read}, 0)
+    registerHandle(selector, client_socket, {Event.Write}, 0)
+
+    var option : int32 = 1
+    if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
+                  addr(option), sizeof(option).SockLen) < 0:
+      raiseOSError(osLastError())
+
+    var aiList = getAddrInfo("0.0.0.0", Port(13337))
+    if bindAddr(server_socket, aiList.ai_addr,
+                aiList.ai_addrlen.Socklen) < 0'i32:
+      dealloc(aiList)
+      raiseOSError(osLastError())
+    discard server_socket.listen()
+    dealloc(aiList)
+
+    aiList = getAddrInfo("127.0.0.1", Port(13337))
+    discard posix.connect(client_socket, aiList.ai_addr,
+                          aiList.ai_addrlen.Socklen)
+    dealloc(aiList)
+    discard selector.select(100)
+    var rc1 = selector.select(100)
+    assert(len(rc1) == 2)
+
+    var sockAddress: SockAddr
+    var addrLen = sizeof(sockAddress).Socklen
+    var server2_socket = accept(server_socket,
+                                cast[ptr SockAddr](addr(sockAddress)),
+                                addr(addrLen))
+    assert(server2_socket != osInvalidSocket)
+    selector.registerHandle(server2_socket, {Event.Read}, 0)
+
+    if posix.send(client_socket, addr(client_message[0]),
+                  len(client_message), 0) == -1:
+      raiseOSError(osLastError())
+
+    selector.updateHandle(client_socket, {Event.Read})
+
+    var rc2 = selector.select(100)
+    assert(len(rc2) == 1)
+
+    var read_count = posix.recv(server2_socket, addr (buffer[0]), 128, 0)
+    if read_count == -1:
+      raiseOSError(osLastError())
+
+    assert(read_count == len(client_message))
+    var test1 = true
+    for i in 0..<read_count:
+      if client_message[i] != buffer[i]:
+        test1 = false
+        break
+    assert(test1)
+
+    selector.updateHandle(server2_socket, {Event.Write})
+    var rc3 = selector.select(0)
+    assert(len(rc3) == 1)
+    if posix.send(server2_socket, addr(server_message[0]),
+                  len(server_message), 0) == -1:
+      raiseOSError(osLastError())
+    selector.updateHandle(server2_socket, {Event.Read})
+
+    var rc4 = selector.select(100)
+    assert(len(rc4) == 1)
+    read_count = posix.recv(client_socket, addr(buffer[0]), 128, 0)
+    if read_count == -1:
+      raiseOSError(osLastError())
+
+    assert(read_count == len(server_message))
+    var test2 = true
+    for i in 0..<read_count:
+      if server_message[i] != buffer[i]:
+        test2 = false
+        break
+    assert(test2)
+
+    selector.unregister(server_socket)
+    selector.unregister(server2_socket)
+    selector.unregister(client_socket)
+    discard posix.close(server_socket)
+    discard posix.close(server2_socket)
+    discard posix.close(client_socket)
+    assert(selector.isEmpty())
+    close(selector)
+    result = true
+
+  proc event_notification_test(): bool =
+    var selector = newSelector[int]()
+    var event = newSelectEvent()
+    selector.registerEvent(event, 1)
+    selector.flush()
+    event.setEvent()
+    var rc1 = selector.select(0)
+    event.setEvent()
+    var rc2 = selector.select(0)
+    var rc3 = selector.select(0)
+    assert(len(rc1) == 1 and len(rc2) == 1 and len(rc3) == 0)
+    var ev1 = rc1[0].data
+    var ev2 = rc2[0].data
+    assert(ev1 == 1 and ev2 == 1)
+    selector.unregister(event)
+    event.close()
+    assert(selector.isEmpty())
+    selector.close()
+    result = true
+
+  when supportedPlatform:
+    proc timer_notification_test(): bool =
+      var selector = newSelector[int]()
+      var timer = selector.registerTimer(100, false, 0)
+      var rc1 = selector.select(140)
+      var rc2 = selector.select(140)
+      assert(len(rc1) == 1 and len(rc2) == 1)
+      selector.unregister(timer)
+      selector.flush()
+      selector.registerTimer(100, true, 0)
+      var rc3 = selector.select(120)
+      var rc4 = selector.select(120)
+      assert(len(rc3) == 1 and len(rc4) == 0)
+      assert(selector.isEmpty())
+      selector.close()
+      result = true
+
+    proc process_notification_test(): bool =
+      var selector = newSelector[int]()
+      var process2 = startProcess("/bin/sleep", "", ["2"], nil,
+                           {poStdErrToStdOut, poUsePath})
+      discard startProcess("/bin/sleep", "", ["1"], nil,
+                           {poStdErrToStdOut, poUsePath})
+
+      selector.registerProcess(process2.processID, 0)
+      var rc1 = selector.select(1500)
+      var rc2 = selector.select(1500)
+      var r = len(rc1) + len(rc2)
+      assert(r == 1)
+      result = true
+
+    proc signal_notification_test(): bool =
+      var sigset1n, sigset1o, sigset2n, sigset2o: Sigset
+      var pid = posix.getpid()
+
+      discard sigemptyset(sigset1n)
+      discard sigemptyset(sigset1o)
+      discard sigemptyset(sigset2n)
+      discard sigemptyset(sigset2o)
+
+      when hasThreadSupport:
+        if pthread_sigmask(SIG_BLOCK, sigset1n, sigset1o) == -1:
+          raiseOSError(osLastError())
+      else:
+        if sigprocmask(SIG_BLOCK, sigset1n, sigset1o) == -1:
+          raiseOSError(osLastError())
+
+      var selector = newSelector[int]()
+      var s1 = selector.registerSignal(SIGUSR1, 1)
+      var s2 = selector.registerSignal(SIGUSR2, 2)
+      var s3 = selector.registerSignal(SIGTERM, 3)
+      selector.flush()
+
+      discard posix.kill(pid, SIGUSR1)
+      discard posix.kill(pid, SIGUSR2)
+      discard posix.kill(pid, SIGTERM)
+      var rc = selector.select(0)
+      selector.unregister(s1)
+      selector.unregister(s2)
+      selector.unregister(s3)
+
+      when hasThreadSupport:
+        if pthread_sigmask(SIG_BLOCK, sigset2n, sigset2o) == -1:
+          raiseOSError(osLastError())
+      else:
+        if sigprocmask(SIG_BLOCK, sigset2n, sigset2o) == -1:
+          raiseOSError(osLastError())
+
+      assert(len(rc) == 3)
+      assert(rc[0].data + rc[1].data + rc[2].data == 6) # 1 + 2 + 3
+      assert(equalMem(addr sigset1o, addr sigset2o, sizeof(Sigset)))
+      assert(selector.isEmpty())
+      result = true
+
+  when hasThreadSupport:
+
+    var counter = 0
+
+    proc event_wait_thread(event: SelectEvent) {.thread.} =
+      var selector = newSelector[int]()
+      selector.registerEvent(event, 1)
+      selector.flush()
+      var rc = selector.select(1000)
+      if len(rc) == 1:
+        inc(counter)
+      selector.unregister(event)
+      assert(selector.isEmpty())
+
+    proc mt_event_test(): bool =
+      var
+        thr: array [0..7, Thread[SelectEvent]]
+      var selector = newSelector[int]()
+      var sock = newNativeSocket()
+      var event = newSelectEvent()
+      for i in 0..high(thr):
+        createThread(thr[i], event_wait_thread, event)
+      selector.registerHandle(sock, {Event.Read}, 1)
+      discard selector.select(500)
+      selector.unregister(sock)
+      event.setEvent()
+      joinThreads(thr)
+      assert(counter == 1)
+      result = true
+
+  processTest("Socket notification test...", socket_notification_test())
+  processTest("User event notification test...", event_notification_test())
+  when hasThreadSupport:
+    processTest("Multithreaded user event notification test...",
+                mt_event_test())
+  when supportedPlatform:
+    processTest("Timer notification test...", timer_notification_test())
+    processTest("Process notification test...", process_notification_test())
+    processTest("Signal notification test...", signal_notification_test())
+  echo("All tests passed!")
+else:
+  import nativesockets, winlean, os, osproc
+
+  proc socket_notification_test(): bool =
+    proc create_test_socket(): SocketHandle =
+      var sock = newNativeSocket()
+      setBlocking(sock, false)
+      result = sock
+
+    var client_message = "SERVER HELLO =>"
+    var server_message = "CLIENT HELLO"
+    var buffer : array[128, char]
+
+    var selector = newSelector[int]()
+    var client_socket = create_test_socket()
+    var server_socket = create_test_socket()
+
+    selector.registerHandle(server_socket, {Event.Read}, 0)
+    selector.registerHandle(client_socket, {Event.Write}, 0)
+
+    var option : int32 = 1
+    if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
+                  addr(option), sizeof(option).SockLen) < 0:
+      raiseOSError(osLastError())
+
+    var aiList = getAddrInfo("0.0.0.0", Port(13337))
+    if bindAddr(server_socket, aiList.ai_addr,
+                aiList.ai_addrlen.Socklen) < 0'i32:
+      dealloc(aiList)
+      raiseOSError(osLastError())
+    discard server_socket.listen()
+    dealloc(aiList)
+
+    aiList = getAddrInfo("127.0.0.1", Port(13337))
+    discard connect(client_socket, aiList.ai_addr,
+                    aiList.ai_addrlen.Socklen)
+    dealloc(aiList)
+    # for some reason Windows select doesn't return both
+    # descriptors from first call, so we need to make 2 calls
+    discard selector.select(100)
+    var rcm = selector.select(100)
+    assert(len(rcm) == 2)
+
+    var sockAddress = SockAddr()
+    var addrLen = sizeof(sockAddress).Socklen
+    var server2_socket = accept(server_socket,
+                                cast[ptr SockAddr](addr(sockAddress)),
+                                addr(addrLen))
+    assert(server2_socket != osInvalidSocket)
+    selector.registerHandle(server2_socket, {Event.Read}, 0)
+
+    if send(client_socket, cast[pointer](addr(client_message[0])),
+            cint(len(client_message)), 0) == -1:
+      raiseOSError(osLastError())
+
+    selector.updateHandle(client_socket, {Event.Read})
+
+    var rc2 = selector.select(100)
+    assert(len(rc2) == 1)
+
+    var read_count = recv(server2_socket, addr (buffer[0]), 128, 0)
+    if read_count == -1:
+      raiseOSError(osLastError())
+
+    assert(read_count == len(client_message))
+    var test1 = true
+    for i in 0..<read_count:
+      if client_message[i] != buffer[i]:
+        test1 = false
+        break
+    assert(test1)
+
+    if send(server2_socket, cast[pointer](addr(server_message[0])),
+                  cint(len(server_message)), 0) == -1:
+      raiseOSError(osLastError())
+
+    var rc3 = selector.select(0)
+    assert(len(rc3) == 1)
+    read_count = recv(client_socket, addr(buffer[0]), 128, 0)
+    if read_count == -1:
+      raiseOSError(osLastError())
+
+    assert(read_count == len(server_message))
+    var test2 = true
+    for i in 0..<read_count:
+      if server_message[i] != buffer[i]:
+        test2 = false
+        break
+    assert(test2)
+
+    selector.unregister(server_socket)
+    selector.unregister(server2_socket)
+    selector.unregister(client_socket)
+    close(server_socket)
+    close(server2_socket)
+    close(client_socket)
+    assert(selector.isEmpty())
+    close(selector)
+    result = true
+
+  proc event_notification_test(): bool =
+    var selector = newSelector[int]()
+    var event = newSelectEvent()
+    selector.registerEvent(event, 1)
+    selector.flush()
+    event.setEvent()
+    var rc1 = selector.select(0)
+    event.setEvent()
+    var rc2 = selector.select(0)
+    var rc3 = selector.select(0)
+    assert(len(rc1) == 1 and len(rc2) == 1 and len(rc3) == 0)
+    var ev1 = rc1[0].data
+    var ev2 = rc2[0].data
+    assert(ev1 == 1 and ev2 == 1)
+    selector.unregister(event)
+    event.close()
+    assert(selector.isEmpty())
+    selector.close()
+    result = true
+
+  when hasThreadSupport:
+    var counter = 0
+
+    proc event_wait_thread(event: SelectEvent) {.thread.} =
+      var selector = newSelector[int]()
+      selector.registerEvent(event, 1)
+      selector.flush()
+      var rc = selector.select(500)
+      if len(rc) == 1:
+        inc(counter)
+      selector.unregister(event)
+      assert(selector.isEmpty())
+
+    proc mt_event_test(): bool =
+      var thr: array [0..7, Thread[SelectEvent]]
+      var event = newSelectEvent()
+      for i in 0..high(thr):
+        createThread(thr[i], event_wait_thread, event)
+      event.setEvent()
+      joinThreads(thr)
+      assert(counter == 1)
+      result = true
+
+  processTest("Socket notification test...", socket_notification_test())
+  processTest("User event notification test...", event_notification_test())
+  when hasThreadSupport:
+    processTest("Multithreaded user event notification test...",
+                 mt_event_test())
+  echo("All tests passed!")
diff --git a/tests/async/tioselectors.nim.cfg b/tests/async/tioselectors.nim.cfg
new file mode 100644
index 000000000..b1b896858
--- /dev/null
+++ b/tests/async/tioselectors.nim.cfg
@@ -0,0 +1 @@
+threads:on -d:threadsafe
diff --git a/tests/async/tnewasyncudp.nim b/tests/async/tnewasyncudp.nim
new file mode 100644
index 000000000..7025fa20d
--- /dev/null
+++ b/tests/async/tnewasyncudp.nim
@@ -0,0 +1,102 @@
+discard """
+  file: "tnewasyncudp.nim"
+  output: "5000"
+"""
+import asyncdispatch, nativesockets, net, strutils, os
+
+when defined(windows):
+  import winlean
+else:
+  import posix
+
+var msgCount = 0
+var recvCount = 0
+
+const
+  messagesToSend = 100
+  swarmSize = 50
+  serverPort = 10333
+
+var
+  sendports = 0
+  recvports = 0
+
+proc saveSendingPort(port: int) =
+  sendports = sendports + port
+
+proc saveReceivedPort(port: int) =
+  recvports = recvports + port
+
+proc prepareAddress(intaddr: uint32, intport: uint16): ptr Sockaddr_in =
+  result = cast[ptr Sockaddr_in](alloc0(sizeof(Sockaddr_in)))
+  when defined(windows):
+    result.sin_family = toInt(nativesockets.AF_INET).int16
+  else:
+    result.sin_family = toInt(nativesockets.AF_INET)
+  result.sin_port = htons(intport)
+  result.sin_addr.s_addr = htonl(intaddr)
+
+proc launchSwarm(name: ptr SockAddr) {.async.} =
+  var i = 0
+  var k = 0
+  while i < swarmSize:
+    var peeraddr = prepareAddress(INADDR_ANY, 0)
+    var sock = newAsyncNativeSocket(nativesockets.AF_INET,
+                                    nativesockets.SOCK_DGRAM,
+                                    Protocol.IPPROTO_UDP)
+    if bindAddr(sock.SocketHandle, cast[ptr SockAddr](peeraddr),
+              sizeof(Sockaddr_in).Socklen) < 0'i32:
+      raiseOSError(osLastError())
+    let sockport = getSockName(sock.SocketHandle).int
+    k = 0
+    while k < messagesToSend:
+      var message = "Message " & $(i * messagesToSend + k)
+      await sendTo(sock, addr message[0], len(message),
+                   name, sizeof(Sockaddr_in).SockLen)
+      saveSendingPort(sockport)
+      inc(k)
+    closeSocket(sock)
+    inc(i)
+
+proc readMessages(server: AsyncFD) {.async.} =
+  var buffer: array[16384, char]
+  var slen = sizeof(Sockaddr_in).SockLen
+  var saddr = Sockaddr_in()
+  var maxResponses = (swarmSize * messagesToSend)
+
+  var i = 0
+  while i < maxResponses:
+    zeroMem(addr(buffer[0]), 16384)
+    zeroMem(cast[pointer](addr(saddr)), sizeof(Sockaddr_in))
+    var size = await recvFromInto(server, cast[cstring](addr buffer[0]),
+                                  16384, cast[ptr SockAddr](addr(saddr)),
+                                  addr(slen))
+    size = 0
+    var grammString = $buffer
+    if grammString.startswith("Message ") and
+       saddr.sin_addr.s_addr == 0x100007F:
+      inc(msgCount)
+      saveReceivedPort(ntohs(saddr.sin_port).int)
+      inc(recvCount)
+    inc(i)
+
+proc createServer() {.async.} =
+  var name = prepareAddress(INADDR_ANY, serverPort)
+  var server = newAsyncNativeSocket(nativesockets.AF_INET,
+                                    nativesockets.SOCK_DGRAM,
+                                    Protocol.IPPROTO_UDP)
+  if bindAddr(server.SocketHandle, cast[ptr SockAddr](name),
+              sizeof(Sockaddr_in).Socklen) < 0'i32:
+    raiseOSError(osLastError())
+  asyncCheck readMessages(server)
+
+var name = prepareAddress(0x7F000001, serverPort) # 127.0.0.1
+asyncCheck createServer()
+asyncCheck launchSwarm(cast[ptr SockAddr](name))
+while true:
+  poll()
+  if recvCount == swarmSize * messagesToSend:
+    break
+assert msgCount == swarmSize * messagesToSend
+assert sendports == recvports
+echo msgCount
diff --git a/tests/async/treturn_await.nim b/tests/async/treturn_await.nim
new file mode 100644
index 000000000..8d266d665
--- /dev/null
+++ b/tests/async/treturn_await.nim
@@ -0,0 +1,23 @@
+
+# bug #4371
+
+import strutils, asyncdispatch, asynchttpserver
+
+type
+  List[A] = ref object
+    value: A
+    next: List[A]
+  StrPair* = tuple[k, v: string]
+  Context* = object
+    position*: int
+    accept*: bool
+    headers*: List[StrPair]
+  Handler* = proc(req: ref Request, ctx: Context): Future[Context]
+
+proc logging*(handler: Handler): auto =
+  proc h(req: ref Request, ctx: Context): Future[Context] {.async.} =
+    let ret = handler(req, ctx)
+    debugEcho "$3 $1 $2".format(req.reqMethod, req.url.path, req.hostname)
+    return await ret
+
+  return h
diff --git a/tests/ccgbugs/tuplecast.nim b/tests/ccgbugs/tuplecast.nim
new file mode 100644
index 000000000..d60e8c490
--- /dev/null
+++ b/tests/ccgbugs/tuplecast.nim
@@ -0,0 +1,8 @@
+
+# bug #4345
+
+# only needs to compile
+proc f(): tuple[a, b: uint8] = (1'u8, 2'u8)
+
+let a, b = f()
+let c = cast[int](b)
diff --git a/tests/closure/uclosures.nim b/tests/closure/uclosures.nim
index 817bfec6b..f259cfeb9 100644
--- a/tests/closure/uclosures.nim
+++ b/tests/closure/uclosures.nim
@@ -1,12 +1,23 @@
+# This test is included from within tunittests
 import unittest
 
-test "loop variables are captured by copy":
+test "loop variables are captured by ref":
   var funcs: seq[proc (): int {.closure.}] = @[]
 
   for i in 0..10:
     let ii = i
     funcs.add do -> int: return ii * ii
 
+  check funcs[0]() == 100
+  check funcs[3]() == 100
+
+test "loop variables in closureScope are captured by copy":
+  var funcs: seq[proc (): int {.closure.}] = @[]
+
+  for i in 0..10:
+    closureScope:
+      let ii = i
+      funcs.add do -> int: return ii * ii
+
   check funcs[0]() == 0
   check funcs[3]() == 9
-
diff --git a/tests/converter/tconverter_with_varargs.nim b/tests/converter/tconverter_with_varargs.nim
new file mode 100644
index 000000000..6d7e31e85
--- /dev/null
+++ b/tests/converter/tconverter_with_varargs.nim
@@ -0,0 +1,18 @@
+
+# bug #888
+
+type
+  PyRef = object
+  PPyRef* = ref PyRef
+
+converter to_py*(i: int) : PPyRef = nil
+
+when false:
+  proc to_tuple*(vals: openarray[PPyRef]): PPyRef =
+    discard
+
+proc abc(args: varargs[PPyRef]) =
+  #let args_tup = to_tuple(args)
+  discard
+
+abc(1, 2)
diff --git a/tests/generics/t88.nim b/tests/generics/t88.nim
new file mode 100644
index 000000000..93d93f063
--- /dev/null
+++ b/tests/generics/t88.nim
@@ -0,0 +1,25 @@
+# Issue 88
+
+type
+  BaseClass[V] = object of RootObj
+    b: V
+
+proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] =
+  BaseClass[V](b: v)
+
+proc baseMethod[V](v: BaseClass[V]): V = v.b
+proc overridedMethod[V](v: BaseClass[V]): V = v.baseMethod
+
+type
+  ChildClass[V] = object of BaseClass[V]
+    c: V
+
+proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] =
+  ChildClass[V](b: v1, c: v2)
+
+proc overridedMethod[V](v: ChildClass[V]): V = v.c
+
+let c = ChildClass[string].new("Base", "Child")
+
+assert c.baseMethod == "Base"
+assert c.overridedMethod == "Child"
diff --git a/tests/generics/tforward_generic.nim b/tests/generics/tforward_generic.nim
new file mode 100644
index 000000000..169279cb3
--- /dev/null
+++ b/tests/generics/tforward_generic.nim
@@ -0,0 +1,28 @@
+discard """
+  output: '''b()
+720 120.0'''
+"""
+
+# bug #3055
+proc b(t: int | string)
+proc a(t: int) = b(t)
+proc b(t: int | string) = echo "b()"
+a(1)
+
+# test recursive generics still work:
+proc fac[T](x: T): T =
+  if x == 0: return 1
+  else: return fac(x-1)*x
+
+echo fac(6), " ", fac(5.0)
+
+when false:
+  # This still doesn't work...
+  # test recursive generic with forwarding:
+  proc fac2[T](x: T): T
+
+  echo fac2(6), " ", fac2(5.0)
+
+  proc fac2[T](x: T): T =
+    if x == 0: return 1
+    else: return fac2(x-1)*x
diff --git a/tests/js/tstring_assignment.nim b/tests/js/tstring_assignment.nim
new file mode 100644
index 000000000..bdd93e6b5
--- /dev/null
+++ b/tests/js/tstring_assignment.nim
@@ -0,0 +1,11 @@
+discard """
+  output: '''true'''
+"""
+
+# bug #4471
+when true:
+  let s1 = "123"
+  var s2 = s1
+  s2.setLen(0)
+  # fails - s1.len == 0
+  echo s1.len == 3
diff --git a/tests/macros/tcomplexecho.nim b/tests/macros/tcomplexecho.nim
new file mode 100644
index 000000000..f7f933c1c
--- /dev/null
+++ b/tests/macros/tcomplexecho.nim
@@ -0,0 +1,42 @@
+discard """
+  output: '''3
+OK
+56
+123
+56
+61'''
+"""
+
+import macros
+
+# Bug from the forum
+macro addEcho1(s: untyped): stmt =
+  s.body.add(newCall("echo", newStrLitNode("OK")))
+  result = s
+
+proc f1() {.addEcho1.} =
+  let i = 1+2
+  echo i
+
+f1()
+
+# bug #537
+proc test(): seq[NimNode] {.compiletime.} =
+  result = @[]
+  result.add parseExpr("echo 56")
+  result.add parseExpr("echo 123")
+  result.add parseExpr("echo 56")
+
+proc foo(): seq[NimNode] {.compiletime.} =
+  result = @[]
+  result.add test()
+  result.add parseExpr("echo(5+56)")
+
+macro bar(): stmt =
+  result = newNimNode(nnkStmtList)
+  let x = foo()
+  for xx in x:
+    result.add xx
+  echo treeRepr(result)
+
+bar()
diff --git a/tests/macros/tvarargsuntyped.nim b/tests/macros/tvarargsuntyped.nim
new file mode 100644
index 000000000..b7d2bc001
--- /dev/null
+++ b/tests/macros/tvarargsuntyped.nim
@@ -0,0 +1,79 @@
+discard """
+  output: '''Let's go!
+(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)
+(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 1, g: 7, b: 8)
+(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 4, g: 7, b: 8)
+(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)'''
+"""
+
+import macros
+
+proc internalBar(top, left, width, height: cint, s: string, x, y: int, r,g,b: int) =
+  echo locals()
+
+# we need these dummy constructors due to the wrong implementation
+# of 'varargs[untyped]' in the compiler:
+
+proc point(x, y: int): int = discard
+proc color(r, g, b: int): int = discard
+proc rect(a, b, c, d: int): int = discard
+
+template declareUnpackingMacro(nimname,extname) =
+  macro nimname(n: varargs[untyped]): untyped =
+    var s: string = astToStr(extname) & "("
+    var first = true
+    echo repr n
+    for x in n.children:
+      var unpack = false
+      if x.kind in nnkCallKinds:
+        case $x[0]
+        of "point":
+          expectLen(x, 3)
+          unpack = true
+        of "rect":
+          expectLen(x, 5)
+          unpack = true
+        of "color":
+          expectLen(x, 4)
+          unpack = true
+        else: discard
+      if unpack:
+        for i in 1..<x.len:
+          if first:
+            first = false
+          else:
+            add(s, ", ")
+          add(s, repr(x[i]))
+      else:
+        if first:
+          first = false
+        else:
+          add(s, ", ")
+        add(s, repr(x))
+
+    add(s, ")")
+    echo s
+    result = parseStmt(s)
+
+declareUnpackingMacro(bar,internalBar)
+
+type MyInt = distinct int
+
+proc myInt(i: int): MyInt = cast[MyInt](i)
+
+converter toCInt(mi: MyInt): cint = cast[cint](mi)
+
+echo "Let's go!"
+
+bar(rect(1, 2, 3, 4), "test", point(8, 9), color(7,7,8))
+
+bar(1,2,3,4,"text",8,9,7,7,8)
+
+bar(myInt(4),2,3,4,"text",8,9,7,7,8)
+
+let top: cint = 1
+let left: cint = 2
+let width: cint = 3
+let height: cint = 4
+
+bar(rect(top, left, width, height), "test", point(8, 9), color(7,7,8))
diff --git a/tests/metatype/tautoproc.nim b/tests/metatype/tautoproc.nim
index ef5377096..2c8f6a3f7 100644
--- a/tests/metatype/tautoproc.nim
+++ b/tests/metatype/tautoproc.nim
@@ -1,5 +1,5 @@
 discard """
-  output: "empty"
+  output: "void"
 """
 
 # bug #898
diff --git a/tests/metatype/tmodulo.nim b/tests/metatype/tmodulo.nim
new file mode 100644
index 000000000..08bcc7935
--- /dev/null
+++ b/tests/metatype/tmodulo.nim
@@ -0,0 +1,20 @@
+discard """
+  output: '''1 mod 7'''
+"""
+
+# bug #3706
+
+type Modulo[M: static[int]] = distinct int
+
+proc modulo(a: int, M: static[int]): Modulo[M] = Modulo[M](a %% M)
+
+proc `+`[M: static[int]](a, b: Modulo[M]): Modulo[M] = (a.int + b.int).modulo(M)
+
+proc `$`*[M: static[int]](a: Modulo[M]): string = $(a.int) & " mod " & $(M)
+
+when isMainModule:
+  let
+    a = 3.modulo(7)
+    b = 5.modulo(7)
+  echo a + b
+
diff --git a/tests/metatype/tvoid_must_not_match.nim b/tests/metatype/tvoid_must_not_match.nim
new file mode 100644
index 000000000..240c3f751
--- /dev/null
+++ b/tests/metatype/tvoid_must_not_match.nim
@@ -0,0 +1,21 @@
+discard """
+  errormsg: "type mismatch: got (Future[system.int], void)"
+  line: 20
+"""
+
+type
+  Future[T] = object
+    value: T
+
+proc complete[T](x: T) =
+  echo "completed"
+  let y = x
+
+
+proc complete*[T](future: var Future[T], val: T) =
+  future.value = val
+
+var a: Future[int]
+
+complete(a):
+  echo "yielding void"
diff --git a/tests/method/tgeneric_methods.nim b/tests/method/tgeneric_methods.nim
new file mode 100644
index 000000000..76a68fbb0
--- /dev/null
+++ b/tests/method/tgeneric_methods.nim
@@ -0,0 +1,24 @@
+discard """
+  output: "wow2"
+"""
+type
+  First[T] = ref object of RootObj
+    value: T
+
+  Second[T] = ref object of First[T]
+    value2: T
+
+method wow[T](y: int; x: First[T]) {.base.} =
+  echo "wow1"
+
+method wow[T](y: int; x: Second[T]) =
+  echo "wow2"
+
+var
+  x: Second[int]
+new(x)
+
+proc takeFirst(x: First[int]) =
+  wow(2, x)
+
+takeFirst(x)
diff --git a/tests/method/tmultim6.nim b/tests/method/tmultim6.nim
index 97ed2845c..2c622b832 100644
--- a/tests/method/tmultim6.nim
+++ b/tests/method/tmultim6.nim
@@ -4,27 +4,27 @@ discard """
 # Test multi methods
 
 type
-  TThing = object {.inheritable.}
-  TUnit[T] = object of TThing
+  Thing = object {.inheritable.}
+  Unit[T] = object of Thing
     x: T
-  TParticle = object of TThing
+  Particle = object of Thing
     a, b: int
 
-method collide(a, b: TThing) {.base, inline.} =
+method collide(a, b: Thing) {.base, inline.} =
   quit "to override!"
 
-method collide[T](a: TThing, b: TUnit[T]) {.inline.} =
+method collide[T](a: Thing, b: Unit[T]) {.inline.} =
   write stdout, "collide: thing, unit | "
 
-method collide[T](a: TUnit[T], b: TThing) {.inline.} =
+method collide[T](a: Unit[T], b: Thing) {.inline.} =
   write stdout, "collide: unit, thing | "
 
-proc test(a, b: TThing) {.inline.} =
+proc test(a, b: Thing) {.inline.} =
   collide(a, b)
 
 var
-  a: TThing
-  b, c: TUnit[string]
-collide(b, TThing(c))
+  a: Thing
+  b, c: Unit[string]
+collide(b, Thing(c))
 test(b, c)
 collide(a, b)
diff --git a/tests/modules/texplicit_system_import.nim b/tests/modules/texplicit_system_import.nim
new file mode 100644
index 000000000..bc4d018bf
--- /dev/null
+++ b/tests/modules/texplicit_system_import.nim
@@ -0,0 +1,9 @@
+##.
+import system except `+`
+discard """
+  errormsg: "undeclared identifier: '+'"
+  line: 9
+"""
+# Testament requires that the initial """ occurs before the 40th byte
+# in the file. No kidding...
+echo 4+5
diff --git a/tests/newconfig/mymath.nim b/tests/newconfig/mymath.nim
new file mode 100644
index 000000000..5668b448b
--- /dev/null
+++ b/tests/newconfig/mymath.nim
@@ -0,0 +1,4 @@
+
+
+proc ln*(x: float): float =
+  return 0.5
diff --git a/tests/newconfig/tfoo.nim b/tests/newconfig/tfoo.nim
index d593d4a75..2e10167b1 100644
--- a/tests/newconfig/tfoo.nim
+++ b/tests/newconfig/tfoo.nim
@@ -1,10 +1,12 @@
 discard """
   cmd: "nim default $file"
-  output: '''hello world!'''
+  output: '''hello world! 0.5'''
   msg: '''[NimScript] exec: gcc -v'''
 """
 
 when not defined(definedefine):
   {.fatal: "wrong nim script configuration".}
 
-echo "hello world!"
+import math
+
+echo "hello world! ", ln 2.0
diff --git a/tests/newconfig/tfoo.nims b/tests/newconfig/tfoo.nims
index 519a868d5..057c0ed92 100644
--- a/tests/newconfig/tfoo.nims
+++ b/tests/newconfig/tfoo.nims
@@ -8,6 +8,11 @@ import ospaths
 
 --forceBuild
 
+warning("uninit", off)
+hint("processing", off)
+#--verbosity:2
+patchFile("stdlib", "math", "mymath")
+
 task listDirs, "lists every subdirectory":
   for x in listDirs("."):
     echo "DIR ", x
diff --git a/tests/osproc/passenv.nim b/tests/osproc/passenv.nim
new file mode 100644
index 000000000..815f7536f
--- /dev/null
+++ b/tests/osproc/passenv.nim
@@ -0,0 +1,32 @@
+discard """
+  file: "passenv.nim"
+  output: "123"
+  targets: "c c++ objc"
+"""
+
+import osproc, os, strtabs
+
+# Checks that the environment is passed correctly in startProcess
+# To do that launches a copy of itself with a new environment.
+
+if paramCount() == 0:
+  # Parent process
+
+  let env = newStringTable()
+  env["A"] = "1"
+  env["B"] = "2"
+  env["C"] = "3"
+
+  let p = startProcess(
+    getAppFilename(),
+    args = @["child"],
+    env = env,
+    options = {poStdErrToStdOut, poUsePath, poParentStreams}
+  )
+
+  discard p.waitForExit
+
+else:
+  # Child process
+  # should output "123"
+  echo getEnv("A") & getEnv("B") & getEnv("C")
diff --git a/tests/overload/tissue4475.nim b/tests/overload/tissue4475.nim
new file mode 100644
index 000000000..34618cac5
--- /dev/null
+++ b/tests/overload/tissue4475.nim
@@ -0,0 +1,6 @@
+# Bug: https://github.com/nim-lang/Nim/issues/4475
+# Fix: https://github.com/nim-lang/Nim/pull/4477
+
+proc test(x: varargs[string], y: int) = discard
+
+test(y = 1)
diff --git a/tests/stdlib/thtmlparser2814.nim b/tests/stdlib/thtmlparser2814.nim
new file mode 100644
index 000000000..968d390f1
--- /dev/null
+++ b/tests/stdlib/thtmlparser2814.nim
@@ -0,0 +1,44 @@
+discard """
+  output: true
+"""
+import htmlparser
+import xmltree
+import strutils
+from streams import newStringStream
+
+
+## builds the two cases below and test that
+## ``//[dd,li]`` has "<p>that</p>" as children
+##
+##  <dl>
+##    <dt>this</dt>
+##    <dd>
+##      <p>that</p>
+##    </dd>
+##  </dl>
+
+##
+## <ul>
+##   <li>
+##     <p>that</p>
+##   </li>
+## </ul>
+
+
+for ltype in [["dl","dd"], ["ul","li"]]:
+  let desc_item = if ltype[0]=="dl": "<dt>this</dt>" else: ""
+  let item = "$1<$2><p>that</p></$2>" % [desc_item, ltype[1]]
+  let list = """ <$1>
+   $2
+</$1> """ % [ltype[0], item]
+
+  var errors : seq[string] = @[]
+
+  let parseH = parseHtml(newStringStream(list),"statichtml", errors =errors)
+
+  if $parseH.findAll(ltype[1])[0].child("p") != "<p>that</p>":
+    echo "case " & ltype[0] & " failed !"
+    quit(2)
+
+
+echo "true"
diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim
index cae388792..1ddaacfcb 100644
--- a/tests/stdlib/tos.nim
+++ b/tests/stdlib/tos.nim
@@ -1,12 +1,88 @@
-# test some things of the os module
+discard """
+  output: '''true
+true
+true
+true
+true
+true
+true
+true
+true
+All:
+__really_obscure_dir_name/are.x
+__really_obscure_dir_name/created
+__really_obscure_dir_name/dirs
+__really_obscure_dir_name/files.q
+__really_obscure_dir_name/some
+__really_obscure_dir_name/test
+__really_obscure_dir_name/testing.r
+__really_obscure_dir_name/these.txt
+Files:
+__really_obscure_dir_name/are.x
+__really_obscure_dir_name/files.q
+__really_obscure_dir_name/testing.r
+__really_obscure_dir_name/these.txt
+Dirs:
+__really_obscure_dir_name/created
+__really_obscure_dir_name/dirs
+__really_obscure_dir_name/some
+__really_obscure_dir_name/test
+false
+false
+false
+false
+false
+false
+false
+false
+false
+'''
+"""
+# test os path creation, iteration, and deletion
 
 import os
 
-proc walkDirTree(root: string) =
-  for k, f in walkDir(root):
-    case k
-    of pcFile, pcLinkToFile: echo(f)
-    of pcDir: walkDirTree(f)
-    of pcLinkToDir: discard
+let files = @["these.txt", "are.x", "testing.r", "files.q"]
+let dirs = @["some", "created", "test", "dirs"]
 
-walkDirTree(".")
+let dname = "__really_obscure_dir_name"
+
+createDir(dname)
+echo dirExists(dname)
+
+# Test creating files and dirs
+for dir in dirs:
+  createDir(dname/dir)
+  echo dirExists(dname/dir)
+
+for file in files:
+  let fh = open(dname/file, fmReadWrite)
+  fh.close()
+  echo fileExists(dname/file)
+
+echo "All:"
+
+for path in walkPattern(dname/"*"):
+  echo path
+
+echo "Files:"
+
+for path in walkFiles(dname/"*"):
+  echo path
+
+echo "Dirs:"
+
+for path in walkDirs(dname/"*"):
+  echo path
+
+# Test removal of files dirs
+for dir in dirs:
+  removeDir(dname/dir)
+  echo dirExists(dname/dir)
+
+for file in files:
+  removeFile(dname/file)
+  echo fileExists(dname/file)
+
+removeDir(dname)
+echo dirExists(dname)
diff --git a/tests/stdlib/tsplit.nim b/tests/stdlib/tsplit.nim
index 5a1cd2f5f..44da58aca 100644
--- a/tests/stdlib/tsplit.nim
+++ b/tests/stdlib/tsplit.nim
@@ -9,7 +9,7 @@ for w in split("|abc|xy|z", {'|'}):
   s.add("#")
   s.add(w)
 
-if s == "#abc#xy#z":
+if s == "##abc#xy#z":
   echo "true"
 else:
   echo "false"
diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim
index 73113ac68..e87cd3508 100644
--- a/tests/stdlib/tunittest.nim
+++ b/tests/stdlib/tunittest.nim
@@ -83,3 +83,9 @@ suite "suite with both":
 
   test "unittest with both 2":
     check c == 2
+
+suite "bug #4494":
+    test "Uniqueness check":
+      var tags = @[1, 2, 3, 4, 5]
+      check:
+        allIt(0..3, tags[it] != tags[it + 1])
diff --git a/tests/tuples/tconver_tuple.nim b/tests/tuples/tconver_tuple.nim
new file mode 100644
index 000000000..306da77fe
--- /dev/null
+++ b/tests/tuples/tconver_tuple.nim
@@ -0,0 +1,23 @@
+# Bug 4479
+
+type
+  MyTuple = tuple
+    num: int
+    strings: seq[string]
+    ints: seq[int]
+
+var foo = MyTuple((
+  num: 7,
+  strings: @[],
+  ints: @[],
+))
+
+var bar = (
+  num: 7,
+  strings: @[],
+  ints: @[],
+).MyTuple
+
+var fooUnnamed = MyTuple((7, @[], @[]))
+var n = 7
+var fooSym = MyTuple((num: n, strings: @[], ints: @[]))
diff --git a/tests/tuples/twrong_generic_caching.nim b/tests/tuples/twrong_generic_caching.nim
new file mode 100644
index 000000000..32ef344d2
--- /dev/null
+++ b/tests/tuples/twrong_generic_caching.nim
@@ -0,0 +1,4 @@
+
+import parsecfg
+
+import asynchttpserver
diff --git a/tests/typerel/tclosure_nil_as_default.nim b/tests/typerel/tclosure_nil_as_default.nim
new file mode 100644
index 000000000..fe9f42b14
--- /dev/null
+++ b/tests/typerel/tclosure_nil_as_default.nim
@@ -0,0 +1,11 @@
+
+# bug #4328
+type
+    foo[T] = object
+        z: T
+
+proc test[T](x: foo[T], p: proc(a: T) = nil) =
+    discard
+
+var d: foo[int]
+d.test()  # <- param omitted
diff --git a/tests/typerel/temptynode.nim b/tests/typerel/temptynode.nim
index 91e45f3ca..b32b16121 100644
--- a/tests/typerel/temptynode.nim
+++ b/tests/typerel/temptynode.nim
@@ -1,6 +1,6 @@
 discard """
   line: 16
-  errormsg: "type mismatch: got (empty)"
+  errormsg: "type mismatch: got (void)"
 """
 
 # bug #950
diff --git a/tests/typerel/tgeneric_subtype_regression.nim b/tests/typerel/tgeneric_subtype_regression.nim
new file mode 100644
index 000000000..e279c0ad4
--- /dev/null
+++ b/tests/typerel/tgeneric_subtype_regression.nim
@@ -0,0 +1,19 @@
+discard """
+  errormsg: "type mismatch: got (FooRef[system.string])"
+  line: 15
+"""
+
+# bug #4478
+
+type
+  Foo[T] = object
+  FooRef[T] = ref Foo[T]
+
+proc takeFoo[T](foo: Foo[T]): int = discard
+
+proc g(x: FooRef[string]) =
+  echo x.takeFoo() != 8
+
+var x: FooRef[string]
+
+g(x)
diff --git a/tests/types/tassignemptytuple.nim b/tests/types/tassignemptytuple.nim
new file mode 100644
index 000000000..bdfc653a5
--- /dev/null
+++ b/tests/types/tassignemptytuple.nim
@@ -0,0 +1,11 @@
+discard """
+  file: "tassignemptytuple.nim"
+  line: 11
+  errormsg: "cannot infer the type of the tuple"
+"""
+
+var
+  foo: seq[int]
+  bar: tuple[a: seq[int], b: set[char]]
+
+(foo, bar) = (@[], (@[], {}))
diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim
new file mode 100644
index 000000000..b7112b099
--- /dev/null
+++ b/tests/vm/tvmmisc.nim
@@ -0,0 +1,16 @@
+
+
+# bug #4462
+import macros
+
+proc foo(t: typedesc) {.compileTime.} =
+  echo getType(t).treeRepr
+
+static:
+  foo(int)
+
+# #4412
+proc default[T](t: typedesc[T]): T {.inline.} = discard
+
+static:
+  var x = default(type(0))