summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2018-06-08 19:50:36 +0200
committerAraq <rumpf_a@web.de>2018-06-08 19:50:36 +0200
commit8e9551b1c7614029f12e7d62ba81f367d1aaf6bd (patch)
tree6aaa97a9734784ab5a65d1d2975100e4dd9872d1 /tests
parent8ba7e7d807c37a0988abd69ef9824b4822fe04f3 (diff)
parentf99acdb07584d2c4c5eb1f22d998d97bcd823357 (diff)
downloadNim-8e9551b1c7614029f12e7d62ba81f367d1aaf6bd.tar.gz
fixex merge conflicts
Diffstat (limited to 'tests')
-rw-r--r--tests/array/t7818.nim141
-rw-r--r--tests/async/t7985.nim19
-rw-r--r--tests/async/tasync_in_seq_constr.nim21
-rw-r--r--tests/async/tasync_traceback.nim30
-rw-r--r--tests/async/tasynctry.nim4
-rw-r--r--tests/async/tasynctry2.nim4
-rw-r--r--tests/collections/tcollections_to_string.nim6
-rw-r--r--tests/iter/tyieldintry.nim407
-rw-r--r--tests/lexer/thexlit.nim12
-rw-r--r--tests/lexer/thexrange.nim8
-rw-r--r--tests/lexer/tlexermisc.nim27
-rw-r--r--tests/stdlib/tos.nim10
-rw-r--r--tests/stdlib/tstrformat.nim34
-rw-r--r--tests/system/tsystem_misc.nim39
-rw-r--r--tests/typerel/t4799.nim245
-rw-r--r--tests/typerel/t4799_1.nim20
-rw-r--r--tests/typerel/t4799_2.nim20
-rw-r--r--tests/typerel/t4799_3.nim20
-rw-r--r--tests/vm/tvmmisc.nim8
19 files changed, 1008 insertions, 67 deletions
diff --git a/tests/array/t7818.nim b/tests/array/t7818.nim
index 5d73efec5..4e43bff85 100644
--- a/tests/array/t7818.nim
+++ b/tests/array/t7818.nim
@@ -1,24 +1,5 @@
 discard """
-  msg: '''BracketExpr
-  Sym "array"
-  Infix
-    Ident ".."
-    IntLit 0
-    IntLit 2
-  BracketExpr
-    Sym "Vehicle"
-    Sym "int"
----------
-BracketExpr
-  Sym "array"
-  Infix
-    Ident ".."
-    IntLit 0
-    IntLit 2
-  BracketExpr
-    Sym "Vehicle"
-    Sym "int"
----------'''
+  output: "OK"
 """
 
 # bug #7818
@@ -34,12 +15,118 @@ type
   Bike[T] = object of Vehicle[T]
 
 macro peek(n: typed): untyped =
-  echo getTypeImpl(n).treeRepr
-  echo "---------"
+  let val = getTypeImpl(n).treeRepr
+  newLit(val)
+
+block test_t7818:
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_1:
+  proc init(x: typedesc, y: int): ref x =
+    result = new(ref x)
+    result.tire = y
+  
+  var v = init(Vehicle[int], 3)
+  var c = init(Car[int], 4)
+  var b = init(Bike[int], 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_2:
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  let y = peek([c.addr, b.addr, v.addr])
+  let z = peek([v.addr, c.addr, b.addr])
+  doAssert(y == z)
+
+block test_t7906_3:
+  type
+    Animal[T] = object of RootObj
+      hair: T
+    Mammal[T] = object of Animal[T]
+    Monkey[T] = object of Mammal[T]
+
+  var v = Animal[int](hair: 3)
+  var c = Mammal[int](hair: 4)
+  var b = Monkey[int](hair: 2)
+
+  let z = peek([c.addr, b.addr, v.addr])
+  let y = peek([v.addr, c.addr, b.addr])
+  doAssert(y == z)
+  
+type
+  Fruit[T] = ref object of RootObj
+    color: T
+  Apple[T] = ref object of Fruit[T]
+  Banana[T] = ref object of Fruit[T]
+    
+proc testArray[T](x: array[3, Fruit[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.color
+
+proc testOpenArray[T](x: openArray[Fruit[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.color
+    
+block test_t7906_4:
+  var v = Fruit[int](color: 3)
+  var c = Apple[int](color: 4)
+  var b = Banana[int](color: 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_5:
+  var a = Fruit[int](color: 1)
+  var b = Apple[int](color: 2)
+  var c = Banana[int](color: 3)
+
+  doAssert(testArray([a, b, c]) == "123")
+  doAssert(testArray([b, c, a]) == "231")
+
+  doAssert(testOpenArray([a, b, c]) == "123")
+  doAssert(testOpenArray([b, c, a]) == "231")
+
+  doAssert(testOpenArray(@[a, b, c]) == "123")
+  doAssert(testOpenArray(@[b, c, a]) == "231")
+
+proc testArray[T](x: array[3, ptr Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+proc testOpenArray[T](x: openArray[ptr Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+block test_t7906_6:
+  var u = Vehicle[int](tire: 1)
+  var v = Bike[int](tire: 2)
+  var w = Car[int](tire: 3)
+  
+  doAssert(testArray([u.addr, v.addr, w.addr]) == "123")
+  doAssert(testArray([w.addr, u.addr, v.addr]) == "312")
+  
+  doAssert(testOpenArray([u.addr, v.addr, w.addr]) == "123")
+  doAssert(testOpenArray([w.addr, u.addr, v.addr]) == "312")
+  
+  doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123")
+  doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312")
+  
+echo "OK"
 
-var v = Vehicle[int](tire: 3)
-var c = Car[int](tire: 4)
-var b = Bike[int](tire: 2)
 
-peek([c, b, v])
-peek([v, c, b])
diff --git a/tests/async/t7985.nim b/tests/async/t7985.nim
new file mode 100644
index 000000000..0365499d3
--- /dev/null
+++ b/tests/async/t7985.nim
@@ -0,0 +1,19 @@
+discard """
+  file: "t7985.nim"
+  exitcode: 0
+  output: "(value: 1)"
+"""
+import json, asyncdispatch
+
+proc getData(): Future[JsonNode] {.async.} =
+  result = %*{"value": 1}
+
+type
+  MyData = object
+    value: BiggestInt
+
+proc main() {.async.} =
+  let data = to(await(getData()), MyData)
+  echo data
+
+waitFor(main())
diff --git a/tests/async/tasync_in_seq_constr.nim b/tests/async/tasync_in_seq_constr.nim
index 46ad74451..3d6dae245 100644
--- a/tests/async/tasync_in_seq_constr.nim
+++ b/tests/async/tasync_in_seq_constr.nim
@@ -1,18 +1,25 @@
 discard """
-  errormsg: "invalid control flow: 'yield' within a constructor"
-  line: 16
+  output: '''
+@[1, 2, 3, 4]
+123
+'''
 """
 
 # bug #5314, bug #6626
 
 import asyncdispatch
 
-proc bar(): Future[int] {.async.} =
-    await sleepAsync(500)
-    result = 3
+proc bar(i: int): Future[int] {.async.} =
+    await sleepAsync(2)
+    result = i
 
 proc foo(): Future[seq[int]] {.async.} =
-    await sleepAsync(500)
-    result = @[1, 2, await bar(), 4] # <--- The bug is here
+    await sleepAsync(2)
+    result = @[1, 2, await bar(3), 4] # <--- The bug is here
+
+proc foo2() {.async.} =
+    await sleepAsync(2)
+    echo(await bar(1), await bar(2), await bar(3))
 
 echo waitFor foo()
+waitFor foo2()
diff --git a/tests/async/tasync_traceback.nim b/tests/async/tasync_traceback.nim
index e4c8a67b3..b6c6a916b 100644
--- a/tests/async/tasync_traceback.nim
+++ b/tests/async/tasync_traceback.nim
@@ -3,7 +3,7 @@ discard """
   disabled: "windows"
   output: "Matched"
 """
-import asyncdispatch
+import asyncdispatch, strutils
 
 # Tests to ensure our exception trace backs are friendly.
 
@@ -82,7 +82,7 @@ Async traceback:
     asyncmacro\.nim\(\d+?\)\s+?a
     asyncmacro\.nim\(\d+?\)\s+?a_continue
       ## Resumes an async procedure
-    asyncmacro\.nim\(\d+?\)\s+?aIter
+    tasync_traceback\.nim\(\d+?\)\s+?aIter
     asyncfutures\.nim\(\d+?\)\s+?read
   \]#
 Exception message: b failure
@@ -110,17 +110,33 @@ Async traceback:
       ## Executes pending callbacks
     asyncmacro\.nim\(\d+?\)\s+?foo_continue
       ## Resumes an async procedure
-    asyncmacro\.nim\(\d+?\)\s+?fooIter
+    tasync_traceback\.nim\(\d+?\)\s+?fooIter
     asyncfutures\.nim\(\d+?\)\s+?read
   \]#
 Exception message: bar failure
 Exception type:
 """
 
-if result.match(re(expected)):
-  echo("Matched")
-else:
-  echo("Not matched!")
+let resLines = splitLines(result.strip)
+let expLines = splitLines(expected.strip)
+
+if resLines.len != expLines.len:
+  echo("Not matched! Wrong number of lines!")
   echo()
   echo(result)
   quit(QuitFailure)
+
+var ok = true
+for i in 0 ..< resLines.len:
+  if not resLines[i].match(re(expLines[i])):
+    echo "Not matched! Line ", i + 1
+    echo "Expected:"
+    echo expLines[i]
+    echo "Actual:"
+    echo resLines[i]
+    ok = false
+
+if ok:
+  echo("Matched")
+else:
+  quit(QuitFailure)
diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim
index 5930f296f..6749aabbf 100644
--- a/tests/async/tasynctry.nim
+++ b/tests/async/tasynctry.nim
@@ -9,7 +9,7 @@ Multiple except branches
 Multiple except branches 2
 '''
 """
-import asyncdispatch
+import asyncdispatch, strutils
 
 # Here we are testing the ability to catch exceptions.
 
@@ -22,7 +22,7 @@ proc catch() {.async.} =
   try:
     await foobar()
   except:
-    echo("Generic except: ", getCurrentExceptionMsg())
+    echo("Generic except: ", getCurrentExceptionMsg().splitLines[0])
 
   try:
     await foobar()
diff --git a/tests/async/tasynctry2.nim b/tests/async/tasynctry2.nim
index 444a058be..4b3f17cc5 100644
--- a/tests/async/tasynctry2.nim
+++ b/tests/async/tasynctry2.nim
@@ -1,10 +1,12 @@
 discard """
   file: "tasynctry2.nim"
   errormsg: "\'yield\' cannot be used within \'try\' in a non-inlined iterator"
-  line: 15
+  line: 14
 """
 import asyncdispatch
 
+{.experimental: "oldIterTransf".}
+
 proc foo(): Future[bool] {.async.} = discard
 
 proc test5(): Future[int] {.async.} =
diff --git a/tests/collections/tcollections_to_string.nim b/tests/collections/tcollections_to_string.nim
index 48b06a6aa..0c4f1e91c 100644
--- a/tests/collections/tcollections_to_string.nim
+++ b/tests/collections/tcollections_to_string.nim
@@ -68,15 +68,15 @@ block:
 block:
   var t: CritBitTree[int]
   t["a"] = 1
-  doAssert $t == "{a: 1}"
+  doAssert $t == """{"a": 1}"""
 block:
   var t: CritBitTree[string]
   t["a"] = "1"
-  doAssert $t == """{a: "1"}"""
+  doAssert $t == """{"a": "1"}"""
 block:
   var t: CritBitTree[char]
   t["a"] = '1'
-  doAssert $t == "{a: '1'}"
+  doAssert $t == """{"a": '1'}"""
 
 
 # Test escaping behavior
diff --git a/tests/iter/tyieldintry.nim b/tests/iter/tyieldintry.nim
new file mode 100644
index 000000000..6f0acb169
--- /dev/null
+++ b/tests/iter/tyieldintry.nim
@@ -0,0 +1,407 @@
+discard """
+targets: "c cpp"
+output: "ok"
+"""
+var closureIterResult = newSeq[int]()
+
+proc checkpoint(arg: int) =
+  closureIterResult.add(arg)
+
+type
+  TestException = object of Exception
+  AnotherException = object of Exception
+
+proc testClosureIterAux(it: iterator(): int, exceptionExpected: bool, expectedResults: varargs[int]) =
+  closureIterResult.setLen(0)
+
+  var exceptionCaught = false
+
+  try:
+    for i in it():
+      closureIterResult.add(i)
+  except TestException:
+    exceptionCaught = true
+
+  if closureIterResult != @expectedResults or exceptionCaught != exceptionExpected:
+    if closureIterResult != @expectedResults:
+      echo "Expected: ", @expectedResults
+      echo "Actual: ", closureIterResult
+    if exceptionCaught != exceptionExpected:
+      echo "Expected exception: ", exceptionExpected
+      echo "Got exception: ", exceptionCaught
+    doAssert(false)
+
+proc test(it: iterator(): int, expectedResults: varargs[int]) =
+  testClosureIterAux(it, false, expectedResults)
+
+proc testExc(it: iterator(): int, expectedResults: varargs[int]) =
+  testClosureIterAux(it, true, expectedResults)
+
+proc raiseException() =
+  raise newException(TestException, "Test exception!")
+
+block:
+  iterator it(): int {.closure.} =
+    var i = 5
+    while i != 0:
+      yield i
+      if i == 3:
+        yield 123
+      dec i
+
+  test(it, 5, 4, 3, 123, 2, 1)
+
+block:
+  iterator it(): int {.closure.} =
+    yield 0
+    try:
+      checkpoint(1)
+      raiseException()
+    except TestException:
+      checkpoint(2)
+      yield 3
+      checkpoint(4)
+    finally:
+      checkpoint(5)
+
+    checkpoint(6)
+
+  test(it, 0, 1, 2, 3, 4, 5, 6)
+
+block:
+  iterator it(): int {.closure.} =
+    yield 0
+    try:
+      yield 1
+      checkpoint(2)
+    finally:
+      checkpoint(3)
+      yield 4
+      checkpoint(5)
+      yield 6
+
+  test(it, 0, 1, 2, 3, 4, 5, 6)
+
+block:
+  iterator it(): int {.closure.} =
+    yield 0
+    try:
+      yield 1
+      raiseException()
+      yield 2
+    finally:
+      checkpoint(3)
+      yield 4
+      checkpoint(5)
+      yield 6
+
+  testExc(it, 0, 1, 3, 4, 5, 6)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      try:
+        raiseException()
+      except AnotherException:
+        yield 123
+      finally:
+        checkpoint(3)
+    finally:
+      checkpoint(4)
+
+  testExc(it, 3, 4)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      yield 1
+      raiseException()
+    except AnotherException:
+      checkpoint(123)
+    finally:
+      checkpoint(2)
+    checkpoint(3)
+
+  testExc(it, 1, 2)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      yield 0
+      try:
+        yield 1
+        try:
+          yield 2
+          raiseException()
+        except AnotherException:
+          yield 123
+        finally:
+          yield 3
+      except AnotherException:
+        yield 124
+      finally:
+        yield 4
+      checkpoint(1234)
+    except:
+      yield 5
+      checkpoint(6)
+    finally:
+      checkpoint(7)
+      yield 8
+    checkpoint(9)
+
+  test(it, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      yield 0
+      return 2
+    finally:
+      checkpoint(1)
+    checkpoint(123)
+
+  test(it, 0, 1)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      try:
+        yield 0
+        raiseException()
+      finally:
+        checkpoint(1)
+    except TestException:
+      yield 2
+      return
+    finally:
+      yield 3
+
+    checkpoint(123)
+
+  test(it, 0, 1, 2, 3)
+
+block:
+  iterator it(): int {.closure.} =
+    try:
+      try:
+        yield 0
+        raiseException()
+      finally:
+        return # Return in finally should stop exception propagation
+    except AnotherException:
+      yield 2
+      return
+    finally:
+      yield 3
+    checkpoint(123)
+
+  test(it, 0, 3)
+
+block: # Yield in yield
+  iterator it(): int {.closure.} =
+    template foo(): int =
+      yield 1
+      2
+
+    for i in 0 .. 2:
+      checkpoint(0)
+      yield foo()
+
+  test(it, 0, 1, 2, 0, 1, 2, 0, 1, 2)
+
+block:
+  iterator it(): int {.closure.} =
+    let i = if true:
+        yield 0
+        1
+      else:
+        2
+    yield i
+
+  test(it, 0, 1)
+
+block:
+  iterator it(): int {.closure.} =
+    var foo = 123
+    let i = try:
+        yield 0
+        raiseException()
+        1
+      except TestException as e:
+        assert(e.msg == "Test exception!")
+        case foo
+        of 1:
+          yield 123
+          2
+        of 123:
+          yield 5
+          6
+        else:
+          7
+    yield i
+
+  test(it, 0, 5, 6)
+
+block:
+  iterator it(): int {.closure.} =
+    proc voidFoo(i1, i2, i3: int) =
+      checkpoint(i1)
+      checkpoint(i2)
+      checkpoint(i3)
+
+    proc foo(i1, i2, i3: int): int =
+      voidFoo(i1, i2, i3)
+      i3
+
+    proc bar(i1: int): int =
+      checkpoint(i1)
+
+    template tryexcept: int =
+      try:
+        yield 1
+        raiseException()
+        123
+      except TestException:
+        yield 2
+        checkpoint(3)
+        4
+
+    let e1 = true
+
+    template ifelse1: int =
+      if e1:
+        yield 10
+        11
+      else:
+        12
+
+    template ifelse2: int =
+      if ifelse1() == 12:
+        yield 20
+        21
+      else:
+        yield 22
+        23
+
+    let i = foo(bar(0), tryexcept, ifelse2)
+    discard foo(bar(0), tryexcept, ifelse2)
+    voidFoo(bar(0), tryexcept, ifelse2)
+    yield i
+
+  test(it,
+
+    # let i = foo(bar(0), tryexcept, ifelse2)
+    0, # bar(0)
+    1, 2, 3, # tryexcept
+    10, # ifelse1
+    22, # ifelse22
+    0, 4, 23, # foo
+
+    # discard foo(bar(0), tryexcept, ifelse2)
+    0, # bar(0)
+    1, 2, 3, # tryexcept
+    10, # ifelse1
+    22, # ifelse22
+    0, 4, 23, # foo
+
+    # voidFoo(bar(0), tryexcept, ifelse2)
+    0, # bar(0)
+    1, 2, 3, # tryexcept
+    10, # ifelse1
+    22, # ifelse22
+    0, 4, 23, # foo
+
+    23 # i
+  )
+
+block:
+  iterator it(): int {.closure.} =
+    checkpoint(0)
+    for i in 0 .. 1:
+      try:
+        yield 1
+        raiseException()
+      except TestException as e:
+        doAssert(e.msg == "Test exception!")
+        yield 2
+      except AnotherException:
+        yield 123
+      except:
+        yield 1234
+      finally:
+        yield 3
+        checkpoint(4)
+        yield 5
+
+  test(it, 0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
+
+block:
+  iterator it(): int {.closure.} =
+    var i = 5
+    template foo(): bool =
+      yield i
+      true
+
+    while foo():
+      dec i
+      if i == 0:
+        break
+
+  test(it, 5, 4, 3, 2, 1)
+
+block: # Short cirquits
+  iterator it(): int {.closure.} =
+    template trueYield: bool =
+      yield 1
+      true
+
+    template falseYield: bool =
+      yield 0
+      false
+
+    if trueYield or falseYield:
+      discard falseYield and trueYield
+
+    if falseYield and trueYield:
+      checkpoint(123)
+
+  test(it, 1, 0, 0)
+
+block: #7969
+  type
+    SomeObj = object
+      id: int
+
+  iterator it(): int {.closure.} =
+    template yieldAndSomeObj: SomeObj =
+      var s: SomeObj
+      s.id = 2
+      yield 1
+      s
+
+    checkpoint(yieldAndSomeObj().id)
+
+    var i = 5
+    case i
+    of 0:
+      checkpoint(123)
+    of 1, 2, 5:
+      checkpoint(3)
+    else:
+      checkpoint(123)
+
+  test(it, 1, 2, 3)
+
+block: # yield in blockexpr
+  iterator it(): int {.closure.} =
+    yield(block:
+      checkpoint(1)
+      yield 2
+      3
+    )
+
+  test(it, 1, 2, 3)
+
+
+echo "ok"
diff --git a/tests/lexer/thexlit.nim b/tests/lexer/thexlit.nim
deleted file mode 100644
index 2b7f0a40e..000000000
--- a/tests/lexer/thexlit.nim
+++ /dev/null
@@ -1,12 +0,0 @@
-discard """
-  file: "thexlit.nim"
-  output: "equal"
-"""
-
-var t=0x950412DE
-
-if t==0x950412DE:
-    echo "equal"
-else:
-    echo "not equal"
-
diff --git a/tests/lexer/thexrange.nim b/tests/lexer/thexrange.nim
deleted file mode 100644
index 461e41dfd..000000000
--- a/tests/lexer/thexrange.nim
+++ /dev/null
@@ -1,8 +0,0 @@
-
-type
-  TArray = array[0x0012..0x0013, int]
-
-var a: TArray
-
-echo a[0x0012] #OUT 0
-
diff --git a/tests/lexer/tlexermisc.nim b/tests/lexer/tlexermisc.nim
new file mode 100644
index 000000000..3e3993599
--- /dev/null
+++ b/tests/lexer/tlexermisc.nim
@@ -0,0 +1,27 @@
+discard """
+  action: run
+  output: "equal"
+"""
+
+var t=0x950412DE
+
+if t==0x950412DE:
+    echo "equal"
+else:
+    echo "not equal"
+
+type
+  TArray = array[0x0012..0x0013, int]
+
+var a: TArray
+
+doAssert a[0x0012] == 0
+
+
+# #7884
+
+type Obj = object
+    ö: int
+
+let o = Obj(ö: 1)
+doAssert o.ö == 1
diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim
index 771dc2456..e6fbb0e51 100644
--- a/tests/stdlib/tos.nim
+++ b/tests/stdlib/tos.nim
@@ -42,6 +42,7 @@ Raises
 true
 true
 true
+true
 '''
 """
 # test os path creation, iteration, and deletion
@@ -129,3 +130,12 @@ echo fileExists("../dest/a/b/file.txt")
 
 echo fileExists("../dest/a/b/c/fileC.txt")
 removeDir("../dest")
+
+# Test get/set modification times
+# Should support at least microsecond resolution
+import times
+let tm = fromUnix(0) + 100.microseconds
+writeFile("a", "")
+setLastModificationTime("a", tm)
+echo getLastModificationTime("a") == tm
+removeFile("a")
\ No newline at end of file
diff --git a/tests/stdlib/tstrformat.nim b/tests/stdlib/tstrformat.nim
index b4cbd41e0..db76899d4 100644
--- a/tests/stdlib/tstrformat.nim
+++ b/tests/stdlib/tstrformat.nim
@@ -12,6 +12,32 @@ var o: Obj
 doAssert fmt"{o}" == "foobar"
 doAssert fmt"{o:10}" == "foobar    "
 
+# see issue #7933
+var str = "abc"
+doAssert fmt">7.1 :: {str:>7.1}" == ">7.1 ::       a"
+doAssert fmt">7.2 :: {str:>7.2}" == ">7.2 ::      ab"
+doAssert fmt">7.3 :: {str:>7.3}" == ">7.3 ::     abc"
+doAssert fmt">7.9 :: {str:>7.9}" == ">7.9 ::     abc"
+doAssert fmt">7.0 :: {str:>7.0}" == ">7.0 ::        "
+doAssert fmt" 7.1 :: {str:7.1}" == " 7.1 :: a      "
+doAssert fmt" 7.2 :: {str:7.2}" == " 7.2 :: ab     "
+doAssert fmt" 7.3 :: {str:7.3}" == " 7.3 :: abc    "
+doAssert fmt" 7.9 :: {str:7.9}" == " 7.9 :: abc    "
+doAssert fmt" 7.0 :: {str:7.0}" == " 7.0 ::        "
+doAssert fmt"^7.1 :: {str:^7.1}" == "^7.1 ::    a   "
+doAssert fmt"^7.2 :: {str:^7.2}" == "^7.2 ::   ab   "
+doAssert fmt"^7.3 :: {str:^7.3}" == "^7.3 ::   abc  "
+doAssert fmt"^7.9 :: {str:^7.9}" == "^7.9 ::   abc  "
+doAssert fmt"^7.0 :: {str:^7.0}" == "^7.0 ::        "
+str = "äöüe\u0309\u0319o\u0307\u0359"
+doAssert fmt"^7.1 :: {str:^7.1}" == "^7.1 ::    ä   "
+doAssert fmt"^7.2 :: {str:^7.2}" == "^7.2 ::   äö   "
+doAssert fmt"^7.3 :: {str:^7.3}" == "^7.3 ::   äöü  "
+doAssert fmt"^7.0 :: {str:^7.0}" == "^7.0 ::        "
+# this is actually wrong, but the unicode module has no support for graphemes
+doAssert fmt"^7.4 :: {str:^7.4}" == "^7.4 ::  äöüe  "
+doAssert fmt"^7.9 :: {str:^7.9}" == "^7.9 :: äöüe\u0309\u0319o\u0307\u0359"
+
 # see issue #7932
 doAssert fmt"{15:08}" == "00000015" # int, works
 doAssert fmt"{1.5:08}" == "000001.5" # float, works
@@ -20,3 +46,11 @@ doAssert fmt"{-1.5:0>8}" == "0000-1.5" # even that does not work for negative fl
 doAssert fmt"{-1.5:08}" == "-00001.5" # works
 doAssert fmt"{1.5:+08}" == "+00001.5" # works
 doAssert fmt"{1.5: 08}" == " 00001.5" # works
+
+# only add explicitly requested sign if value != -0.0 (neg zero)
+doAssert fmt"{-0.0:g}" == "-0"
+doassert fmt"{-0.0:+g}" == "-0"
+doassert fmt"{-0.0: g}" == "-0"
+doAssert fmt"{0.0:g}" == "0"
+doAssert fmt"{0.0:+g}" == "+0"
+doAssert fmt"{0.0: g}" == " 0"
diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim
index 85228e9e7..6d14aa68f 100644
--- a/tests/system/tsystem_misc.nim
+++ b/tests/system/tsystem_misc.nim
@@ -11,6 +11,10 @@ discard """
 2
 3
 4
+2
+1
+2
+3
 '''
 """
 
@@ -47,3 +51,38 @@ foo(toOpenArray(arr, 8, 12))
 
 var seqq = @[1, 2, 3, 4, 5]
 foo(toOpenArray(seqq, 1, 3))
+
+# empty openArray issue #7904
+foo(toOpenArray(seqq, 0, -1))
+foo(toOpenArray(seqq, 1, 0))
+doAssertRaises(IndexError):
+  foo(toOpenArray(seqq, 0, -2))
+
+foo(toOpenArray(arr, 9, 8))
+foo(toOpenArray(arr, 0, -1))
+foo(toOpenArray(arr, 1, 0))
+doAssertRaises(IndexError):
+  foo(toOpenArray(arr, 10, 8))
+
+# test openArray of openArray
+proc oaEmpty(a: openArray[int]) =
+  foo(toOpenArray(a, 0, -1))
+
+proc oaFirstElm(a: openArray[int]) =
+  foo(toOpenArray(a, 0, 0))
+
+oaEmpty(toOpenArray(seqq, 0, -1))
+oaEmpty(toOpenArray(seqq, 1, 0))
+oaEmpty(toOpenArray(seqq, 1, 2))
+oaFirstElm(toOpenArray(seqq, 1, seqq.len-1))
+
+var arrNeg: array[-3 .. -1, int] = [1, 2, 3]
+foo(toOpenArray(arrNeg, -3, -1))
+foo(toOpenArray(arrNeg, 0, -1))
+foo(toOpenArray(arrNeg, -3, -4))
+doAssertRaises(IndexError):
+  foo(toOpenArray(arrNeg, -4, -1))
+doAssertRaises(IndexError):
+  foo(toOpenArray(arrNeg, -1, 0))
+doAssertRaises(IndexError):
+  foo(toOpenArray(arrNeg, -1, -3))
diff --git a/tests/typerel/t4799.nim b/tests/typerel/t4799.nim
new file mode 100644
index 000000000..075893476
--- /dev/null
+++ b/tests/typerel/t4799.nim
@@ -0,0 +1,245 @@
+discard """
+  output: "OK"
+"""
+
+type
+  GRBase[T] = ref object of RootObj
+    val: T
+  GRC[T] = ref object of GRBase[T]
+  GRD[T] = ref object of GRBase[T]
+
+proc testGR[T](x: varargs[GRBase[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.val
+
+block test_t4799_1:
+  var rgv = GRBase[int](val: 3)
+  var rgc = GRC[int](val: 4)
+  var rgb = GRD[int](val: 2)
+  doAssert(testGR(rgb, rgc, rgv) == "243")
+  doAssert(testGR(rgc, rgv, rgb) == "432")
+  doAssert(testGR(rgv, rgb, rgc) == "324")
+  doAssert(testGR([rgb, rgc, rgv]) == "243")
+  doAssert(testGR([rgc, rgv, rgb]) == "432")
+  doAssert(testGR([rgv, rgb, rgc]) == "324")
+
+type
+  PRBase[T] = object of RootObj
+    val: T
+  PRC[T] = object of PRBase[T]
+  PRD[T] = object of PRBase[T]
+
+proc testPR[T](x: varargs[ptr PRBase[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.val
+
+block test_t4799_2:
+  var pgv = PRBase[int](val: 3)
+  var pgc = PRC[int](val: 4)
+  var pgb = PRD[int](val: 2)
+  doAssert(testPR(pgb.addr, pgc.addr, pgv.addr) == "243")
+  doAssert(testPR(pgc.addr, pgv.addr, pgb.addr) == "432")
+  doAssert(testPR(pgv.addr, pgb.addr, pgc.addr) == "324")
+  doAssert(testPR([pgb.addr, pgc.addr, pgv.addr]) == "243")
+  doAssert(testPR([pgc.addr, pgv.addr, pgb.addr]) == "432")
+  doAssert(testPR([pgv.addr, pgb.addr, pgc.addr]) == "324")
+
+type
+  RBase = ref object of RootObj
+    val: int
+  RC = ref object of RBase
+  RD = ref object of RBase
+
+proc testR(x: varargs[RBase]): string =
+  result = ""
+  for c in x:
+    result.add $c.val
+
+block test_t4799_3:
+  var rv = RBase(val: 3)
+  var rc = RC(val: 4)
+  var rb = RD(val: 2)
+  doAssert(testR(rb, rc, rv) == "243")
+  doAssert(testR(rc, rv, rb) == "432")
+  doAssert(testR(rv, rb, rc) == "324")
+  doAssert(testR([rb, rc, rv]) == "243")
+  doAssert(testR([rc, rv, rb]) == "432")
+  doAssert(testR([rv, rb, rc]) == "324")
+
+type
+  PBase = object of RootObj
+    val: int
+  PC = object of PBase
+  PD = object of PBase
+
+proc testP(x: varargs[ptr PBase]): string =
+  result = ""
+  for c in x:
+    result.add $c.val
+
+block test_t4799_4:
+  var pv = PBase(val: 3)
+  var pc = PC(val: 4)
+  var pb = PD(val: 2)
+  doAssert(testP(pb.addr, pc.addr, pv.addr) == "243")
+  doAssert(testP(pc.addr, pv.addr, pb.addr) == "432")
+  doAssert(testP(pv.addr, pb.addr, pc.addr) == "324")
+  doAssert(testP([pb.addr, pc.addr, pv.addr]) == "243")
+  doAssert(testP([pc.addr, pv.addr, pb.addr]) == "432")
+  doAssert(testP([pv.addr, pb.addr, pc.addr]) == "324")
+
+type
+  PSBase[T, V] = ref object of RootObj
+    val: T
+    color: V
+  PSRC[T] = ref object of PSBase[T, int]
+  PSRD[T] = ref object of PSBase[T, int]
+
+proc testPS[T, V](x: varargs[PSBase[T, V]]): string =
+  result = ""
+  for c in x:
+    result.add c.val
+    result.add $c.color
+
+block test_t4799_5:
+  var a = PSBase[string, int](val: "base", color: 1)
+  var b = PSRC[string](val: "rc", color: 2)
+  var c = PSRD[string](val: "rd", color: 3)
+
+  doAssert(testPS(a, b, c) == "base1rc2rd3")
+  doAssert(testPS(b, a, c) == "rc2base1rd3")
+  doAssert(testPS(c, b, a) == "rd3rc2base1")
+  doAssert(testPS([a, b, c]) == "base1rc2rd3")
+  doAssert(testPS([b, a, c]) == "rc2base1rd3")
+  doAssert(testPS([c, b, a]) == "rd3rc2base1")
+
+type
+  SBase[T, V] = ref object of RootObj
+    val: T
+    color: V
+  SRC = ref object of SBase[string, int]
+  SRD = ref object of SBase[string, int]
+
+proc testS[T, V](x: varargs[SBase[T, V]]): string =
+  result = ""
+  for c in x:
+    result.add c.val
+    result.add $c.color
+
+block test_t4799_6:
+  var a = SBase[string, int](val: "base", color: 1)
+  var b = SRC(val: "rc", color: 2)
+  var c = SRD(val: "rd", color: 3)
+
+  doAssert(testS(a, b, c) == "base1rc2rd3")
+  doAssert(testS(b, a, c) == "rc2base1rd3")
+  doAssert(testS(c, b, a) == "rd3rc2base1")
+  doAssert(testS([a, b, c]) == "base1rc2rd3")
+  # this is not varargs bug, but array construction bug
+  # see #7955
+  #doAssert(testS([b, c, a]) == "rc2rd3base1")
+  #doAssert(testS([c, b, a]) == "rd3rc2base1")
+
+proc test_inproc() =
+  block test_inproc_1:
+    var rgv = GRBase[int](val: 3)
+    var rgc = GRC[int](val: 4)
+    var rgb = GRD[int](val: 2)
+    doAssert(testGR(rgb, rgc, rgv) == "243")
+    doAssert(testGR(rgc, rgv, rgb) == "432")
+    doAssert(testGR(rgv, rgb, rgc) == "324")
+    doAssert(testGR([rgb, rgc, rgv]) == "243")
+    doAssert(testGR([rgc, rgv, rgb]) == "432")
+    doAssert(testGR([rgv, rgb, rgc]) == "324")
+
+  block test_inproc_2:
+    var pgv = PRBase[int](val: 3)
+    var pgc = PRC[int](val: 4)
+    var pgb = PRD[int](val: 2)
+    doAssert(testPR(pgb.addr, pgc.addr, pgv.addr) == "243")
+    doAssert(testPR(pgc.addr, pgv.addr, pgb.addr) == "432")
+    doAssert(testPR(pgv.addr, pgb.addr, pgc.addr) == "324")
+    doAssert(testPR([pgb.addr, pgc.addr, pgv.addr]) == "243")
+    doAssert(testPR([pgc.addr, pgv.addr, pgb.addr]) == "432")
+    doAssert(testPR([pgv.addr, pgb.addr, pgc.addr]) == "324")
+
+test_inproc()
+
+template reject(x) =
+  static: assert(not compiles(x))
+
+block test_t4799_7:
+  type
+    Vehicle[T] = ref object of RootObj
+      tire: T
+    Car[T] = object of Vehicle[T]
+    Bike[T] = object of Vehicle[T]
+
+  proc testVehicle[T](x: varargs[Vehicle[T]]): string {.used.} =
+    result = ""
+    for c in x:
+      result.add $c.tire
+
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  reject:
+    echo testVehicle(b, c, v)
+
+block test_t4799_8:
+  type
+    Vehicle = ref object of RootObj
+      tire: int
+    Car = object of Vehicle
+    Bike = object of Vehicle
+
+  proc testVehicle(x: varargs[Vehicle]): string {.used.} =
+    result = ""
+    for c in x:
+      result.add $c.tire
+
+  var v = Vehicle(tire: 3)
+  var c = Car(tire: 4)
+  var b = Bike(tire: 2)
+
+  reject:
+    echo testVehicle(b, c, v)
+
+type
+  PGVehicle[T] = ptr object of RootObj
+    tire: T
+  PGCar[T] = object of PGVehicle[T]
+  PGBike[T] = object of PGVehicle[T]
+
+proc testVehicle[T](x: varargs[PGVehicle[T]]): string {.used.} =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+var pgc = PGCar[int](tire: 4)
+var pgb = PGBike[int](tire: 2)
+
+reject:
+  echo testVehicle(pgb, pgc)
+
+type
+  RVehicle = ptr object of RootObj
+    tire: int
+  RCar = object of RVehicle
+  RBike = object of RVehicle
+
+proc testVehicle(x: varargs[RVehicle]): string {.used.} =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+var rc = RCar(tire: 4)
+var rb = RBike(tire: 2)
+
+reject:
+  echo testVehicle(rb, rc)
+
+echo "OK"
diff --git a/tests/typerel/t4799_1.nim b/tests/typerel/t4799_1.nim
new file mode 100644
index 000000000..549b6bf3c
--- /dev/null
+++ b/tests/typerel/t4799_1.nim
@@ -0,0 +1,20 @@
+discard """
+  outputsub: '''ObjectAssignmentError'''
+  exitcode: "1"
+"""
+
+type
+  Vehicle[T] = object of RootObj
+    tire: T
+  Car[T] = object of Vehicle[T]
+  Bike[T] = object of Vehicle[T]
+
+proc testVehicle[T](x: varargs[Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+var v = Vehicle[int](tire: 3)
+var c = Car[int](tire: 4)
+var b = Bike[int](tire: 2)
+echo testVehicle b, c, v
diff --git a/tests/typerel/t4799_2.nim b/tests/typerel/t4799_2.nim
new file mode 100644
index 000000000..cfd399a6e
--- /dev/null
+++ b/tests/typerel/t4799_2.nim
@@ -0,0 +1,20 @@
+discard """
+  outputsub: '''ObjectAssignmentError'''
+  exitcode: "1"
+"""
+
+type
+  Vehicle[T] = object of RootObj
+    tire: T
+  Car[T] = object of Vehicle[T]
+  Bike[T] = object of Vehicle[T]
+
+proc testVehicle[T](x: varargs[Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+var v = Vehicle[int](tire: 3)
+var c = Car[int](tire: 4)
+var b = Bike[int](tire: 2)
+echo testVehicle([b, c, v])
\ No newline at end of file
diff --git a/tests/typerel/t4799_3.nim b/tests/typerel/t4799_3.nim
new file mode 100644
index 000000000..784eee8fc
--- /dev/null
+++ b/tests/typerel/t4799_3.nim
@@ -0,0 +1,20 @@
+discard """
+  outputsub: '''ObjectAssignmentError'''
+  exitcode: "1"
+"""
+
+type
+  Vehicle = object of RootObj
+    tire: int
+  Car = object of Vehicle
+  Bike = object of Vehicle
+
+proc testVehicle(x: varargs[Vehicle]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+var v = Vehicle(tire: 3)
+var c = Car(tire: 4)
+var b = Bike(tire: 2)
+echo testVehicle([b, c, v])
\ No newline at end of file
diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim
index 472660bc2..4af824cf4 100644
--- a/tests/vm/tvmmisc.nim
+++ b/tests/vm/tvmmisc.nim
@@ -82,3 +82,11 @@ block:
 
     assert fileExists("MISSINGFILE") == false
     assert dirExists("MISSINGDIR") == false
+
+# #7210
+block:
+  static:
+    proc f(size: int): int =
+      var some = newStringOfCap(size)
+      result = size
+    doAssert f(4) == 4
\ No newline at end of file