diff options
Diffstat (limited to 'tests')
157 files changed, 11813 insertions, 1414 deletions
diff --git a/tests/arithm/tsubrange.nim b/tests/arithm/tsubrange.nim new file mode 100644 index 000000000..9d60dbd1a --- /dev/null +++ b/tests/arithm/tsubrange.nim @@ -0,0 +1,13 @@ +discard """ + output: '''1''' +""" + +# bug #5854 +type + n16* = range[0'i16..high(int16)] + +var level: n16 = 1 +let maxLevel: n16 = 1 + +level = min(level + 2, maxLevel) +echo level diff --git a/tests/array/troof1.nim b/tests/array/troof1.nim index 96669a121..b486c3448 100644 --- a/tests/array/troof1.nim +++ b/tests/array/troof1.nim @@ -1,7 +1,11 @@ discard """ output: '''@[2, 3, 4]321 9.0 4.0 -(a: 1.0, b: 2.0, c: 8.0)2.0''' +3 +@[(Field0: 1, Field1: 2), (Field0: 3, Field1: 5)] +2 +@["a", "new one", "c"] +@[1, 2, 3]''' """ proc foo[T](x, y: T): T = x @@ -11,26 +15,29 @@ var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]] echo a[1.. ^1], a[^2], a[^3], a[^4] echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1] -type - MyArray = object - a, b, c: float +b[^1] = [8.8, 8.9] -var - ma = MyArray(a: 1.0, b: 2.0, c: 3.0) +var c: seq[(int, int)] = @[(1,2), (3,4)] -proc len(x: MyArray): int = 3 +proc takeA(x: ptr int) = echo x[] -proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) = - case idx - of 0: x.a = val - of 1: x.b = val - of 2: x.c = val +takeA(addr c[^1][0]) +c[^1][1] = 5 +echo c -proc `[]`(x: var MyArray; idx: range[0..2]): float = - case idx - of 0: result = x.a - of 1: result = x.b - of 2: result = x.c +proc useOpenarray(x: openArray[int]) = + echo x[^2] -ma[^1] = 8.0 -echo ma, ma[^2] +proc mutOpenarray(x: var openArray[string]) = + x[^2] = "new one" + +useOpenarray([1, 2, 3]) + +var z = @["a", "b", "c"] +mutOpenarray(z) +echo z + +# bug #6675 +var y: array[1..5, int] = [1,2,3,4,5] +y[3..5] = [1, 2, 3] +echo y[3..5] diff --git a/tests/array/troof2.nim b/tests/array/troof2.nim deleted file mode 100644 index e4b4f4b3c..000000000 --- a/tests/array/troof2.nim +++ /dev/null @@ -1,10 +0,0 @@ -discard """ - errormsg: "invalid context for '^' as 'foo()' has side effects" - line: "9" -""" -# XXX This needs to be fixed properly! -proc foo(): seq[int] {.sideEffect.} = - echo "ha" - -let f = foo()[^1] - diff --git a/tests/array/troof3.nim b/tests/array/troof3.nim index 4b6e22223..efe0eafb8 100644 --- a/tests/array/troof3.nim +++ b/tests/array/troof3.nim @@ -1,8 +1,7 @@ discard """ - errormsg: "invalid context for '^' as len!=high+1 for 'a'" - line: "8" + output: '''c''' """ -var a: array[1..3, string] +var a: array['a'..'c', string] = ["a", "b", "c"] echo a[^1] diff --git a/tests/array/troof4.nim b/tests/array/troof4.nim deleted file mode 100644 index 7a262d9de..000000000 --- a/tests/array/troof4.nim +++ /dev/null @@ -1,37 +0,0 @@ -discard """ - errormsg: "no surrounding array access context for '^'" - line: "37" -""" - -proc foo[T](x, y: T): T = x - -var a = @[1, 2, 3, 4] -var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]] -echo a[1.. ^1], a[^2], a[^3], a[^4] -echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1] - -type - MyArray = object - a, b, c: float - -var - ma = MyArray(a: 1.0, b: 2.0, c: 3.0) - -proc len(x: MyArray): int = 3 - -proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) = - case idx - of 0: x.a = val - of 1: x.b = val - of 2: x.c = val - -proc `[]`(x: var MyArray; idx: range[0..2]): float = - case idx - of 0: result = x.a - of 1: result = x.b - of 2: result = x.c - -ma[^1] = 8.0 -echo ma, ma[^2] - -echo(^1) diff --git a/tests/array/troofregression.nim b/tests/array/troofregression.nim new file mode 100644 index 000000000..0b96123a4 --- /dev/null +++ b/tests/array/troofregression.nim @@ -0,0 +1,46 @@ +############################### +#### part from Arraymancer + +type + MetadataArray* = object + data*: array[8, int] + len*: int + +# Commenting the converter removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" +converter toMetadataArray*(se: varargs[int]): MetadataArray {.inline.} = + result.len = se.len + for i in 0..<se.len: + result.data[i] = se[i] + + +when NimVersion >= "0.17.3": + type Index = int or BackwardsIndex + template `^^`(s, i: untyped): untyped = + when i is BackwardsIndex: + s.len - int(i) + else: i +else: + type Index = int + template `^^`(s, i: untyped): untyped = + i + +## With Nim devel from the start of the week (~Oct30) I managed to trigger "lib/system.nim(3536, 4) Error: expression has no address" +## but I can't anymore after updating Nim (Nov5) +## Now commenting this plain compiles and removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" +proc `[]`*(a: var MetadataArray, idx: Index): var int {.inline.} = + a.data[a ^^ idx] + + +############################## +### Completely unrelated lib that triggers the issue + +type + MySeq[T] = ref object + data: seq[T] + +proc test[T](sx: MySeq[T]) = + # Removing the backward index removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" + echo sx.data[^1] # error here + +let s = MySeq[int](data: @[1, 2, 3]) +s.test() diff --git a/tests/async/tasync_in_seq_constr.nim b/tests/async/tasync_in_seq_constr.nim index 7d216e352..46ad74451 100644 --- a/tests/async/tasync_in_seq_constr.nim +++ b/tests/async/tasync_in_seq_constr.nim @@ -1,8 +1,9 @@ discard """ - output: '''@[1, 2, 3, 4]''' + errormsg: "invalid control flow: 'yield' within a constructor" + line: 16 """ -# bug #5314 +# bug #5314, bug #6626 import asyncdispatch diff --git a/tests/async/tasync_traceback.nim b/tests/async/tasync_traceback.nim new file mode 100644 index 000000000..08f7e7317 --- /dev/null +++ b/tests/async/tasync_traceback.nim @@ -0,0 +1,116 @@ +discard """ + exitcode: 0 + disabled: "windows" + output: ''' +b failure +Async traceback: + tasync_traceback.nim(97) tasync_traceback + asyncmacro.nim(395) a + asyncmacro.nim(34) a_continue + ## Resumes an async procedure + tasync_traceback.nim(95) aIter + asyncmacro.nim(395) b + asyncmacro.nim(34) b_continue + ## Resumes an async procedure + tasync_traceback.nim(92) bIter + #[ + tasync_traceback.nim(97) tasync_traceback + asyncmacro.nim(395) a + asyncmacro.nim(43) a_continue + ## Resumes an async procedure + asyncfutures.nim(211) callback= + asyncfutures.nim(190) addCallback + asyncfutures.nim(53) callSoon + asyncmacro.nim(34) a_continue + ## Resumes an async procedure + asyncmacro.nim(0) aIter + asyncfutures.nim(304) read + ]# +Exception message: b failure +Exception type: + +bar failure +Async traceback: + tasync_traceback.nim(113) tasync_traceback + asyncdispatch.nim(1492) waitFor + asyncdispatch.nim(1496) poll + ## Processes asynchronous completion events + asyncdispatch.nim(1262) runOnce + asyncdispatch.nim(183) processPendingCallbacks + ## Executes pending callbacks + asyncmacro.nim(34) bar_continue + ## Resumes an async procedure + tasync_traceback.nim(108) barIter + #[ + tasync_traceback.nim(113) tasync_traceback + asyncdispatch.nim(1492) waitFor + asyncdispatch.nim(1496) poll + ## Processes asynchronous completion events + asyncdispatch.nim(1262) runOnce + asyncdispatch.nim(183) processPendingCallbacks + ## Executes pending callbacks + asyncmacro.nim(34) foo_continue + ## Resumes an async procedure + asyncmacro.nim(0) fooIter + asyncfutures.nim(304) read + ]# +Exception message: bar failure +Exception type:''' +""" +import asyncdispatch + +# Tests to ensure our exception trace backs are friendly. + +# --- Simple test. --- +# +# What does this look like when it's synchronous? +# +# tasync_traceback.nim(23) tasync_traceback +# tasync_traceback.nim(21) a +# tasync_traceback.nim(18) b +# Error: unhandled exception: b failure [OSError] +# +# Good (not quite ideal, but gotta work within constraints) traceback, +# when exception is unhandled: +# +# <traceback for the unhandled exception> +# <very much a bunch of noise> +# <would be ideal to customise this> +# <(the code responsible is in excpt:raiseExceptionAux)> +# Error: unhandled exception: b failure +# =============== +# Async traceback +# =============== +# +# tasync_traceback.nim(23) tasync_traceback +# +# tasync_traceback.nim(21) a +# tasync_traceback.nim(18) b + +proc b(): Future[int] {.async.} = + if true: + raise newException(OSError, "b failure") + +proc a(): Future[int] {.async.} = + return await b() + +let aFut = a() +try: + discard waitFor aFut +except Exception as exc: + echo exc.msg +echo() + +# From #6803 +proc bar(): Future[string] {.async.} = + await sleepAsync(100) + if true: + raise newException(OSError, "bar failure") + +proc foo(): Future[string] {.async.} = return await bar() + +try: + echo waitFor(foo()) +except Exception as exc: + echo exc.msg +echo() \ No newline at end of file diff --git a/tests/async/tasyncall.nim b/tests/async/tasyncall.nim index 7daecd9ef..775dd0c6f 100644 --- a/tests/async/tasyncall.nim +++ b/tests/async/tasyncall.nim @@ -40,8 +40,17 @@ proc testVarargs(x, y, z: int): seq[int] = result = waitFor all(a, b, c) -suite "tasyncall": - test "testFuturesWithValue": +proc testWithDupes() = + var + tasks = newSeq[Future[void]](taskCount) + fut = futureWithoutValue() + + for i in 0..<taskCount: + tasks[i] = fut + + waitFor all(tasks) + +block: let startTime = cpuTime() results = testFuturesWithValue(42) @@ -51,14 +60,21 @@ suite "tasyncall": doAssert execTime * 1000 < taskCount * sleepDuration doAssert results == expected - test "testFuturesWithoutValues": +block: let startTime = cpuTime() testFuturesWithoutValues() let execTime = cpuTime() - startTime doAssert execTime * 1000 < taskCount * sleepDuration - test "testVarargs": +block: + let startTime = cpuTime() + testWithDupes() + let execTime = cpuTime() - startTime + + doAssert execTime * 1000 < taskCount * sleepDuration + +block: let startTime = cpuTime() results = testVarargs(1, 2, 3) @@ -68,7 +84,7 @@ suite "tasyncall": doAssert execTime * 100 < taskCount * sleepDuration doAssert results == expected - test "all on seq[Future]": +block: let noIntFuturesFut = all(newSeq[Future[int]]()) noVoidFuturesFut = all(newSeq[Future[void]]()) diff --git a/tests/async/tasyncdial.nim b/tests/async/tasyncdial.nim index d70e14020..fa81235fe 100644 --- a/tests/async/tasyncdial.nim +++ b/tests/async/tasyncdial.nim @@ -4,6 +4,7 @@ discard """ OK AF_INET OK AF_INET6 ''' + disabled: "travis" """ import diff --git a/tests/async/tasyncfile.nim b/tests/async/tasyncfile.nim index 592f0ebd8..6c0725c88 100644 --- a/tests/async/tasyncfile.nim +++ b/tests/async/tasyncfile.nim @@ -34,4 +34,19 @@ proc main() {.async.} = doAssert data == "foot\ntest2" file.close() + # Issue #5531 + block: + removeFile(fn) + var file = openAsync(fn, fmWrite) + await file.write("test2") + file.close() + file = openAsync(fn, fmWrite) + await file.write("test3") + file.close() + file = openAsync(fn, fmRead) + let data = await file.readAll() + doAssert data == "test3" + file.close() + + waitFor main() diff --git a/tests/async/tasyncsend4757.nim b/tests/async/tasyncsend4757.nim index 1066f38e5..752bb3e75 100644 --- a/tests/async/tasyncsend4757.nim +++ b/tests/async/tasyncsend4757.nim @@ -3,11 +3,22 @@ discard """ output: "Finished" """ -import asyncdispatch +import asyncdispatch, asyncnet + +proc createServer(port: Port) {.async.} = + var server = newAsyncSocket() + server.setSockOpt(OptReuseAddr, true) + bindAddr(server, port) + server.listen() + while true: + let client = await server.accept() + discard await client.recvLine() + +asyncCheck createServer(10335.Port) proc f(): Future[void] {.async.} = let s = newAsyncNativeSocket() - await s.connect("example.com", 80.Port) + await s.connect("localhost", 10335.Port) await s.send("123") echo "Finished" diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index 034c2185c..d2e4cfec1 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -2,7 +2,7 @@ discard """ file: "tioselectors.nim" output: "All tests passed!" """ -import ioselectors +import selectors const hasThreadSupport = compileOption("threads") @@ -579,9 +579,9 @@ else: var event = newSelectEvent() selector.registerEvent(event, 1) discard selector.select(0) - event.setEvent() + event.trigger() var rc1 = selector.select(0) - event.setEvent() + event.trigger() var rc2 = selector.select(0) var rc3 = selector.select(0) assert(len(rc1) == 1 and len(rc2) == 1 and len(rc3) == 0) @@ -611,7 +611,7 @@ else: var event = newSelectEvent() for i in 0..high(thr): createThread(thr[i], event_wait_thread, event) - event.setEvent() + event.trigger() joinThreads(thr) assert(counter == 1) result = true diff --git a/tests/async/tnewasyncudp.nim b/tests/async/tnewasyncudp.nim index b56cdc71b..e61f630e4 100644 --- a/tests/async/tnewasyncudp.nim +++ b/tests/async/tnewasyncudp.nim @@ -86,7 +86,7 @@ proc readMessages(server: AsyncFD) {.async.} = size = 0 var grammString = $cstring(addr buffer) if grammString.startswith("Message ") and - saddr.sin_addr.s_addr == 0x100007F: + saddr.sin_addr.s_addr == nativesockets.ntohl(INADDR_LOOPBACK.uint32): await sendTo(server, addr grammString[0], len(grammString), cast[ptr SockAddr](addr saddr), slen) inc(msgCount) diff --git a/tests/casestmt/tcasestm.nim b/tests/casestmt/tcasestm.nim index 7ac20bf2f..b005d8120 100644 --- a/tests/casestmt/tcasestm.nim +++ b/tests/casestmt/tcasestm.nim @@ -36,5 +36,64 @@ var z = case i echo z #OUT ayyy +let str1 = "Y" +let str2 = "NN" +let a = case str1: + of "Y": true + of "N": false + else: + echo "no good" + quit("quiting") +let b = case str2: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str2[0] == 'Y': true + elif str2[0] == 'N': false + else: "error".quit(2) +doAssert(a == true) +doAssert(b == false) + +var bb: bool +doassert(not compiles( + bb = case str2: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str.startsWith("Y"): true + elif str.startsWith("N"): false +)) + +doassert(not compiles( + bb = case str2: + of "Y": true + of "N": false +)) + +doassert(not compiles( + bb = case str2: + of "Y": true + of "N": raise newException(ValueError, "N not allowed") +)) + +doassert(not compiles( + bb = case str2: + of "Y": raise newException(ValueError, "Invalid Y") + else: raise newException(ValueError, "Invalid N") +)) + + +doassert(not compiles( + bb = case str2: + of "Y": + raise newException(ValueError, "Invalid Y") + true + else: raise newException(ValueError, "Invalid") +)) + + +doassert(not compiles( + bb = case str2: + of "Y": + "invalid Y".quit(3) + true + else: raise newException(ValueError, "Invalid") +)) \ No newline at end of file diff --git a/tests/ccgbugs/t6279.nim b/tests/ccgbugs/t6279.nim index 37345d807..5a3d6768c 100644 --- a/tests/ccgbugs/t6279.nim +++ b/tests/ccgbugs/t6279.nim @@ -1,6 +1,6 @@ discard """ cmd: "nim c -r -d:fulldebug -d:smokeCycles --gc:refc $file" -output: '''@[a]''' +output: '''@["a"]''' """ # bug #6279 diff --git a/tests/ccgbugs/t6756.nim b/tests/ccgbugs/t6756.nim new file mode 100644 index 000000000..0f08557eb --- /dev/null +++ b/tests/ccgbugs/t6756.nim @@ -0,0 +1,18 @@ +import typetraits +type + A[T] = ref object + v: T + +template templ(o: A, op: untyped): untyped = + type T = type(o.v) + + var res: A[T] + + block: + var it {.inject.}: T + it = o.v + res = A[T](v: op) + res + +let a = A[int](v: 1) +echo templ(a, it + 2)[] diff --git a/tests/ccgbugs/tbug1081.nim b/tests/ccgbugs/tbug1081.nim index 71628feec..baef99d84 100644 --- a/tests/ccgbugs/tbug1081.nim +++ b/tests/ccgbugs/tbug1081.nim @@ -2,7 +2,8 @@ discard """ output: '''1 0 0 -0''' +0 +x = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6'] and y = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6']''' """ proc `1/1`() = echo(1 div 1) @@ -15,3 +16,19 @@ let `1/4` = 1 div 4 `1/2`() echo `1/3` echo `1/4` + +# bug #6422 + +proc toCharArray1(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + x[] + +proc toCharArray2(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + result = x[] + +let x = toCharArray1(10, "abc0123456") +let y = toCharArray2(10, "abc0123456") +echo "x = ", $x, " and y = ", $y diff --git a/tests/ccgbugs/tconstobj.nim b/tests/ccgbugs/tconstobj.nim index 98f441e83..51cf661ee 100644 --- a/tests/ccgbugs/tconstobj.nim +++ b/tests/ccgbugs/tconstobj.nim @@ -1,5 +1,5 @@ discard """ - output: '''(FirstName: James, LastName: Franco)''' + output: '''(FirstName: "James", LastName: "Franco")''' """ # bug #1547 diff --git a/tests/ccgbugs/tobjconstr_bad_aliasing.nim b/tests/ccgbugs/tobjconstr_bad_aliasing.nim new file mode 100644 index 000000000..ea51ecacb --- /dev/null +++ b/tests/ccgbugs/tobjconstr_bad_aliasing.nim @@ -0,0 +1,26 @@ +discard """ + output: '''(10, (20, ))''' +""" + +import strutils, sequtils + +# bug #668 + +type + TThing = ref object + data: int + children: seq[TThing] + +proc `$`(t: TThing): string = + result = "($1, $2)" % @[$t.data, join(map(t.children, proc(th: TThing): string = $th), ", ")] + +proc somethingelse(): seq[TThing] = + result = @[TThing(data: 20, children: @[])] + +proc dosomething(): seq[TThing] = + result = somethingelse() + + result = @[TThing(data: 10, children: result)] + +when isMainModule: + echo($dosomething()[0]) diff --git a/tests/ccgbugs/tobjconstr_regression.nim b/tests/ccgbugs/tobjconstr_regression.nim index 87d037894..d29abad97 100644 --- a/tests/ccgbugs/tobjconstr_regression.nim +++ b/tests/ccgbugs/tobjconstr_regression.nim @@ -1,5 +1,5 @@ discard """ - output: "@[(username: user, role: admin, description: desc, email_addr: email), (username: user, role: admin, description: desc, email_addr: email)]" + output: '''@[(username: "user", role: "admin", description: "desc", email_addr: "email"), (username: "user", role: "admin", description: "desc", email_addr: "email")]''' """ type diff --git a/tests/ccgbugs/trefseqsort.nim b/tests/ccgbugs/trefseqsort.nim new file mode 100644 index 000000000..2410770cf --- /dev/null +++ b/tests/ccgbugs/trefseqsort.nim @@ -0,0 +1,33 @@ +discard """ + output: '''@[0, 4, 9, 1, 3, 2] +@[0, 1, 2, 3, 9]''' +""" +# bug #6724 +import algorithm + +type + Bar = object + bar: ref seq[int] + Foo = ref Bar + +proc test(x: ref Foo) = + x.bar[].del(1) + x.bar[].sort(cmp) + +proc main() = + var foo: ref Foo + new(foo) + + var s = @[0, 4, 9, 1, 3, 2] + + var sr: ref seq[int] + new(sr) + sr[] = s + + foo[] = Foo(bar: sr) + echo($foo.bar[]) + + test(foo) + echo($foo.bar[]) + +main() diff --git a/tests/ccgbugs/tret_arg_init.nim b/tests/ccgbugs/tret_arg_init.nim index 3c80fb061..5cd67de3e 100644 --- a/tests/ccgbugs/tret_arg_init.nim +++ b/tests/ccgbugs/tret_arg_init.nim @@ -1,7 +1,7 @@ discard """ - output: '''nil -nil -nil''' + output: ''' + +''' """ type Bar = object diff --git a/tests/ccgbugs/tuple_canon.nim b/tests/ccgbugs/tuple_canon.nim index 45fed8eee..7e9e91836 100644 --- a/tests/ccgbugs/tuple_canon.nim +++ b/tests/ccgbugs/tuple_canon.nim @@ -85,3 +85,31 @@ proc go() = echo "vidx ", $vidx(hg, 1, 2, hiC) go() + +# another sighashes problem: In tuples we have to ignore ranges. + +type + Position = tuple[x, y: int16] + n16 = range[0'i16..high(int16)] + +proc print(pos: Position) = + echo $pos.x, ",", $pos.y + +var x = 0.n16 +var y = 0.n16 +print((x, y)) + + +# bug #6889 +proc createProgressSetterWithPropSetter[T](setter: proc(v: T)) = discard + +type A = distinct array[4, float32] +type B = distinct array[3, float32] + +type Foo[T] = tuple + setter: proc(v: T) + +proc getFoo[T](): Foo[T] = discard + +createProgressSetterWithPropSetter(getFoo[A]().setter) +createProgressSetterWithPropSetter(getFoo[B]().setter) diff --git a/tests/closure/t1641.nim b/tests/closure/t1641.nim new file mode 100644 index 000000000..a3e4da367 --- /dev/null +++ b/tests/closure/t1641.nim @@ -0,0 +1,20 @@ +discard """ + output: '''foo 0 +bar 0 +baz''' +""" + +# bug #1641 +proc baz() = + echo "baz" + +proc bar(x: int, p: proc()) = + echo "bar ", x + p() + +proc foo(x: int, p: proc(x: int)) = + echo "foo ", x + p(x) + +let x = 0 +x.foo do(x: int): x.bar do(): baz() diff --git a/tests/closure/tinvalidclosure3.nim b/tests/closure/tinvalidclosure3.nim new file mode 100644 index 000000000..31c4976f8 --- /dev/null +++ b/tests/closure/tinvalidclosure3.nim @@ -0,0 +1,12 @@ +discard """ + line: 9 + errormsg: "illegal capture 'x'" +""" + +proc outer(arg: string) = + var x = 0 + proc inner {.inline.} = + echo "inner", x + inner() + +outer("abc") \ No newline at end of file diff --git a/tests/collections/tcollections_to_string.nim b/tests/collections/tcollections_to_string.nim new file mode 100644 index 000000000..6cc8a84ff --- /dev/null +++ b/tests/collections/tcollections_to_string.nim @@ -0,0 +1,106 @@ +discard """ + exitcode: 0 + output: "" +""" +import sets +import tables +import deques +import lists +import critbits + +# Tests for tuples +doAssert $(1, 2, 3) == "(Field0: 1, Field1: 2, Field2: 3)" +doAssert $("1", "2", "3") == """(Field0: "1", Field1: "2", Field2: "3")""" +doAssert $('1', '2', '3') == """(Field0: '1', Field1: '2', Field2: '3')""" + +# Tests for seqs +doAssert $(@[1, 2, 3]) == "@[1, 2, 3]" +doAssert $(@["1", "2", "3"]) == """@["1", "2", "3"]""" +doAssert $(@['1', '2', '3']) == """@['1', '2', '3']""" + +# Tests for sets +doAssert $(toSet([1])) == "{1}" +doAssert $(toSet(["1"])) == """{"1"}""" +doAssert $(toSet(['1'])) == """{'1'}""" +doAssert $(toOrderedSet([1, 2, 3])) == "{1, 2, 3}" +doAssert $(toOrderedSet(["1", "2", "3"])) == """{"1", "2", "3"}""" +doAssert $(toOrderedSet(['1', '2', '3'])) == """{'1', '2', '3'}""" + +# Tests for tables +doAssert $({1: "1", 2: "2"}.toTable) == """{1: "1", 2: "2"}""" +doAssert $({"1": 1, "2": 2}.toTable) == """{"1": 1, "2": 2}""" + +# Tests for deques +block: + var d = initDeque[int]() + d.addLast(1) + doAssert $d == "[1]" +block: + var d = initDeque[string]() + d.addLast("1") + doAssert $d == """["1"]""" +block: + var d = initDeque[char]() + d.addLast('1') + doAssert $d == "['1']" + +# Tests for lists +block: + var l = initDoublyLinkedList[int]() + l.append(1) + l.append(2) + l.append(3) + doAssert $l == "[1, 2, 3]" +block: + var l = initDoublyLinkedList[string]() + l.append("1") + l.append("2") + l.append("3") + doAssert $l == """["1", "2", "3"]""" +block: + var l = initDoublyLinkedList[char]() + l.append('1') + l.append('2') + l.append('3') + doAssert $l == """['1', '2', '3']""" + +# Tests for critbits +block: + var t: CritBitTree[int] + t["a"] = 1 + doAssert $t == "{a: 1}" +block: + var t: CritBitTree[string] + t["a"] = "1" + doAssert $t == """{a: "1"}""" +block: + var t: CritBitTree[char] + t["a"] = '1' + doAssert $t == "{a: '1'}" + + +# Test escaping behavior +block: + var s = "" + s.addQuoted('\0') + s.addQuoted('\31') + s.addQuoted('\127') + s.addQuoted('\255') + doAssert s == "'\\x00''\\x1F''\\x7F''\\xFF'" +block: + var s = "" + s.addQuoted('\\') + s.addQuoted('\'') + s.addQuoted('\"') + doAssert s == """'\\''\'''\"'""" + +# Test customized element representation +type CustomString = object + +proc addQuoted(s: var string, x: CustomString) = + s.add("<CustomString>") + +block: + let s = @[CustomString()] + doAssert $s == "@[<CustomString>]" + diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index 01dab44fc..7fe4c79b1 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -48,7 +48,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") block tableTest2: var t = initTable[string, float]() @@ -213,7 +213,8 @@ block clearCountTableTest: assert t.len() == 0 block withKeyTest: - var t = initSharedTable[int, int]() + var t: SharedTable[int, int] + t.init() t.withKey(1) do (k: int, v: var int, pairExists: var bool): assert(v == 0) pairExists = true diff --git a/tests/collections/ttablesref.nim b/tests/collections/ttablesref.nim index 12af1ccbb..a4030e0dc 100644 --- a/tests/collections/ttablesref.nim +++ b/tests/collections/ttablesref.nim @@ -47,7 +47,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") block tableTest2: var t = newTable[string, float]() @@ -139,7 +139,7 @@ proc orderedTableSortTest() = block anonZipTest: let keys = @['a','b','c'] let values = @[1, 2, 3] - doAssert "{a: 1, b: 2, c: 3}" == $ toTable zip(keys, values) + doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values) block clearTableTest: var t = newTable[string, float]() diff --git a/tests/concepts/t1128.nim b/tests/concepts/t1128.nim index 7f7525a13..69a2fa9b7 100644 --- a/tests/concepts/t1128.nim +++ b/tests/concepts/t1128.nim @@ -4,8 +4,8 @@ discard """ type TFooContainer[T] = object - - TContainer[T] = generic var c + + TContainer[T] = concept var c foo(c, T) proc foo[T](c: var TFooContainer[T], val: T) = diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim index fcd5054ef..722c0a0e0 100644 --- a/tests/concepts/t3330.nim +++ b/tests/concepts/t3330.nim @@ -6,10 +6,10 @@ but expected one of: proc test(foo: Foo[int]) t3330.nim(25, 8) Hint: Non-matching candidates for add(k, string, T) proc add(x: var string; y: string) +proc add(result: var string; x: float) proc add(x: var string; y: char) proc add(result: var string; x: int64) proc add(x: var string; y: cstring) -proc add(result: var string; x: float) proc add[T](x: var seq[T]; y: openArray[T]) proc add[T](x: var seq[T]; y: T) diff --git a/tests/concepts/t6462.nim b/tests/concepts/t6462.nim new file mode 100644 index 000000000..2fa2268f8 --- /dev/null +++ b/tests/concepts/t6462.nim @@ -0,0 +1,23 @@ +discard """ + output: "true" +""" + +import future + +type + FilterMixin*[T] = ref object + test*: (T) -> bool + trans*: (T) -> T + + SeqGen*[T] = ref object + fil*: FilterMixin[T] + + WithFilter[T] = concept a + a.fil is FilterMixin[T] + +proc test*[T](a: WithFilter[T]): (T) -> bool = + a.fil.test + +var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) +echo s.test() == nil + diff --git a/tests/concepts/tcomparable.nim b/tests/concepts/tcomparable.nim new file mode 100644 index 000000000..06612a47e --- /dev/null +++ b/tests/concepts/tcomparable.nim @@ -0,0 +1,13 @@ +type + Comparable = concept a + (a < a) is bool + +proc myMax(a, b: Comparable): Comparable = + if a < b: + return b + else: + return a + +doAssert myMax(5, 10) == 10 +doAssert myMax(31.3, 1.23124) == 31.3 + diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 417d1e502..de8ddf890 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -1,62 +1,66 @@ discard """ cmd: "nim c --verbosity:0 --colors:off $file" nimout: ''' -texplain.nim(99, 10) Hint: Non-matching candidates for e(y) +texplain.nim(103, 10) Hint: Non-matching candidates for e(y) proc e(i: int): int -texplain.nim(102, 7) Hint: Non-matching candidates for e(10) +texplain.nim(106, 7) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(65, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed -texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(66, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed - -texplain.nim(105, 10) Hint: Non-matching candidates for e(10) +texplain.nim(69, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(69, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(69, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed +texplain.nim(70, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(70, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(70, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed + +texplain.nim(109, 10) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(65, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed -texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(66, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed - -texplain.nim(109, 20) Error: type mismatch: got (NonMatchingType) -but expected one of: +texplain.nim(69, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(69, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(69, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed +texplain.nim(70, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(70, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(70, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed + +texplain.nim(113, 20) Error: type mismatch: got (NonMatchingType) +but expected one of: proc e(o: ExplainedConcept): int -texplain.nim(65, 5) ExplainedConcept: concept predicate failed +texplain.nim(69, 5) ExplainedConcept: concept predicate failed proc e(i: int): int -texplain.nim(110, 20) Error: type mismatch: got (NonMatchingType) -but expected one of: +expression: e(n) +texplain.nim(114, 20) Error: type mismatch: got (NonMatchingType) +but expected one of: proc r(o: RegularConcept): int -texplain.nim(69, 5) RegularConcept: concept predicate failed +texplain.nim(73, 5) RegularConcept: concept predicate failed proc r[T](a: SomeNumber; b: T; c: auto) proc r(i: string): int -texplain.nim(111, 20) Hint: Non-matching candidates for r(y) +expression: r(n) +texplain.nim(115, 20) Hint: Non-matching candidates for r(y) proc r[T](a: SomeNumber; b: T; c: auto) proc r(i: string): int -texplain.nim(119, 2) Error: type mismatch: got (MatchingType) -but expected one of: +texplain.nim(123, 2) Error: type mismatch: got (MatchingType) +but expected one of: proc f(o: NestedConcept) -texplain.nim(69, 6) RegularConcept: undeclared field: 'foo' -texplain.nim(69, 6) RegularConcept: undeclared field: '.' -texplain.nim(69, 6) RegularConcept: expression '.' cannot be called -texplain.nim(69, 5) RegularConcept: concept predicate failed -texplain.nim(70, 6) RegularConcept: undeclared field: 'bar' -texplain.nim(70, 6) RegularConcept: undeclared field: '.' -texplain.nim(70, 6) RegularConcept: expression '.' cannot be called -texplain.nim(69, 5) RegularConcept: concept predicate failed -texplain.nim(73, 5) NestedConcept: concept predicate failed +texplain.nim(73, 6) RegularConcept: undeclared field: 'foo' +texplain.nim(73, 6) RegularConcept: undeclared field: '.' +texplain.nim(73, 6) RegularConcept: expression '.' cannot be called +texplain.nim(73, 5) RegularConcept: concept predicate failed +texplain.nim(74, 6) RegularConcept: undeclared field: 'bar' +texplain.nim(74, 6) RegularConcept: undeclared field: '.' +texplain.nim(74, 6) RegularConcept: expression '.' cannot be called +texplain.nim(73, 5) RegularConcept: concept predicate failed +texplain.nim(77, 5) NestedConcept: concept predicate failed + +expression: f(y) ''' - line: 119 + line: 123 errormsg: "type mismatch: got (MatchingType)" """ diff --git a/tests/concepts/tinfrecursion.nim b/tests/concepts/tinfrecursion.nim new file mode 100644 index 000000000..60db410de --- /dev/null +++ b/tests/concepts/tinfrecursion.nim @@ -0,0 +1,13 @@ + +# bug #6691 +type + ConceptA = concept c + + ConceptB = concept c + c.myProc(ConceptA) + + Obj = object + +proc myProc(obj: Obj, x: ConceptA) = discard + +echo Obj is ConceptB diff --git a/tests/concepts/titerable.nim b/tests/concepts/titerable.nim new file mode 100644 index 000000000..b18658b2a --- /dev/null +++ b/tests/concepts/titerable.nim @@ -0,0 +1,20 @@ +discard """ + nimout: "int\nint" + output: 15 +""" + +import typetraits + +type + Iterable[T] = concept x + for value in x: + type(value) is T + +proc sum*[T](iter: Iterable[T]): T = + static: echo T.name + for element in iter: + static: echo element.type.name + result += element + +echo sum([1, 2, 3, 4, 5]) + diff --git a/tests/concepts/tmapconcept.nim b/tests/concepts/tmapconcept.nim index 81caed7c6..5082fcb61 100644 --- a/tests/concepts/tmapconcept.nim +++ b/tests/concepts/tmapconcept.nim @@ -1,7 +1,7 @@ discard """ output: '''10 10 -nil + 1''' msg: ''' K=string V=int diff --git a/tests/concepts/tmisc_issues.nim b/tests/concepts/tmisc_issues.nim index d9bb84a2f..662eba380 100644 --- a/tests/concepts/tmisc_issues.nim +++ b/tests/concepts/tmisc_issues.nim @@ -31,7 +31,7 @@ type ConcretePointOfFloat = object type ConcretePoint[Value] = object x, y: Value -type AbstractPointOfFloat = generic p +type AbstractPointOfFloat = concept p p.x is float and p.y is float let p1 = ConcretePointOfFloat(x: 0, y: 0) @@ -89,10 +89,10 @@ type B = object proc size(self: B): int = - return -1 + return -1 proc size(self: A): int = - return 0 + return 0 let b = B() echo b is A diff --git a/tests/cpp/tasync_cpp.nim b/tests/cpp/tasync_cpp.nim index ec78ae26c..a5e3374b6 100644 --- a/tests/cpp/tasync_cpp.nim +++ b/tests/cpp/tasync_cpp.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: "hello" """ diff --git a/tests/cpp/tcasts.nim b/tests/cpp/tcasts.nim new file mode 100644 index 000000000..24ebb8f62 --- /dev/null +++ b/tests/cpp/tcasts.nim @@ -0,0 +1,11 @@ +discard """ + cmd: "nim cpp $file" + output: "" + targets: "cpp" +""" + +block: #5979 + var a = 'a' + var p: pointer = cast[pointer](a) + var c = cast[char](p) + doAssert(c == 'a') diff --git a/tests/cpp/tcovariancerules.nim b/tests/cpp/tcovariancerules.nim index dfe4cb941..9365a3a18 100644 --- a/tests/cpp/tcovariancerules.nim +++ b/tests/cpp/tcovariancerules.nim @@ -1,5 +1,5 @@ discard """ -cmd: "nim cpp $file" +targets: "cpp" output: ''' cat cat diff --git a/tests/cpp/tcppraise.nim b/tests/cpp/tcppraise.nim index a9ea8e6ce..7db9c0cfa 100644 --- a/tests/cpp/tcppraise.nim +++ b/tests/cpp/tcppraise.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''foo bar Need odd and >= 3 digits## diff --git a/tests/cpp/tdont_init_instantiation.nim b/tests/cpp/tdont_init_instantiation.nim index 652cb1414..fe487fba0 100644 --- a/tests/cpp/tdont_init_instantiation.nim +++ b/tests/cpp/tdont_init_instantiation.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''''' disabled: true """ diff --git a/tests/cpp/tembarrassing_generic_failure.nim b/tests/cpp/tembarrassing_generic_failure.nim index 3c31dcdb8..4b5050948 100644 --- a/tests/cpp/tembarrassing_generic_failure.nim +++ b/tests/cpp/tembarrassing_generic_failure.nim @@ -1,4 +1,5 @@ discard """ + targets: "cpp" cmd: "nim cpp --threads:on $file" """ diff --git a/tests/cpp/temitlist.nim b/tests/cpp/temitlist.nim index cef0fc52d..a7a8ebde4 100644 --- a/tests/cpp/temitlist.nim +++ b/tests/cpp/temitlist.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''6.0''' """ diff --git a/tests/cpp/tempty_generic_obj.nim b/tests/cpp/tempty_generic_obj.nim index e2957a5cd..b4c746a30 100644 --- a/tests/cpp/tempty_generic_obj.nim +++ b/tests/cpp/tempty_generic_obj.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''int float''' """ diff --git a/tests/cpp/tgen_prototype_for_importc.nim b/tests/cpp/tgen_prototype_for_importc.nim index 91f34755b..4e5a197a8 100644 --- a/tests/cpp/tgen_prototype_for_importc.nim +++ b/tests/cpp/tgen_prototype_for_importc.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''Hello world''' """ diff --git a/tests/cpp/tget_subsystem.nim b/tests/cpp/tget_subsystem.nim index 81009dd39..6fb095a3d 100644 --- a/tests/cpp/tget_subsystem.nim +++ b/tests/cpp/tget_subsystem.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ {.emit: """ @@ -22,10 +22,18 @@ proc getSubsystem*[T](): ptr T {. let input: ptr Input = getSubsystem[Input]() -# bug #4910 +# bugs #4910, #6892 +proc modify(x: var int) = + x = 123 proc foo() = - var ts: array[10, int] + var ts: array[2, int] for t in mitems(ts): - t = 123 + discard + + for t in mitems(ts): + modify(t) + + for i, t in mpairs(ts): + modify(t) diff --git a/tests/cpp/tnativesockets.nim b/tests/cpp/tnativesockets.nim index 6108380a8..c62008050 100644 --- a/tests/cpp/tnativesockets.nim +++ b/tests/cpp/tnativesockets.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ import nativesockets diff --git a/tests/cpp/treturn_array.nim b/tests/cpp/treturn_array.nim index ba4fbd6cc..432b9ce3b 100644 --- a/tests/cpp/treturn_array.nim +++ b/tests/cpp/treturn_array.nim @@ -1,3 +1,6 @@ +discard """ + targets: "cpp" +""" # bug #2259 type Mat4f* = array[0..15, float] diff --git a/tests/cpp/tsigbreak.nim b/tests/cpp/tsigbreak.nim index c8044f2bf..9a381d84f 100644 --- a/tests/cpp/tsigbreak.nim +++ b/tests/cpp/tsigbreak.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ import tables, lists diff --git a/tests/cpp/tstaticvar_via_typedesc.nim b/tests/cpp/tstaticvar_via_typedesc.nim index 7a9fa2afc..0d8f424d0 100644 --- a/tests/cpp/tstaticvar_via_typedesc.nim +++ b/tests/cpp/tstaticvar_via_typedesc.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: "42" """ diff --git a/tests/cpp/ttemplatetype.nim b/tests/cpp/ttemplatetype.nim index 7f56a225d..ef24e4cdc 100644 --- a/tests/cpp/ttemplatetype.nim +++ b/tests/cpp/ttemplatetype.nim @@ -1,3 +1,7 @@ +discard """ + targets: "cpp" +""" + type Map {.importcpp: "std::map", header: "<map>".} [T,U] = object diff --git a/tests/cpp/tthread_createthread.nim b/tests/cpp/tthread_createthread.nim index 363136e9d..b46b876b7 100644 --- a/tests/cpp/tthread_createthread.nim +++ b/tests/cpp/tthread_createthread.nim @@ -1,4 +1,5 @@ discard """ + targets: "cpp" cmd: "nim cpp --hints:on --threads:on $options $file" """ diff --git a/tests/cpp/ttypeinfo.nim b/tests/cpp/ttypeinfo.nim index 282c682b2..97825f452 100644 --- a/tests/cpp/ttypeinfo.nim +++ b/tests/cpp/ttypeinfo.nim @@ -1,6 +1,6 @@ discard """ + targets: "cpp" output: '''100''' - cmd: "nim cpp $file" """ import typeinfo diff --git a/tests/cpp/ttypeinfo2.nim b/tests/cpp/ttypeinfo2.nim index 64bd43e96..e3661c848 100644 --- a/tests/cpp/ttypeinfo2.nim +++ b/tests/cpp/ttypeinfo2.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ # bug #2841 import typeinfo diff --git a/tests/cpp/tvector_iterator.nim b/tests/cpp/tvector_iterator.nim index cb5ab33af..9df3754ba 100644 --- a/tests/cpp/tvector_iterator.nim +++ b/tests/cpp/tvector_iterator.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ {.emit: """ diff --git a/tests/cpp/tvectorseq.nim b/tests/cpp/tvectorseq.nim index 6eb5dc9e4..4d9ffc3d6 100644 --- a/tests/cpp/tvectorseq.nim +++ b/tests/cpp/tvectorseq.nim @@ -1,7 +1,7 @@ discard """ + targets: "cpp" output: '''(x: 1.0) (x: 0.0)''' - cmd: "nim cpp $file" disabled: "true" """ diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim new file mode 100644 index 000000000..d20596415 --- /dev/null +++ b/tests/destructor/tatomicptrs.nim @@ -0,0 +1,101 @@ +discard """ + output: '''allocating +allocating +allocating +55 +60 +99 +deallocating +deallocating +deallocating +''' + cmd: '''nim c --newruntime $file''' +""" + +type + SharedPtr*[T] = object + x: ptr T + +#proc isNil[T](s: SharedPtr[T]): bool {.inline.} = s.x.isNil + +template incRef(x) = + atomicInc(x.refcount) + +template decRef(x): untyped = atomicDec(x.refcount) + +proc makeShared*[T](x: T): SharedPtr[T] = + # XXX could benefit from 'sink' parameter. + # XXX could benefit from a macro that generates it. + result = cast[SharedPtr[T]](allocShared(sizeof(x))) + result.x[] = x + echo "allocating" + +proc `=destroy`*[T](dest: var SharedPtr[T]) = + var s = dest.x + if s != nil and decRef(s) == 0: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + dest.x = nil + +proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) = + var s = src.x + if s != nil: incRef(s) + #atomicSwap(dest, s) + # XXX use an atomic store here: + swap(dest.x, s) + if s != nil and decRef(s) == 0: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + +proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) = + ## XXX make this an atomic store: + if dest.x != src.x: + let s = dest.x + if s != nil: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + dest.x = src.x + +template `.`*[T](s: SharedPtr[T]; field: untyped): untyped = + s.x.field + +template `.=`*[T](s: SharedPtr[T]; field, value: untyped) = + s.x.field = value + +from macros import unpackVarargs + +template `.()`*[T](s: SharedPtr[T]; field: untyped, args: varargs[untyped]): untyped = + unpackVarargs(s.x.field, args) + + +type + Tree = SharedPtr[TreeObj] + TreeObj = object + refcount: int + le, ri: Tree + data: int + +proc takesTree(a: Tree) = + if not a.isNil: + takesTree(a.le) + echo a.data + takesTree(a.ri) + +proc createTree(data: int): Tree = + result = makeShared(TreeObj(refcount: 1, data: data)) + +proc createTree(data: int; le, ri: Tree): Tree = + result = makeShared(TreeObj(refcount: 1, le: le, ri: ri, data: data)) + + +proc main = + let le = createTree(55) + let ri = createTree(99) + let t = createTree(60, le, ri) + takesTree(t) + +main() + diff --git a/tests/destructor/tcustomseqs.nim b/tests/destructor/tcustomseqs.nim new file mode 100644 index 000000000..97d7c07b6 --- /dev/null +++ b/tests/destructor/tcustomseqs.nim @@ -0,0 +1,143 @@ +discard """ + output: '''1 +2 +3 +4 +5 +6 +89 +90 +90 +0 0 1 +0 1 2 +0 2 3 +1 0 4 +1 1 5 +1 2 6 +1 3 7 +after 6 6''' + cmd: '''nim c --newruntime $file''' +""" + +import typetraits + +type + myseq*[T] = object + len, cap: int + data: ptr UncheckedArray[T] + +# XXX make code memory safe for overflows in '*' +var + allocCount, deallocCount: int + +proc `=destroy`*[T](x: var myseq[T]) = + if x.data != nil: + when not supportsCopyMem(T): + for i in 0..<x.len: `=destroy`(x[i]) + dealloc(x.data) + inc deallocCount + x.data = nil + x.len = 0 + x.cap = 0 + +proc `=`*[T](a: var myseq[T]; b: myseq[T]) = + if a.data == b.data: return + if a.data != nil: + dealloc(a.data) + inc deallocCount + a.data = nil + a.len = b.len + a.cap = b.cap + if b.data != nil: + a.data = cast[type(a.data)](alloc(a.cap * sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(a.data, b.data, a.cap * sizeof(T)) + else: + for i in 0..<a.len: + a.data[i] = b.data[i] + +proc `=sink`*[T](a: var myseq[T]; b: myseq[T]) = + if a.data != nil and a.data != b.data: + dealloc(a.data) + inc deallocCount + a.len = b.len + a.cap = b.cap + a.data = b.data + +proc resize[T](s: var myseq[T]) = + if s.cap == 0: s.cap = 8 + else: s.cap = (s.cap * 3) shr 1 + if s.data == nil: inc allocCount + s.data = cast[type(s.data)](realloc(s.data, s.cap * sizeof(T))) + +proc reserveSlot[T](x: var myseq[T]): ptr T = + if x.len >= x.cap: resize(x) + result = addr(x.data[x.len]) + inc x.len + +template add*[T](x: var myseq[T]; y: T) = + reserveSlot(x)[] = y + +proc shrink*[T](x: var myseq[T]; newLen: int) = + assert newLen <= x.len + assert newLen >= 0 + when not supportsCopyMem(T): + for i in countdown(x.len - 1, newLen - 1): + `=destroy`(x.data[i]) + x.len = newLen + +proc grow*[T](x: var myseq[T]; newLen: int; value: T) = + if newLen <= x.len: return + assert newLen >= 0 + if x.cap == 0: x.cap = newLen + else: x.cap = max(newLen, (x.cap * 3) shr 1) + if x.data == nil: inc allocCount + x.data = cast[type(x.data)](realloc(x.data, x.cap * sizeof(T))) + for i in x.len..<newLen: + x.data[i] = value + x.len = newLen + +template default[T](t: typedesc[T]): T = + var v: T + v + +proc setLen*[T](x: var myseq[T]; newLen: int) {.deprecated.} = + if newlen < x.len: shrink(x, newLen) + else: grow(x, newLen, default(T)) + +template `[]`*[T](x: myseq[T]; i: Natural): T = + assert i < x.len + x.data[i] + +template `[]=`*[T](x: myseq[T]; i: Natural; y: T) = + assert i < x.len + x.data[i] = y + +proc createSeq*[T](elems: varargs[T]): myseq[T] = + result.cap = elems.len + result.len = elems.len + result.data = cast[type(result.data)](alloc(result.cap * sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(result.data, unsafeAddr(elems[0]), result.cap * sizeof(T)) + else: + for i in 0..<result.len: + result.data[i] = elems[i] + +proc len*[T](x: myseq[T]): int {.inline.} = x.len + +proc main = + var s = createSeq(1, 2, 3, 4, 5, 6) + s.add 89 + s.grow s.len + 2, 90 + for i in 0 ..< s.len: + echo s[i] + + var nested = createSeq(createSeq(1, 2, 3), createSeq(4, 5, 6, 7)) + for i in 0 ..< nested.len: + for j in 0 ..< nested[i].len: + echo i, " ", j, " ", nested[i][j] + +main() +echo "after ", allocCount, " ", deallocCount diff --git a/tests/destructor/tcustomstrings.nim b/tests/destructor/tcustomstrings.nim index 2250d4772..1a78df20b 100644 --- a/tests/destructor/tcustomstrings.nim +++ b/tests/destructor/tcustomstrings.nim @@ -4,27 +4,27 @@ foo bar to appendmore here foo bar to appendmore here foo bar to appendmore here foo bar to appendmore here -after 16 16''' +after 20 20''' cmd: '''nim c --newruntime $file''' """ +{.this: self.} + type mystring = object len, cap: int data: ptr UncheckedArray[char] -{.this: self.} - var allocCount, deallocCount: int -proc `=destroy`*(self: var mystring) = - if data != nil: - dealloc(data) +proc `=destroy`*(s: var mystring) = + if s.data != nil: + dealloc(s.data) inc deallocCount - data = nil - len = 0 - cap = 0 + s.data = nil + s.len = 0 + s.cap = 0 proc `=sink`*(a: var mystring, b: mystring) = # we hope this is optimized away for not yet alive objects: @@ -48,10 +48,10 @@ proc `=`*(a: var mystring; b: mystring) = copyMem(a.data, b.data, a.cap+1) proc resize(self: var mystring) = - if cap == 0: cap = 8 - else: cap = (cap * 3) shr 1 - if data == nil: inc allocCount - data = cast[type(data)](realloc(data, cap + 1)) + if self.cap == 0: self.cap = 8 + else: self.cap = (self.cap * 3) shr 1 + if self.data == nil: inc allocCount + self.data = cast[type(data)](realloc(self.data, self.cap + 1)) proc add*(self: var mystring; c: char) = if self.len >= self.cap: resize(self) @@ -92,5 +92,8 @@ proc main(n: int) = a.add c echo cstring(a.data) + var x: array[4, mystring] + for i in 0..high(x): x[i] = create"added to array" + main(1000) echo "after ", allocCount, " ", deallocCount diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim index 639dba941..c9f1caf2d 100644 --- a/tests/destructor/tdestructor.nim +++ b/tests/destructor/tdestructor.nim @@ -20,10 +20,10 @@ myobj destroyed ---- myobj destroyed ''' + cmd: '''nim c --newruntime $file''' + disabled: "true" """ -{.experimental.} - type TMyObj = object x, y: int @@ -61,7 +61,7 @@ proc `=destroy`(o: var TMyObj) = if o.p != nil: dealloc o.p echo "myobj destroyed" -proc `=destroy`(o: var TMyGeneric1) = +proc `=destroy`(o: var TMyGeneric1[int]) = echo "mygeneric1 destroyed" proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) = diff --git a/tests/destructor/tdestructor2.nim b/tests/destructor/tdestructor2.nim deleted file mode 100644 index 34fa466af..000000000 --- a/tests/destructor/tdestructor2.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - line: 23 - nimout: " usage of a type with a destructor in a non destructible context" -""" - -{.experimental.} - -type - TMyObj = object - x, y: int - p: pointer - -proc `=destroy`(o: var TMyObj) = - if o.p != nil: dealloc o.p - -proc open: TMyObj = - result = TMyObj(x: 1, y: 2, p: alloc(3)) - - -proc `$`(x: TMyObj): string = $x.y - -proc foo = - discard open() - -# XXX doesn't trigger this yet: -#echo open() - diff --git a/tests/destructor/tdestructor3.nim b/tests/destructor/tdestructor3.nim index d0c53c7bd..3e177d3cd 100644 --- a/tests/destructor/tdestructor3.nim +++ b/tests/destructor/tdestructor3.nim @@ -2,14 +2,14 @@ discard """ output: '''assign destroy destroy -destroy Foo: 5 5 -destroy Foo: 123 -123''' +123 +destroy Foo: 5 +destroy Foo: 123''' + cmd: '''nim c --newruntime $file''' """ # bug #2821 -{.experimental.} type T = object diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim new file mode 100644 index 000000000..8aa12ed05 --- /dev/null +++ b/tests/destructor/tmove_objconstr.nim @@ -0,0 +1,59 @@ + +discard """ +output: '''test created +test destroyed 0 +1 +2 +3 +4 +Pony is dying!''' + cmd: '''nim c --newruntime $file''' +""" + +# bug #4214 +type + Data = object + data: string + rc: int + +proc `=destroy`(d: var Data) = + dec d.rc + echo d.data, " destroyed ", d.rc + +proc `=`(dst: var Data, src: Data) = + echo src.data, " copied" + dst.data = src.data & " (copy)" + dec dst.rc + inc dst.rc + +proc initData(s: string): Data = + result = Data(data: s, rc: 1) + echo s, " created" + +proc pointlessWrapper(s: string): Data = + result = initData(s) + +proc main = + var x = pointlessWrapper"test" + +when isMainModule: + main() + +# bug #985 + +type + Pony = object + name: string + +proc `=destroy`(o: var Pony) = + echo "Pony is dying!" + +proc getPony: Pony = + result.name = "Sparkles" + +iterator items(p: Pony): int = + for i in 1..4: + yield i + +for x in getPony(): + echo x diff --git a/tests/destructor/topttree.nim b/tests/destructor/topttree.nim new file mode 100644 index 000000000..924644392 --- /dev/null +++ b/tests/destructor/topttree.nim @@ -0,0 +1,104 @@ +discard """ + output: '''10.0 +60.0 +90.0 +120.0 +10.0 +60.0 +90.0 +120.0 +8 8''' + cmd: '''nim c --newruntime $file''' +""" + +import typetraits + +type + opt[T] = object + data: ptr T + +var + allocCount, deallocCount: int + +proc `=destroy`*[T](x: var opt[T]) = + if x.data != nil: + when not supportsCopyMem(T): + `=destroy`(x.data[]) + dealloc(x.data) + inc deallocCount + x.data = nil + +proc `=`*[T](a: var opt[T]; b: opt[T]) = + if a.data == b.data: return + if a.data != nil: + dealloc(a.data) + inc deallocCount + a.data = nil + if b.data != nil: + a.data = cast[type(a.data)](alloc(sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(a.data, b.data, sizeof(T)) + else: + a.data[] = b.data[] + +proc `=sink`*[T](a: var opt[T]; b: opt[T]) = + if a.data != nil and a.data != b.data: + dealloc(a.data) + inc deallocCount + a.data = b.data + +proc createOpt*[T](x: T): opt[T] = + result.data = cast[type(result.data)](alloc(sizeof(T))) + inc allocCount + result.data[] = x + +template `[]`[T](x: opt[T]): T = + assert x.p != nil, "attempt to read from moved/destroyed value" + x.p[] + +template `?=`[T](it: untyped; x: opt[T]): bool = + template it: untyped {.inject.} = x.data[] + if x.data != nil: + true + else: + false + +type + Tree = object + data: float + le, ri: opt[Tree] + +proc createTree(data: float): Tree = + result.data = data + +proc insert(t: var opt[Tree]; newVal: float) = + #if it ?= t: + if t.data != nil: + if newVal < t.data[].data: + insert(t.data[].le, newVal) + elif t.data[].data < newVal: + insert(t.data[].ri, newVal) + else: + discard "already in the tree" + else: + t = createOpt(Tree(data: newVal)) + +proc write(t: opt[Tree]) = + if it ?= t: + write(it.le) + write stdout, it.data, "\n" + write(it.ri) + +proc main = + var t: opt[Tree] + insert t, 60.0 + insert t, 90.0 + insert t, 10.0 + insert t, 120.0 + write t + let copy = t + write copy + +main() +echo allocCount, " ", deallocCount diff --git a/tests/errmsgs/tmake_tuple_visible.nim b/tests/errmsgs/tmake_tuple_visible.nim new file mode 100644 index 000000000..43337c2a9 --- /dev/null +++ b/tests/errmsgs/tmake_tuple_visible.nim @@ -0,0 +1,23 @@ +discard """ + errormsg: '''got (tuple of (type NimEdAppWindow, int))''' + line: 22 + nimout: '''got (tuple of (type NimEdAppWindow, int)) +but expected one of: +template xxx(tn: typedesc; i: int)''' +""" + +type + NimEdAppWindow = ptr NimEdAppWindowObj + NimEdAppWindowObj = object + i: int + +template gDefineTypeExtended*(tn: typeDesc) = + discard + +gDefineTypeExtended (NimEdAppWindow) + +template xxx*(tn: typeDesc, i: int) = + discard + +xxx (NimEdAppWindow, 0) +# bug #6776 diff --git a/tests/exprs/texprstmt.nim b/tests/exprs/texprstmt.nim index 0e92702e8..6c9759cf5 100644 --- a/tests/exprs/texprstmt.nim +++ b/tests/exprs/texprstmt.nim @@ -1,6 +1,6 @@ discard """ line: 10 - errormsg: "expression 'result[1 .. -(len(result), 1)]' is of type 'string' and has to be discarded" + errormsg: "expression 'result[1 .. BackwardsIndex(1)]' is of type 'string' and has to be discarded" """ # bug #578 diff --git a/tests/exprs/tstmtexprs.nim b/tests/exprs/tstmtexprs.nim index b2d5db408..2a0ec2821 100644 --- a/tests/exprs/tstmtexprs.nim +++ b/tests/exprs/tstmtexprs.nim @@ -1,11 +1,12 @@ discard """ output: '''24 -(bar: bar) +(bar: "bar") 1244 6 abcdefghijklmnopqrstuvwxyz 145 23 -3''' +3 +2''' """ import strutils @@ -122,3 +123,31 @@ var testTry = PFooBase(field: 5) echo(testTry.field) + +# bug #6166 + +proc quo(op: proc (x: int): bool): int = + result = + if op(3): + 2 + else: + 0 + +echo( + if true: + quo do (a: int) -> bool: + a mod 2 != 0 + else: + quo do (a: int) -> bool: + a mod 3 != 0 +) + +# bug #6980 + +proc fooBool: bool {.discardable.} = + true + +if true: + fooBool() +else: + raise newException(ValueError, "argh") diff --git a/tests/fields/timplicitfieldswithpartial.nim b/tests/fields/timplicitfieldswithpartial.nim index 996912a1a..937833257 100644 --- a/tests/fields/timplicitfieldswithpartial.nim +++ b/tests/fields/timplicitfieldswithpartial.nim @@ -1,6 +1,8 @@ discard """ - output: '''(foo: 38, other: string here) -43''' + output: '''(foo: 38, other: "string here") +43 +100 +90''' """ type @@ -17,3 +19,17 @@ proc my(f: Foo) = var g: Foo new(g) my(g) + +type + FooTask {.partial.} = ref object of RootObj + +proc foo(t: FooTask) {.liftLocals: t.} = + var x = 90 + if true: + var x = 10 + while x < 100: + inc x + echo x + echo x + +foo(FooTask()) diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim new file mode 100644 index 000000000..aa288d342 --- /dev/null +++ b/tests/float/tfloatnan.nim @@ -0,0 +1,16 @@ +discard """ + file: "tfloatnan.nim" + output: '''Nim: nan +Nim: nan (float) +Nim: nan (double) +''' +""" + +let f = NaN +echo "Nim: ", f + +let f32: float32 = NaN +echo "Nim: ", f32, " (float)" + +let f64: float64 = NaN +echo "Nim: ", f64, " (double)" diff --git a/tests/float/tlenientops.nim b/tests/float/tlenientops.nim new file mode 100644 index 000000000..586580670 --- /dev/null +++ b/tests/float/tlenientops.nim @@ -0,0 +1,100 @@ +discard """ + exitcode: 0 + output: "" +""" + +import lenientops + +proc `~=`[T](a, b: T): bool = abs(a - b) < 1e-7 + +block: # math binary operators + let i = 1 + let f = 2.0 + + doAssert i + f ~= 3 + doAssert f + i ~= 3 + + doAssert i - f ~= -1 + doAssert f - i ~= 1 + + doAssert i * f ~= 2 + doAssert f * i ~= 2 + + doAssert i / f ~= 0.5 + doAssert f / i ~= 2 + +block: # comparison operators + doAssert 1.int < 2.float + doAssert 1.float < 2.int + doAssert 1.int <= 2.float + doAssert 1.float <= 2.int + doAssert 2.int >= 1.float + doAssert 2.float >= 1.int + doAssert 2.int > 1.float + doAssert 2.float > 1.int + +block: # all type combinations + let i = 1 + let f = 2.0 + + doAssert i.int + f.float ~= 3 + doAssert i.int + f.float32 ~= 3 + doAssert i.int + f.float64 ~= 3 + doAssert i.int8 + f.float ~= 3 + doAssert i.int8 + f.float32 ~= 3 + doAssert i.int8 + f.float64 ~= 3 + doAssert i.int16 + f.float ~= 3 + doAssert i.int16 + f.float32 ~= 3 + doAssert i.int16 + f.float64 ~= 3 + doAssert i.int32 + f.float ~= 3 + doAssert i.int32 + f.float32 ~= 3 + doAssert i.int32 + f.float64 ~= 3 + doAssert i.int64 + f.float ~= 3 + doAssert i.int64 + f.float32 ~= 3 + doAssert i.int64 + f.float64 ~= 3 + doAssert i.uint + f.float ~= 3 + doAssert i.uint + f.float32 ~= 3 + doAssert i.uint + f.float64 ~= 3 + doAssert i.uint8 + f.float ~= 3 + doAssert i.uint8 + f.float32 ~= 3 + doAssert i.uint8 + f.float64 ~= 3 + doAssert i.uint16 + f.float ~= 3 + doAssert i.uint16 + f.float32 ~= 3 + doAssert i.uint16 + f.float64 ~= 3 + doAssert i.uint32 + f.float ~= 3 + doAssert i.uint32 + f.float32 ~= 3 + doAssert i.uint32 + f.float64 ~= 3 + doAssert i.uint64 + f.float ~= 3 + doAssert i.uint64 + f.float32 ~= 3 + doAssert i.uint64 + f.float64 ~= 3 + + doAssert f.float + i.int ~= 3 + doAssert f.float32 + i.int ~= 3 + doAssert f.float64 + i.int ~= 3 + doAssert f.float + i.int8 ~= 3 + doAssert f.float32 + i.int8 ~= 3 + doAssert f.float64 + i.int8 ~= 3 + doAssert f.float + i.int16 ~= 3 + doAssert f.float32 + i.int16 ~= 3 + doAssert f.float64 + i.int16 ~= 3 + doAssert f.float + i.int32 ~= 3 + doAssert f.float32 + i.int32 ~= 3 + doAssert f.float64 + i.int32 ~= 3 + doAssert f.float + i.int64 ~= 3 + doAssert f.float32 + i.int64 ~= 3 + doAssert f.float64 + i.int64 ~= 3 + doAssert f.float + i.uint ~= 3 + doAssert f.float32 + i.uint ~= 3 + doAssert f.float64 + i.uint ~= 3 + doAssert f.float + i.uint8 ~= 3 + doAssert f.float32 + i.uint8 ~= 3 + doAssert f.float64 + i.uint8 ~= 3 + doAssert f.float + i.uint16 ~= 3 + doAssert f.float32 + i.uint16 ~= 3 + doAssert f.float64 + i.uint16 ~= 3 + doAssert f.float + i.uint32 ~= 3 + doAssert f.float32 + i.uint32 ~= 3 + doAssert f.float64 + i.uint32 ~= 3 + doAssert f.float + i.uint64 ~= 3 + doAssert f.float32 + i.uint64 ~= 3 + doAssert f.float64 + i.uint64 ~= 3 diff --git a/tests/fragmentation/data.nim b/tests/fragmentation/data.nim new file mode 100644 index 000000000..d14123c0f --- /dev/null +++ b/tests/fragmentation/data.nim @@ -0,0 +1,7629 @@ + +const sizes* = [ + 643584, + 140800, + 802, + 2464928, + 488122, + 1161601, + 861051, + 1413, + 389, + 2412032, + 328704, + 323488, + 484864, + 31232, + 38400, + 87552, + 328704, + 242176, + 55808, + 32256, + 15360, + 15080, + 567074, + 1390, + 1390, + 366080, + 186536, + 314368, + 4154, + 3017582, + 62658, + 3874662, + 227, + 126616, + 290, + 261792, + 287, + 151200, + 293, + 34976, + 293, + 28840, + 296, + 20664, + 314, + 223232, + 288, + 53248, + 326, + 12800, + 312, + 473600, + 306, + 2676224, + 308, + 2846720, + 308, + 563712, + 308, + 567296, + 308, + 576000, + 308, + 577024, + 308, + 577536, + 308, + 577536, + 308, + 578560, + 308, + 578560, + 308, + 145920, + 310, + 159232, + 312, + 364544, + 310, + 178176, + 312, + 8032448, + 323, + 29392, + 332, + 35112, + 394, + 85768, + 371, + 88864, + 385, + 23840, + 385, + 176128, + 386, + 126976, + 389, + 24800, + 401, + 118784, + 379, + 21792, + 385, + 259152, + 385, + 172032, + 389, + 40960, + 389, + 114688, + 403, + 57344, + 407, + 7680, + 407, + 126216, + 373, + 29952, + 367, + 148768, + 385, + 27384, + 362, + 24832, + 362, + 50944, + 364, + 20136, + 302, + 32416, + 293, + 69296, + 305, + 36016, + 308, + 89784, + 305, + 5120, + 305, + 49152, + 320, + 30424, + 331, + 12288, + 326, + 62976, + 69120, + 72192, + 503808, + 77824, + 382144, + 163840, + 88728, + 1581, + 1718096, + 66728, + 82172, + 116756, + 4554752, + 59342, + 45794, + 39284, + 66384, + 60294, + 83748, + 83748, + 262148, + 20320, + 28288, + 382, + 3072, + 4222976, + 161, + 1737888, + 2975744, + 487424, + 258048, + 113664, + 372736, + 261632, + 5287936, + 80896, + 89600, + 503808, + 77824, + 554176, + 163840, + 84632, + 1581, + 1714000, + 66728, + 82172, + 116756, + 4571136, + 59342, + 45794, + 39284, + 66384, + 60294, + 83748, + 83748, + 262148, + 20320, + 28288, + 4006400, + 161, + 2256032, + 3150336, + 503296, + 245760, + 133120, + 358400, + 283136, + 5296128, + 10752, + 507904, + 315392, + 11264, + 921600, + 7680, + 118784, + 166560, + 13312, + 5120, + 18768, + 52736, + 8192, + 77824, + 6656, + 106496, + 389120, + 733184, + 53248, + 36864, + 36864, + 655360, + 139264, + 802816, + 169864, + 77824, + 10752, + 94208, + 17808, + 40960, + 36864, + 749568, + 45056, + 188416, + 28672, + 16384, + 69632, + 102400, + 11776, + 10752, + 290816, + 36864, + 36864, + 667648, + 53248, + 49152, + 200704, + 45056, + 40960, + 77824, + 10240, + 9216, + 77504, + 161472, + 163528, + 26304, + 26312, + 96448, + 99016, + 19648, + 19656, + 127680, + 127680, + 364224, + 323272, + 73408, + 71368, + 24776, + 138944, + 128200, + 27328, + 48832, + 37576, + 32960, + 52928, + 40128, + 89792, + 80584, + 25792, + 499392, + 504520, + 163520, + 167624, + 36032, + 36040, + 138944, + 127688, + 4208320, + 4839104, + 77504, + 81608, + 2768576, + 2757832, + 331456, + 321728, + 65224, + 65216, + 56008, + 163520, + 154816, + 48832, + 77504, + 62656, + 48832, + 77504, + 50888, + 57024, + 47296, + 52928, + 40640, + 71360, + 71360, + 22208, + 22208, + 57024, + 45768, + 48832, + 48840, + 3720896, + 4037832, + 790208, + 868040, + 230592, + 230592, + 20160, + 20160, + 29376, + 31944, + 1355456, + 1419976, + 839360, + 851656, + 32960, + 36040, + 179904, + 265920, + 85696, + 85696, + 33472, + 33472, + 392896, + 391872, + 397008, + 48832, + 48832, + 48832, + 48832, + 52928, + 48832, + 48832, + 57024, + 36032, + 36032, + 48832, + 48840, + 48840, + 48832, + 52928, + 48832, + 48832, + 57024, + 36032, + 36032, + 48848, + 48848, + 48848, + 48848, + 52944, + 48848, + 48848, + 57040, + 36048, + 36048, + 57024, + 45760, + 20160, + 20160, + 34528, + 13024, + 397312, + 5120, + 28672, + 659456, + 372736, + 110592, + 9216, + 9728, + 61440, + 28672, + 5632, + 41984, + 29736, + 20056, + 216632, + 110184, + 27032, + 37472, + 31592, + 24376, + 102728, + 280912, + 27472, + 27936, + 23392, + 56624, + 57216, + 38744, + 51016, + 36696, + 48896, + 53024, + 32032, + 34120, + 34120, + 20256, + 107848, + 109928, + 1267040, + 46984, + 496544, + 1174384, + 762288, + 101744, + 32664, + 95712, + 48480, + 365344, + 98448, + 86440, + 35312, + 37704, + 75664, + 101672, + 47912, + 15872, + 11168, + 22856, + 22856, + 506616, + 556824, + 61784, + 30008, + 44848, + 81816, + 31528, + 32768, + 12800, + 27000, + 155000, + 14712, + 14712, + 14712, + 15224, + 14712, + 15224, + 14712, + 14712, + 14712, + 15736, + 14712, + 13688, + 14200, + 122232, + 14200, + 14200, + 14200, + 14200, + 14200, + 14200, + 14712, + 13688, + 14200, + 14200, + 15224, + 14200, + 13688, + 13176, + 978296, + 1580408, + 134520, + 15224, + 15736, + 15736, + 15736, + 15736, + 15736, + 16248, + 15736, + 15736, + 15224, + 16760, + 15224, + 14712, + 15224, + 171384, + 175480, + 159096, + 171384, + 179576, + 171384, + 191864, + 175480, + 175480, + 171384, + 216440, + 167288, + 155000, + 155000, + 40312, + 27000, + 48504, + 14200, + 14200, + 14712, + 14200, + 14200, + 14200, + 14712, + 13688, + 14200, + 14200, + 14712, + 14712, + 13688, + 14200, + 52600, + 56696, + 146704, + 21792, + 286720, + 15360, + 13824, + 7168, + 7168, + 421888, + 36864, + 36864, + 110592, + 4608, + 4096, + 29576, + 29576, + 29576, + 29576, + 40840, + 30088, + 32136, + 27368, + 27528, + 315392, + 381, + 3072, + 1318, + 3072, + 375, + 3072, + 378, + 3072, + 598016, + 53248, + 32768, + 110592, + 43696, + 5283840, + 196608, + 139264, + 397312, + 249856, + 163840, + 864256, + 372736, + 532480, + 36864, + 5632, + 110592, + 5120, + 129664, + 110592, + 10752, + 3203072, + 163840, + 45056, + 57344, + 8192, + 425984, + 81920, + 28672, + 49152, + 671744, + 61440, + 53248, + 2879488, + 229376, + 15360, + 397312, + 684032, + 57344, + 110592, + 356352, + 696320, + 462848, + 53248, + 163840, + 11776, + 98304, + 470240, + 47328, + 745472, + 36864, + 974848, + 397312, + 5062656, + 544768, + 401408, + 290816, + 36864, + 188416, + 28672, + 40960, + 630784, + 81920, + 6144, + 24576, + 32768, + 446464, + 65536, + 126976, + 53248, + 131072, + 11776, + 389120, + 3010560, + 278528, + 253952, + 143360, + 13824, + 258048, + 77824, + 237568, + 16896, + 212992, + 307200, + 32768, + 970752, + 131072, + 11776, + 98304, + 270336, + 28672, + 5992448, + 73728, + 36864, + 491520, + 32768, + 569344, + 69632, + 114688, + 40960, + 692224, + 65536, + 28672, + 77824, + 3584, + 229376, + 32768, + 4096, + 16896, + 139264, + 131072, + 11264, + 15360, + 1282048, + 335872, + 49152, + 634880, + 835584, + 81920, + 98304, + 622592, + 61440, + 7168, + 839680, + 81920, + 5025792, + 434176, + 12288, + 3584, + 1142784, + 188416, + 1630208, + 311296, + 540672, + 36864, + 507904, + 102400, + 2056192, + 139264, + 167936, + 172032, + 4096, + 380928, + 8192, + 40960, + 4096, + 98304, + 7168, + 10584, + 81080, + 23376, + 1257472, + 90112, + 94208, + 5120, + 150168, + 25600, + 2553856, + 69120, + 220672, + 51712, + 1349120, + 1349120, + 167424, + 786432, + 515584, + 291328, + 1681920, + 33792, + 102400, + 102912, + 60928, + 44032, + 631296, + 44544, + 11776, + 408576, + 138752, + 1849856, + 13824, + 33280, + 44544, + 17920, + 11776, + 9153536, + 150016, + 13824, + 24576, + 293888, + 651264, + 818176, + 17920, + 141312, + 64512, + 583168, + 58368, + 830976, + 109568, + 65536, + 24576, + 771584, + 1545728, + 1540608, + 11776, + 144896, + 11776, + 18944, + 67584, + 65536, + 17920, + 848896, + 43520, + 30720, + 27648, + 1935872, + 127488, + 11264, + 44032, + 583168, + 11264, + 67584, + 632320, + 38400, + 8470528, + 127488, + 257536, + 30720, + 111104, + 286720, + 1711616, + 64000, + 240128, + 22016, + 86528, + 174080, + 16896, + 531456, + 17920, + 23552, + 20992, + 20992, + 22528, + 20992, + 19456, + 19456, + 20992, + 20992, + 11500544, + 12260864, + 368128, + 14345216, + 29184, + 29184, + 84480, + 64512, + 925696, + 8003072, + 141312, + 978432, + 2305024, + 6658048, + 1116160, + 1593344, + 1059328, + 777216, + 214016, + 627200, + 11935232, + 1840640, + 12438528, + 5466624, + 86528, + 98816, + 3358720, + 145408, + 126976, + 73728, + 78848, + 94208, + 348672, + 76288, + 2347008, + 2347008, + 2176512, + 237056, + 1130496, + 416768, + 713216, + 1126400, + 61440, + 163328, + 158208, + 61440, + 2173952, + 681472, + 33792, + 15580160, + 16565248, + 463360, + 19202560, + 47104, + 116736, + 89088, + 10677248, + 192512, + 1320448, + 3324416, + 8741888, + 1639936, + 2320384, + 1482752, + 11899392, + 1028608, + 296448, + 921600, + 15390720, + 2292224, + 17390080, + 6968320, + 125952, + 136192, + 4978176, + 193536, + 169984, + 104960, + 43520, + 300, + 112128, + 536, + 110592, + 536, + 112128, + 536, + 2664448, + 1060, + 2664448, + 1060, + 2664448, + 1060, + 71168, + 572, + 72192, + 572, + 71168, + 572, + 131072, + 2416, + 82944, + 3084, + 12800, + 3508, + 15872, + 3576, + 1321984, + 1364, + 653312, + 2124, + 18492416, + 2048, + 6656, + 344, + 1219584, + 416, + 548864, + 2444, + 6656, + 344, + 11776, + 1008, + 54272, + 404, + 63488, + 404, + 64000, + 404, + 624640, + 5752, + 624640, + 5720, + 89600, + 1736, + 164352, + 1096, + 178688, + 1096, + 16384, + 352, + 326656, + 1368, + 315392, + 1368, + 699392, + 1004, + 54784, + 360, + 75776, + 352, + 69120, + 352, + 61440, + 352, + 62976, + 352, + 61952, + 352, + 53760, + 360, + 61440, + 352, + 62464, + 352, + 33280, + 320, + 23552, + 368, + 26112, + 360, + 26624, + 324, + 26112, + 360, + 27648, + 320, + 27136, + 320, + 27136, + 320, + 28160, + 360, + 27648, + 320, + 27648, + 320, + 27648, + 320, + 33280, + 320, + 27648, + 320, + 26112, + 360, + 29696, + 320, + 31232, + 360, + 26112, + 360, + 27648, + 320, + 25088, + 328, + 27648, + 320, + 26624, + 320, + 25088, + 328, + 25088, + 328, + 25088, + 328, + 27648, + 320, + 26112, + 360, + 27136, + 320, + 27136, + 320, + 27648, + 320, + 23552, + 368, + 26624, + 320, + 25600, + 320, + 25600, + 320, + 29696, + 320, + 27648, + 320, + 26624, + 324, + 1927168, + 928, + 2015232, + 928, + 414720, + 588, + 426496, + 588, + 327680, + 708, + 1290240, + 2608, + 83456, + 308, + 86016, + 308, + 109056, + 308, + 100352, + 348, + 86016, + 308, + 109056, + 308, + 83968, + 308, + 87040, + 308, + 76800, + 312, + 87040, + 308, + 88576, + 348, + 79360, + 348, + 79872, + 308, + 75264, + 312, + 87552, + 308, + 76800, + 312, + 86528, + 308, + 88064, + 308, + 80384, + 348, + 88576, + 308, + 83456, + 308, + 79872, + 308, + 96768, + 308, + 86528, + 308, + 78848, + 348, + 82944, + 308, + 88576, + 308, + 87552, + 308, + 79360, + 348, + 69120, + 352, + 83968, + 308, + 88064, + 308, + 82944, + 308, + 70144, + 352, + 80384, + 348, + 75264, + 312, + 96768, + 308, + 10240, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 10240, + 364, + 9216, + 368, + 9216, + 368, + 163840, + 8280, + 242176, + 2980, + 210432, + 360, + 244224, + 360, + 209408, + 360, + 212480, + 360, + 192512, + 364, + 206336, + 360, + 224768, + 360, + 193536, + 364, + 206336, + 360, + 872960, + 1232, + 1231872, + 1056, + 809472, + 888, + 809472, + 992, + 3544576, + 2160, + 3544576, + 2056, + 3580928, + 2220, + 2396160, + 2568, + 145408, + 316, + 160256, + 316, + 145408, + 316, + 195584, + 364, + 140288, + 316, + 126464, + 324, + 144896, + 316, + 160256, + 316, + 139264, + 316, + 216064, + 356, + 212992, + 356, + 144896, + 316, + 139264, + 316, + 140288, + 316, + 196608, + 364, + 132608, + 316, + 128000, + 324, + 249344, + 356, + 181760, + 316, + 142848, + 316, + 228864, + 356, + 144896, + 316, + 147456, + 316, + 141824, + 316, + 144896, + 316, + 214528, + 356, + 210944, + 356, + 181760, + 316, + 140288, + 320, + 142848, + 316, + 141824, + 316, + 210432, + 356, + 128000, + 324, + 132608, + 316, + 140288, + 320, + 126464, + 324, + 147456, + 316, + 26624, + 364, + 24576, + 364, + 22016, + 368, + 29696, + 364, + 22528, + 368, + 24576, + 364, + 24576, + 364, + 24576, + 364, + 25088, + 364, + 2791936, + 2000, + 161280, + 1048, + 169472, + 1048, + 5100032, + 2612, + 5506560, + 1728, + 8192, + 380, + 101888, + 5804, + 104960, + 3332, + 99328, + 2872, + 8704, + 388, + 35328, + 368, + 11244032, + 5592, + 11244032, + 5592, + 10870784, + 5256, + 10744320, + 7916, + 540160, + 744, + 408064, + 720, + 58368, + 4604, + 58368, + 4604, + 52736, + 5008, + 1554432, + 4636, + 2222080, + 6712, + 7168, + 384, + 6656, + 400, + 6656, + 372, + 272384, + 3816, + 235008, + 2760, + 8192, + 368, + 625664, + 5764, + 563200, + 6720, + 9728, + 392, + 7168, + 404, + 415744, + 4688, + 1320960, + 6228, + 7168, + 376, + 1756160, + 4992, + 1961472, + 6552, + 244736, + 360, + 2317824, + 6480, + 1916928, + 4832, + 6656, + 400, + 8192, + 372, + 7168, + 372, + 405504, + 4152, + 411136, + 5580, + 83456, + 1784, + 84992, + 2280, + 6943744, + 6676, + 8638976, + 9976, + 16384, + 368, + 366080, + 5696, + 294912, + 6460, + 366080, + 5696, + 8192, + 380, + 384000, + 364, + 622592, + 8296, + 564224, + 7396, + 359936, + 4004, + 700416, + 6276, + 7168, + 372, + 1648640, + 6952, + 1498624, + 4620, + 38912, + 360, + 6656, + 396, + 8255488, + 5060, + 7553024, + 5084, + 8255488, + 5060, + 8048640, + 8684, + 4229120, + 7476, + 4243456, + 9716, + 57344, + 372, + 483840, + 4016, + 484352, + 4468, + 20480, + 364, + 6948352, + 8444, + 5271552, + 5800, + 9728, + 364, + 12800, + 376, + 273920, + 2708, + 114176, + 2116, + 256512, + 6212, + 186368, + 6428, + 1016320, + 3228, + 379904, + 7256, + 508928, + 6568, + 470528, + 5128, + 468480, + 3764, + 13023232, + 5424, + 12046336, + 7648, + 13023232, + 5424, + 23040, + 352, + 1604096, + 700, + 625664, + 708, + 608256, + 656, + 722944, + 3524, + 1263104, + 4232, + 243200, + 3632, + 60928, + 720, + 1249280, + 2216, + 233472, + 1212, + 110080, + 1104, + 1939456, + 2864, + 289792, + 1632, + 241664, + 2956, + 535040, + 3040, + 25088, + 688, + 38400, + 544, + 24576, + 1816, + 10240, + 600, + 10752, + 1516, + 68096, + 1056, + 75776, + 424, + 723968, + 2076, + 1162240, + 1976, + 117248, + 760, + 117248, + 3696, + 140800, + 892, + 998400, + 708, + 1829888, + 10068, + 3081216, + 10696, + 1305600, + 4820, + 172032, + 1524, + 7168, + 304, + 578048, + 2232, + 505856, + 2232, + 7168, + 288, + 149504, + 856, + 38400, + 464, + 196608, + 1268, + 198656, + 1268, + 752128, + 2188, + 799232, + 2188, + 164864, + 1912, + 197120, + 1912, + 261632, + 1552, + 259584, + 1552, + 601600, + 1372, + 583680, + 1372, + 19968, + 832, + 19968, + 832, + 375296, + 1556, + 373248, + 1556, + 44032, + 2192, + 44032, + 1696, + 148992, + 1272, + 148992, + 1272, + 71168, + 988, + 71168, + 988, + 108032, + 2516, + 96768, + 1772, + 1223680, + 3812, + 1895936, + 4020, + 560128, + 708, + 392192, + 656, + 1083904, + 2364, + 294400, + 1948, + 446464, + 1620, + 451072, + 1620, + 1251840, + 432, + 611840, + 5216, + 47104, + 620, + 53248, + 620, + 501760, + 3572, + 200192, + 3312, + 2404352, + 580, + 1298944, + 876, + 783360, + 772, + 111104, + 504, + 491008, + 748, + 580096, + 1784, + 6215680, + 696, + 1199616, + 1832, + 1252864, + 2000, + 314880, + 1076, + 346112, + 2008, + 11637248, + 2264, + 1553920, + 3336, + 311296, + 1268, + 259584, + 1652, + 1376256, + 2196, + 1782784, + 3148, + 516096, + 1248, + 1872896, + 3692, + 377856, + 316, + 96256, + 608, + 62464, + 804, + 338432, + 1500, + 296960, + 1512, + 396800, + 1652, + 329216, + 1424, + 859648, + 2168, + 2535424, + 3688, + 1282560, + 2192, + 4596736, + 5784, + 2210816, + 2420, + 139776, + 760, + 4002304, + 4776, + 4817920, + 3500, + 26624, + 352, + 488448, + 2188, + 1078272, + 5188, + 808448, + 5548, + 76288, + 1496, + 50688, + 688, + 603648, + 4856, + 600064, + 3928, + 49152, + 368, + 491008, + 3236, + 487936, + 3120, + 144896, + 2216, + 1013248, + 6708, + 805888, + 6448, + 114688, + 320, + 104448, + 328, + 103936, + 328, + 112128, + 320, + 113152, + 320, + 114688, + 320, + 110592, + 320, + 113664, + 320, + 136192, + 320, + 122880, + 320, + 110592, + 320, + 111616, + 324, + 113152, + 320, + 1485824, + 4928, + 690688, + 10996, + 737280, + 12228, + 108032, + 924, + 101888, + 740, + 6156288, + 4976, + 6376448, + 6200, + 548352, + 1492, + 441344, + 1168, + 1564672, + 8060, + 1538560, + 7084, + 169472, + 368, + 521216, + 4180, + 133632, + 2348, + 134144, + 2348, + 1046016, + 8576, + 1351680, + 4732, + 1823232, + 1872, + 829440, + 3820, + 781312, + 3720, + 5850112, + 10748, + 4831232, + 10408, + 119296, + 2012, + 118784, + 2012, + 19456, + 1652, + 9411584, + 320, + 9260032, + 320, + 367616, + 4564, + 360960, + 4372, + 69632, + 7804, + 68608, + 6724, + 1329152, + 7692, + 1319424, + 6936, + 2029568, + 3088, + 115200, + 4584, + 139776, + 5012, + 2570752, + 1576, + 43520, + 2792, + 42496, + 2792, + 842752, + 7988, + 2548224, + 11824, + 5488128, + 1760, + 260096, + 7020, + 706048, + 3612, + 740352, + 5040, + 16384, + 380, + 235520, + 2536, + 264704, + 2652, + 4364288, + 8256, + 4176896, + 6204, + 16559104, + 3220, + 107008, + 2052, + 1103872, + 3264, + 1098752, + 3056, + 1177600, + 3856, + 1028608, + 3404, + 663552, + 2212, + 665088, + 2396, + 140288, + 560, + 90112, + 2736, + 141824, + 1284, + 6045184, + 13232, + 4726784, + 12052, + 176640, + 4388, + 626688, + 3868, + 621568, + 3868, + 1908224, + 1820, + 704512, + 4976, + 700928, + 4584, + 2672128, + 7920, + 2396160, + 7872, + 4750848, + 4916, + 4597248, + 5928, + 345600, + 7092, + 318976, + 7204, + 31744, + 676, + 32256, + 676, + 593920, + 3824, + 615936, + 4292, + 1656320, + 9112, + 1626112, + 9324, + 177152, + 2020, + 5765632, + 5816, + 56320, + 2228, + 61952, + 2228, + 1814528, + 3612, + 6656, + 380, + 16896, + 456, + 31744, + 844, + 3265024, + 9080, + 4318720, + 11204, + 192512, + 784, + 188416, + 784, + 627200, + 11148, + 681472, + 11644, + 1456640, + 4156, + 306176, + 2064, + 305152, + 1908, + 2410496, + 9624, + 3928576, + 10028, + 3820544, + 9056, + 5166080, + 3392, + 417792, + 1840, + 17920, + 720, + 17920, + 720, + 732672, + 5100, + 832512, + 5676, + 1738752, + 4948, + 1936896, + 452, + 1940480, + 452, + 68608, + 3424, + 68608, + 3428, + 211456, + 4428, + 203776, + 4120, + 467456, + 3208, + 423936, + 4084, + 701952, + 5048, + 474624, + 5268, + 2202112, + 6132, + 136704, + 2432, + 136704, + 2432, + 10240, + 372, + 35840, + 824, + 35840, + 824, + 365568, + 5700, + 365568, + 6176, + 155648, + 2168, + 156160, + 2168, + 24064, + 1004, + 35840, + 1392, + 337408, + 4956, + 341504, + 4688, + 77312, + 5412, + 79360, + 6264, + 2067456, + 10360, + 435712, + 448, + 1226240, + 5600, + 1228800, + 5952, + 16384, + 324, + 16896, + 324, + 16896, + 324, + 16896, + 328, + 15872, + 332, + 16896, + 324, + 17920, + 324, + 16384, + 324, + 16896, + 324, + 16896, + 324, + 15872, + 332, + 16896, + 324, + 18432, + 324, + 99328, + 776, + 2295296, + 8784, + 1970176, + 7988, + 175104, + 7768, + 183808, + 8200, + 23552, + 1244, + 364032, + 4316, + 955904, + 6660, + 1570304, + 8804, + 1491968, + 8444, + 725504, + 528, + 729088, + 528, + 172544, + 928, + 411648, + 7312, + 294400, + 3532, + 313344, + 3416, + 48640, + 984, + 48128, + 984, + 48128, + 1760, + 160768, + 900, + 160768, + 900, + 3207680, + 2016, + 155136, + 4012, + 312320, + 4680, + 287232, + 2888, + 288768, + 2888, + 898560, + 4116, + 894464, + 4116, + 15360, + 364, + 2923520, + 6556, + 103936, + 2668, + 115200, + 4552, + 93696, + 920, + 87552, + 920, + 384512, + 1976, + 374784, + 1976, + 122368, + 2456, + 4463616, + 2788, + 1618432, + 1200, + 69632, + 1672, + 18432, + 328, + 23040, + 1268, + 13824, + 328, + 80384, + 2132, + 363008, + 5288, + 363520, + 5776, + 47616, + 2808, + 206848, + 1952, + 214016, + 2120, + 1050624, + 6560, + 1114112, + 7476, + 1883648, + 1708, + 710144, + 9276, + 937472, + 12088, + 3946496, + 10876, + 3973632, + 11776, + 6656, + 372, + 56832, + 2452, + 2269696, + 10188, + 300544, + 4128, + 299520, + 3920, + 1971712, + 7600, + 1007104, + 3108, + 9728, + 384, + 7168, + 364, + 32256, + 512, + 28672, + 512, + 640000, + 1636, + 24064, + 1976, + 272896, + 3096, + 167936, + 3860, + 1135616, + 4944, + 96768, + 1772, + 1086464, + 10516, + 1362944, + 7912, + 62976, + 656, + 63488, + 656, + 63488, + 656, + 115712, + 320, + 115200, + 320, + 895488, + 9612, + 11264, + 336, + 271360, + 2784, + 394240, + 9496, + 53760, + 784, + 360448, + 6288, + 84480, + 2488, + 588288, + 7708, + 724480, + 7052, + 2811392, + 12416, + 2999296, + 10636, + 34304, + 332, + 38400, + 336, + 38400, + 336, + 1101312, + 4140, + 1100288, + 4072, + 13824, + 332, + 13312, + 332, + 13824, + 332, + 12800, + 336, + 11776, + 372, + 13312, + 332, + 13312, + 332, + 13312, + 332, + 15360, + 332, + 13312, + 332, + 13824, + 332, + 12800, + 336, + 13312, + 332, + 13312, + 332, + 125952, + 3308, + 128000, + 3688, + 431616, + 2860, + 442880, + 3348, + 2013184, + 1400, + 660992, + 5236, + 1506816, + 5124, + 707584, + 3248, + 706560, + 3248, + 1534976, + 572, + 1537536, + 572, + 2013696, + 3344, + 2031616, + 3344, + 57856, + 2364, + 205824, + 1748, + 739328, + 1232, + 741376, + 1232, + 67584, + 1316, + 1430528, + 2832, + 429568, + 620, + 455680, + 620, + 1007616, + 5588, + 1282048, + 2624, + 1265152, + 2628, + 4728320, + 7148, + 4441600, + 6448, + 4735488, + 5152, + 3809280, + 5136, + 4013568, + 5852, + 97280, + 1332, + 978432, + 3564, + 72704, + 2504, + 28672, + 376, + 2288640, + 7400, + 2407936, + 7308, + 901632, + 8740, + 972288, + 9456, + 1052160, + 6812, + 1026560, + 6528, + 1321472, + 9780, + 837120, + 8460, + 288768, + 1108, + 308736, + 1108, + 1195520, + 1948, + 1198080, + 1948, + 181248, + 5368, + 144384, + 4900, + 776704, + 348, + 157696, + 5076, + 60928, + 444, + 60928, + 444, + 209920, + 5220, + 246784, + 756, + 246272, + 756, + 604672, + 8528, + 24064, + 564, + 24064, + 564, + 47104, + 556, + 44032, + 556, + 321536, + 2176, + 332288, + 2176, + 204288, + 2388, + 204800, + 2440, + 107008, + 912, + 82432, + 1448, + 87552, + 1996, + 89088, + 372, + 922112, + 4576, + 508928, + 1944, + 528896, + 1996, + 5450240, + 2776, + 3680768, + 15000, + 3721728, + 16696, + 845312, + 9152, + 3270656, + 4144, + 1602048, + 852, + 1606656, + 852, + 36864, + 564, + 39936, + 564, + 214016, + 3144, + 576000, + 4544, + 580096, + 4468, + 627200, + 6596, + 1623040, + 11196, + 1107456, + 9700, + 2272256, + 13208, + 2289152, + 13624, + 1189376, + 704, + 1203712, + 704, + 470528, + 6616, + 451584, + 5508, + 143360, + 1388, + 143360, + 1388, + 55296, + 2920, + 55808, + 2920, + 82944, + 2444, + 82944, + 2444, + 2862592, + 3168, + 7680, + 372, + 68096, + 1124, + 67584, + 1124, + 1022976, + 1240, + 193024, + 2660, + 193536, + 2660, + 2833408, + 1172, + 195072, + 1564, + 512000, + 2840, + 131072, + 3096, + 313344, + 2100, + 89088, + 2136, + 86016, + 2136, + 1243648, + 1840, + 1280512, + 1840, + 778752, + 1040, + 10240, + 388, + 420864, + 1660, + 3430400, + 5764, + 1161216, + 736, + 2591232, + 9460, + 1972224, + 8028, + 583168, + 6348, + 468992, + 6044, + 553472, + 4172, + 551424, + 3364, + 1433600, + 2712, + 677376, + 2552, + 1743872, + 5072, + 1784320, + 5540, + 1024512, + 2564, + 1110016, + 3572, + 5252096, + 11496, + 5855744, + 13532, + 18944, + 1000, + 12800, + 424, + 149504, + 512, + 9216, + 312, + 84480, + 1308, + 20992, + 992, + 17920, + 996, + 36352, + 1096, + 15872, + 996, + 1478144, + 1736, + 83968, + 432, + 1655296, + 2292, + 1654272, + 2200, + 604160, + 560, + 27136, + 2024, + 43520, + 656, + 21504, + 1316, + 26624, + 324, + 412160, + 2000, + 163840, + 724, + 155136, + 724, + 1257472, + 7584, + 1146368, + 3468, + 18944, + 324, + 2123264, + 5428, + 2144768, + 6080, + 57344, + 896, + 80384, + 1284, + 1655808, + 1172, + 260608, + 1280, + 908800, + 1356, + 532480, + 1196, + 46592, + 340, + 61440, + 300, + 50176, + 300, + 49664, + 300, + 50176, + 300, + 49152, + 300, + 48640, + 300, + 49664, + 300, + 49664, + 300, + 48640, + 300, + 49664, + 300, + 42496, + 340, + 46080, + 300, + 50176, + 300, + 44032, + 304, + 50176, + 300, + 43008, + 340, + 48128, + 300, + 38400, + 344, + 49664, + 300, + 43008, + 340, + 44032, + 340, + 54272, + 300, + 50176, + 300, + 44032, + 304, + 48128, + 300, + 43520, + 340, + 50176, + 300, + 49152, + 300, + 44032, + 304, + 44032, + 304, + 61440, + 300, + 52736, + 340, + 54272, + 300, + 46080, + 300, + 49664, + 300, + 36864, + 344, + 17920, + 308, + 16896, + 312, + 17920, + 308, + 17408, + 308, + 17920, + 308, + 17920, + 308, + 17920, + 308, + 17920, + 308, + 16896, + 312, + 17408, + 308, + 17920, + 308, + 18432, + 308, + 17920, + 308, + 17408, + 308, + 18432, + 308, + 17920, + 308, + 18432, + 308, + 19456, + 308, + 20480, + 308, + 18432, + 308, + 16384, + 312, + 20480, + 308, + 16384, + 312, + 17920, + 308, + 18432, + 308, + 18432, + 308, + 17408, + 308, + 19456, + 308, + 721408, + 1540, + 20518056, + 176, + 25554944, + 176, + 17408, + 1464, + 17408, + 1620, + 78848, + 296, + 118784, + 740, + 2226688, + 1360, + 2097664, + 1360, + 2452992, + 16100, + 2390528, + 15368, + 19825152, + 2436, + 536064, + 1252, + 12187136, + 1832, + 26112, + 2080, + 26112, + 2080, + 26112, + 2084, + 26112, + 2084, + 25088, + 1760, + 25600, + 2088, + 25088, + 2088, + 25088, + 1756, + 25088, + 2084, + 25088, + 2084, + 23552, + 2100, + 23552, + 2100, + 23552, + 2100, + 23552, + 2100, + 168960, + 1064, + 171520, + 1064, + 168960, + 1064, + 6656, + 372, + 7168, + 368, + 12288, + 704, + 14848, + 816, + 3638784, + 856, + 3638272, + 856, + 3700736, + 856, + 11264, + 484, + 68096, + 732, + 68096, + 732, + 68096, + 732, + 118272, + 924, + 933376, + 1352, + 933376, + 1352, + 942080, + 1352, + 683008, + 10132, + 768512, + 3312, + 768000, + 3312, + 230912, + 1488, + 200704, + 1876, + 148480, + 2048, + 391680, + 2204, + 391680, + 2204, + 395264, + 2204, + 13061632, + 620, + 10336768, + 620, + 5653504, + 2256, + 6656, + 348, + 7680, + 304, + 1251840, + 1980, + 796672, + 1984, + 812544, + 2324, + 8192, + 316, + 8704, + 304, + 181248, + 3020, + 252928, + 728, + 176128, + 2856, + 9728, + 356, + 174080, + 3208, + 10752, + 360, + 1075712, + 556, + 9216, + 360, + 150016, + 1260, + 993792, + 864, + 27648, + 300, + 9489920, + 900, + 7684608, + 900, + 7966720, + 1540, + 2586624, + 708, + 1241600, + 1180, + 1172992, + 1336, + 1838592, + 1196, + 10906624, + 2396, + 11145728, + 2580, + 31232, + 312, + 6656, + 360, + 10752, + 316, + 10240, + 316, + 8192, + 308, + 8192, + 308, + 9216, + 320, + 8704, + 312, + 460800, + 768, + 1172992, + 752, + 247808, + 1088, + 1645568, + 584, + 8704, + 308, + 391680, + 536, + 769536, + 1100, + 243200, + 8192, + 304, + 3034624, + 1732, + 8192, + 296, + 283648, + 424, + 8192, + 316, + 8704, + 316, + 6656, + 352, + 6656, + 360, + 19968, + 316, + 8192, + 304, + 9216, + 304, + 9216, + 300, + 8192, + 296, + 10752, + 308, + 26242048, + 2764, + 1180672, + 764, + 36864, + 592, + 522752, + 536, + 9728, + 304, + 128000, + 420, + 273920, + 300, + 26624, + 316, + 8704, + 312, + 1382912, + 3572, + 2391552, + 3368, + 1316864, + 3200, + 8192, + 312, + 8704, + 304, + 8192, + 316, + 636928, + 1956, + 251904, + 752, + 8192, + 312, + 35328, + 1368, + 811520, + 1276, + 306176, + 644, + 408576, + 1240, + 12288, + 316, + 102400, + 504, + 8192, + 308, + 2842112, + 1100, + 19456, + 300, + 32256, + 332, + 31744, + 316, + 9216, + 324, + 9728, + 324, + 14336, + 308, + 36352, + 560, + 9728, + 320, + 805888, + 912, + 221696, + 932, + 802304, + 592, + 19939840, + 3948, + 8192, + 304, + 8192, + 316, + 886784, + 3224, + 1123840, + 3024, + 8192, + 316, + 9216, + 308, + 8704, + 300, + 8704, + 308, + 719360, + 924, + 702464, + 972, + 13918208, + 4076, + 13918208, + 3972, + 257024, + 432, + 94720, + 600, + 1904640, + 1580, + 122880, + 1372, + 122368, + 1252, + 13563392, + 1720, + 4451328, + 2520, + 2031616, + 572, + 7577088, + 748, + 15872, + 636, + 10240, + 308, + 8704, + 308, + 9728, + 308, + 395776, + 872, + 8704, + 304, + 9728, + 300, + 240640, + 2288, + 1309184, + 3864, + 93696, + 292, + 93696, + 292, + 95232, + 292, + 635392, + 572, + 629248, + 572, + 629248, + 572, + 474624, + 3184, + 130560, + 2420, + 84480, + 3088, + 153088, + 3444, + 227840, + 3116, + 339456, + 1420, + 708096, + 5904, + 999936, + 7792, + 1446400, + 2340, + 1404928, + 2340, + 4345344, + 14076, + 4835328, + 15864, + 411136, + 1556, + 411648, + 1556, + 605696, + 1076, + 605184, + 1024, + 13824, + 808, + 183296, + 1680, + 185856, + 1680, + 347136, + 1428, + 141824, + 340, + 222720, + 344, + 721920, + 2112, + 4110336, + 1348, + 248832, + 3588, + 249344, + 3680, + 98816, + 2896, + 99328, + 3012, + 7753728, + 852, + 7665664, + 852, + 7665664, + 852, + 154112, + 892, + 155648, + 892, + 154112, + 892, + 457216, + 1660, + 133632, + 2716, + 137216, + 888, + 136704, + 888, + 136704, + 888, + 118272, + 1832, + 122368, + 736, + 135680, + 736, + 135680, + 736, + 63488, + 300, + 80384, + 572, + 81920, + 572, + 80384, + 572, + 104960, + 3084, + 166912, + 2416, + 14848, + 3508, + 18944, + 3576, + 267264, + 300, + 1542656, + 1364, + 765952, + 2124, + 23862784, + 2048, + 596480, + 2444, + 72704, + 404, + 72704, + 404, + 61440, + 404, + 129024, + 504, + 105984, + 540, + 108032, + 1736, + 28160, + 320, + 30720, + 320, + 26112, + 328, + 28160, + 324, + 28160, + 320, + 28160, + 324, + 29184, + 320, + 26112, + 328, + 28672, + 320, + 28672, + 320, + 26112, + 328, + 27136, + 320, + 28672, + 320, + 34304, + 320, + 28672, + 320, + 27648, + 320, + 27648, + 320, + 29184, + 320, + 26112, + 328, + 28672, + 320, + 27136, + 320, + 34304, + 320, + 29184, + 320, + 30720, + 320, + 28672, + 320, + 29184, + 320, + 28672, + 320, + 28672, + 320, + 2295296, + 928, + 2386432, + 928, + 561664, + 588, + 445952, + 708, + 577536, + 588, + 88064, + 308, + 88576, + 308, + 97792, + 308, + 81408, + 308, + 88064, + 308, + 77824, + 312, + 89088, + 308, + 97792, + 308, + 89088, + 308, + 83968, + 308, + 87040, + 308, + 84480, + 308, + 85504, + 308, + 81408, + 308, + 89600, + 308, + 110080, + 308, + 87552, + 308, + 110080, + 308, + 76288, + 312, + 84480, + 308, + 89600, + 308, + 83968, + 308, + 87552, + 308, + 88576, + 308, + 87040, + 308, + 76288, + 312, + 85504, + 308, + 77824, + 312, + 288768, + 2980, + 193536, + 8280, + 1096192, + 1232, + 1049088, + 992, + 1049088, + 888, + 4356608, + 2160, + 4356608, + 2056, + 2875904, + 2568, + 161792, + 316, + 127488, + 324, + 146432, + 316, + 148480, + 316, + 146432, + 316, + 144384, + 316, + 141312, + 316, + 148480, + 316, + 145920, + 316, + 129024, + 324, + 141312, + 316, + 182784, + 316, + 141824, + 320, + 142848, + 316, + 127488, + 324, + 146432, + 316, + 133632, + 316, + 161792, + 316, + 140288, + 316, + 144384, + 316, + 129024, + 324, + 133632, + 316, + 140288, + 316, + 141824, + 320, + 142848, + 316, + 145920, + 316, + 146432, + 316, + 182784, + 316, + 190464, + 1048, + 6645760, + 2612, + 7172608, + 1728, + 130048, + 5804, + 129536, + 3332, + 14091776, + 5592, + 13456896, + 7916, + 13585920, + 5256, + 671232, + 744, + 65536, + 5008, + 71168, + 4604, + 2784256, + 6712, + 339456, + 3816, + 709120, + 6720, + 1713152, + 6228, + 2441216, + 6552, + 2871296, + 6480, + 541184, + 5580, + 93696, + 2280, + 11535872, + 9976, + 473600, + 5696, + 386048, + 6460, + 800768, + 8296, + 953344, + 6276, + 2007040, + 6952, + 11059712, + 5060, + 10085888, + 5084, + 10799104, + 8684, + 5849600, + 9716, + 633344, + 4468, + 9155072, + 8444, + 327168, + 2708, + 235008, + 6428, + 1310720, + 3228, + 476160, + 7256, + 634368, + 5128, + 16174592, + 5424, + 15025152, + 7648, + 1963008, + 700, + 308224, + 3632, + 82944, + 720, + 1541632, + 2216, + 304640, + 1212, + 132608, + 1104, + 2478592, + 2864, + 383488, + 1632, + 302592, + 2956, + 29184, + 688, + 50176, + 544, + 30208, + 1816, + 12800, + 600, + 13312, + 1516, + 79872, + 1056, + 94720, + 424, + 148992, + 760, + 148992, + 3696, + 221696, + 892, + 225280, + 1524, + 8704, + 304, + 8192, + 288, + 188416, + 856, + 53760, + 464, + 1364480, + 2364, + 91648, + 500, + 1593856, + 432, + 2812416, + 580, + 135680, + 504, + 664064, + 328, + 626688, + 748, + 548864, + 1120, + 720896, + 1784, + 1544192, + 1832, + 1606144, + 2000, + 4137472, + 3300, + 7470592, + 2380, + 387584, + 1076, + 440320, + 2008, + 739840, + 1608, + 13512704, + 2264, + 1871360, + 3336, + 381440, + 1268, + 332288, + 1652, + 1762304, + 2196, + 214016, + 1252, + 2290176, + 3148, + 671232, + 1248, + 1467392, + 2232, + 80896, + 608, + 2438144, + 3692, + 489984, + 316, + 117760, + 608, + 437760, + 1500, + 377344, + 1512, + 175616, + 760, + 744448, + 3928, + 111616, + 320, + 112640, + 324, + 123904, + 320, + 113152, + 320, + 114176, + 320, + 114176, + 320, + 111616, + 320, + 116224, + 320, + 105472, + 328, + 114688, + 320, + 105472, + 328, + 137216, + 320, + 115712, + 320, + 882688, + 12228, + 155136, + 2348, + 144384, + 2012, + 23040, + 1652, + 89600, + 7804, + 161280, + 5012, + 754688, + 3868, + 34304, + 676, + 816128, + 11644, + 372736, + 1908, + 551424, + 5268, + 86016, + 6264, + 16896, + 332, + 17920, + 324, + 17920, + 324, + 18944, + 324, + 17920, + 324, + 18432, + 324, + 19968, + 324, + 17408, + 332, + 17920, + 324, + 17920, + 324, + 17920, + 324, + 17920, + 324, + 17920, + 328, + 241152, + 8200, + 919040, + 528, + 913408, + 528, + 371712, + 2888, + 1105920, + 4116, + 2182656, + 1708, + 1213440, + 12088, + 524288, + 9496, + 460800, + 6288, + 3119616, + 12416, + 47104, + 336, + 14848, + 332, + 16384, + 332, + 14848, + 332, + 13824, + 336, + 13824, + 336, + 14336, + 332, + 14336, + 332, + 14336, + 332, + 14848, + 332, + 14848, + 332, + 14848, + 332, + 14336, + 332, + 14336, + 332, + 913920, + 3248, + 2378240, + 3344, + 998912, + 1232, + 60416, + 556, + 233472, + 2388, + 4872192, + 16696, + 1746432, + 852, + 1432576, + 704, + 1444352, + 704, + 98304, + 2444, + 218112, + 2660, + 4998144, + 716, + 5272064, + 716, + 240128, + 1564, + 1604608, + 1840, + 1565696, + 1840, + 1565696, + 1840, + 1497088, + 736, + 22016, + 1000, + 14848, + 424, + 1531392, + 2684, + 188928, + 512, + 10240, + 312, + 97792, + 1308, + 24064, + 992, + 20480, + 996, + 44544, + 1096, + 18432, + 996, + 31744, + 2024, + 51712, + 656, + 25600, + 1316, + 35328, + 324, + 611328, + 1444, + 526848, + 2000, + 26112, + 324, + 7213568, + 1568, + 2115072, + 1172, + 316416, + 1280, + 646144, + 1196, + 1097216, + 1356, + 47104, + 300, + 50688, + 300, + 51200, + 300, + 51200, + 300, + 51200, + 300, + 45056, + 304, + 49664, + 300, + 47104, + 300, + 51200, + 300, + 49664, + 300, + 50688, + 300, + 62464, + 300, + 51200, + 300, + 50688, + 300, + 50688, + 300, + 49664, + 300, + 55296, + 300, + 45056, + 304, + 51200, + 300, + 45056, + 304, + 50688, + 300, + 55296, + 300, + 49664, + 300, + 51200, + 300, + 62464, + 300, + 51200, + 300, + 50688, + 300, + 45056, + 304, + 19456, + 308, + 19456, + 308, + 18944, + 308, + 19456, + 308, + 18944, + 308, + 18944, + 308, + 22016, + 308, + 22016, + 308, + 20992, + 308, + 18944, + 308, + 19456, + 308, + 18432, + 308, + 18944, + 308, + 19456, + 308, + 18944, + 308, + 19456, + 308, + 19456, + 308, + 17920, + 312, + 18944, + 308, + 18432, + 308, + 19456, + 308, + 17920, + 312, + 19456, + 308, + 17920, + 312, + 20992, + 308, + 19456, + 308, + 18944, + 308, + 17920, + 312, + 910848, + 1540, + 22551712, + 176, + 98816, + 296, + 139264, + 740, + 2679296, + 1360, + 2817024, + 1360, + 23356416, + 2436, + 650752, + 1252, + 14530048, + 1832, + 29696, + 2080, + 29184, + 2084, + 26624, + 2100, + 13312, + 484, + 73728, + 732, + 73728, + 732, + 74240, + 732, + 143872, + 924, + 303104, + 1488, + 12712448, + 620, + 7215616, + 2256, + 9216, + 304, + 1687552, + 1980, + 1063424, + 1984, + 1082880, + 2324, + 9728, + 316, + 10752, + 304, + 349696, + 728, + 1405440, + 556, + 169984, + 1260, + 1175552, + 864, + 31744, + 300, + 10212352, + 900, + 9414656, + 1540, + 3118080, + 708, + 1555456, + 1180, + 1391616, + 1336, + 2229760, + 1196, + 12569600, + 2396, + 35328, + 312, + 12288, + 316, + 12800, + 316, + 9216, + 308, + 9216, + 308, + 10240, + 320, + 10240, + 312, + 1125376, + 1128, + 547328, + 768, + 1424384, + 752, + 295424, + 1088, + 1996288, + 584, + 10752, + 308, + 486912, + 536, + 1000960, + 1100, + 334336, + 9216, + 304, + 9728, + 296, + 338944, + 424, + 9216, + 316, + 10240, + 316, + 22528, + 316, + 9216, + 304, + 10752, + 304, + 10752, + 300, + 9216, + 296, + 12800, + 308, + 2764, + 1433600, + 764, + 642048, + 536, + 314880, + 300, + 10240, + 312, + 1701888, + 3200, + 3041280, + 3368, + 1785344, + 3572, + 9216, + 312, + 10240, + 304, + 9728, + 316, + 867840, + 1948, + 300544, + 752, + 10240, + 312, + 41984, + 1368, + 932352, + 1276, + 345600, + 644, + 517120, + 1240, + 15360, + 316, + 111104, + 504, + 9216, + 308, + 3349504, + 1100, + 24576, + 300, + 36864, + 332, + 36352, + 316, + 10752, + 324, + 10752, + 324, + 16896, + 308, + 41472, + 560, + 11264, + 320, + 950272, + 912, + 260608, + 932, + 989184, + 592, + 24750080, + 3948, + 9216, + 304, + 9216, + 316, + 917504, + 3224, + 1547776, + 3024, + 9216, + 316, + 10752, + 308, + 10752, + 300, + 9728, + 308, + 872448, + 924, + 814592, + 972, + 16530944, + 4076, + 16530944, + 3972, + 290304, + 432, + 111616, + 600, + 2162688, + 1580, + 15892480, + 1720, + 5285888, + 2520, + 2543616, + 572, + 8998912, + 748, + 18944, + 636, + 10240, + 308, + 11776, + 308, + 11264, + 308, + 480256, + 872, + 10240, + 304, + 11264, + 300, + 267264, + 2288, + 108544, + 292, + 107008, + 292, + 107008, + 292, + 841728, + 572, + 847872, + 572, + 842240, + 572, + 219136, + 304, + 105984, + 3088, + 167424, + 2420, + 292352, + 3116, + 195584, + 3444, + 1740288, + 2340, + 1792000, + 2340, + 5146624, + 1348, + 176640, + 892, + 174592, + 892, + 174592, + 892, + 611840, + 1660, + 154112, + 888, + 155648, + 888, + 154112, + 888, + 197632, + 1832, + 301609, + 338048, + 64512, + 135, + 16384, + 3170304, + 1474560, + 1474560, + 16384, + 3170304, + 1024, + 1024, + 4096, + 77728, + 77728, + 4669, + 1224608, + 1209752, + 115616, + 76696, + 76704, + 45472, + 75680, + 75680, + 45472, + 79264, + 79264, + 45984, + 80288, + 80288, + 46488, + 74144, + 74144, + 74136, + 74144, + 44960, + 77728, + 77728, + 45984, + 77728, + 77728, + 75168, + 75168, + 76704, + 76704, + 45472, + 79264, + 79264, + 79256, + 79264, + 45984, + 76704, + 76696, + 78752, + 78752, + 45984, + 77216, + 77216, + 45472, + 67488, + 67488, + 42912, + 66976, + 66976, + 42912, + 75680, + 75680, + 75680, + 75672, + 1056664, + 75680, + 75680, + 45472, + 77728, + 77728, + 45472, + 77728, + 77720, + 45976, + 76704, + 76704, + 45472, + 76696, + 76704, + 45984, + 54176, + 76192, + 76192, + 77208, + 77216, + 44960, + 77216, + 77216, + 76704, + 76704, + 77216, + 77216, + 76192, + 76192, + 44960, + 75168, + 75168, + 45472, + 77208, + 77216, + 4662, + 6534, + 63904, + 63904, + 42400, + 63904, + 63904, + 42400, + 3695719, + 3878410, + 1985867, + 2373000, + 174959, + 177414, + 143754, + 145419, + 162331, + 164347, + 154427, + 156245, + 44859, + 85862, + 86178, + 49091, + 77728, + 395314, + 1, + 95648, + 99744, + 76704, + 45472, + 75672, + 45472, + 79264, + 45984, + 80288, + 46496, + 74144, + 74144, + 44960, + 77728, + 45984, + 77720, + 75160, + 76696, + 45472, + 79264, + 79264, + 45984, + 76696, + 78752, + 45976, + 77208, + 45472, + 67488, + 42904, + 66976, + 42912, + 75672, + 75680, + 812440, + 75672, + 45472, + 77728, + 45472, + 77728, + 45984, + 76704, + 45472, + 76696, + 45984, + 83352, + 54176, + 76184, + 77208, + 44960, + 77216, + 76704, + 77216, + 76192, + 44952, + 75168, + 45472, + 77216, + 4662, + 63904, + 42400, + 63904, + 42392, + 92576, + 12704, + 12192, + 67584, + 1477720, + 7680, + 7680, + 962048, + 958976, + 6480, + 34390, + 136606, + 136606, + 156118, + 556304, + 556304, + 556304, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 8774, + 8774, + 8774, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 556304, + 556304, + 556304, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 2560, + 1024, + 15360, + 10752, + 2560, + 12288, + 52736, + 6656, + 3072, + 8582, + 3, + 16777270, + 4606392, + 70144, + 808, + 1233, + 2222, + 2090, + 1120, + 1317, + 2038, + 2574, + 1544, + 1215, + 1277, + 2053, + 2088, + 1560, + 1815, + 2177, + 1483, + 846, + 1590, + 2724, + 1676, + 2430, + 1197, + 1429, + 1310, + 1873, + 1914, + 13868, + 8116, + 5632, + 11423, + 78336, + 6996, + 5120, + 1151, + 1848, + 1898, + 1137, + 1802, + 2593, + 4506, + 2839, + 410, + 1093, + 610, + 848, + 422, + 12109, + 5756, + 2092, + 5260, + 3584, + 5120, + 2620, + 80896, + 4680, + 3584, + 229, + 12800, + 592, + 1963, + 1068, + 1080, + 701, + 369, + 711, + 1485, + 540, + 613, + 3148, + 1390, + 2432, + 1488, + 1282, + 711, + 531, + 682, + 468, + 3728, + 9216, + 15256, + 152064, + 3280, + 8192, + 1219, + 2204, + 382, + 1470, + 734, + 347, + 2381, + 370, + 1069, + 832, + 1943, + 11026, + 1535, + 714, + 17920, + 11776, + 1141, + 1029, + 610, + 384, + 141662, + 8016, + 13824, + 29602, + 176128, + 7380, + 11776, + 22718, + 1636, + 2557, + 2804, + 1756, + 1223, + 7091, + 6746, + 1323, + 1139, + 5106, + 1825, + 1624, + 15593, + 2462, + 1932, + 2563, + 1575, + 3258, + 1591, + 1921, + 2920, + 2226, + 20053, + 10426, + 894, + 4608, + 7152, + 78848, + 814, + 4096, + 1050, + 2221, + 5322, + 858, + 779, + 5310, + 1861, + 4670, + 6144, + 17152, + 17920, + 4106, + 5632, + 1200, + 1200, + 1192, + 1204, + 3594, + 1206, + 1192, + 1131, + 1131, + 1123, + 1135, + 2313, + 1137, + 1123, + 8508, + 40057, + 1648, + 15872, + 20463, + 1062, + 7168, + 14398, + 2560, + 972, + 6144, + 1022, + 918, + 1398, + 1737, + 1445, + 1185, + 747, + 1218, + 1307, + 712, + 1331, + 1022, + 1277, + 43151, + 4245, + 3898, + 9216, + 25149, + 55808, + 3496, + 8192, + 2351, + 2054, + 660, + 248, + 321, + 3578, + 1242, + 1770, + 2523, + 2706, + 2691, + 2270, + 1902, + 1276, + 476, + 34272, + 408, + 4096, + 3977, + 2560, + 396, + 3584, + 2214, + 10719, + 751, + 427, + 1150, + 796, + 4968, + 37376, + 63654, + 79360, + 4368, + 28160, + 10240, + 27648, + 5063, + 2292, + 712, + 5480, + 2769, + 446, + 218, + 526, + 3584, + 2800, + 44032, + 504, + 3584, + 22016, + 137, + 252, + 181, + 17920, + 5966, + 164860, + 489984, + 14848, + 5366, + 951, + 770, + 9728, + 12213, + 23982, + 11079, + 567, + 54687, + 3011, + 7220, + 13312, + 23306, + 66560, + 6424, + 11264, + 42483, + 16946, + 453, + 49790, + 5766, + 3584, + 2653, + 85504, + 5062, + 3584, + 2755, + 311, + 879, + 1004, + 717, + 2301, + 2009, + 540, + 1537, + 836, + 1365, + 510, + 488, + 5025, + 651, + 11264, + 2194, + 1402, + 1224, + 1576, + 868, + 1592, + 384, + 1468, + 1556, + 1530, + 1736, + 16622, + 75264, + 9216, + 1732, + 1176, + 1014, + 1324, + 760, + 1240, + 358, + 1180, + 1234, + 1180, + 1198, + 27598, + 781, + 3102, + 2192, + 3130, + 2135, + 3091, + 389, + 3053, + 3160, + 3137, + 3144, + 3051, + 1626, + 1712, + 1695, + 1711, + 1564, + 1326, + 772, + 1492, + 2048, + 21039, + 6740, + 16384, + 28156, + 64512, + 6210, + 13312, + 4208, + 607, + 4161, + 2886, + 1025, + 555, + 377, + 1274, + 663, + 490, + 2004, + 1078, + 1402, + 4082, + 1459, + 2770, + 1100, + 663, + 757, + 654, + 746, + 1052, + 760, + 2089, + 636, + 1394, + 640, + 10752, + 1314, + 20594, + 5772, + 10752, + 13349, + 81408, + 5012, + 9216, + 838, + 2078, + 548, + 2218, + 913, + 945, + 962, + 1775, + 909, + 931, + 1491, + 47126, + 4108, + 6656, + 12750, + 78848, + 3694, + 6144, + 2672, + 3062, + 94720, + 949, + 62743, + 1154, + 5120, + 7501, + 2560, + 1064, + 4608, + 8826, + 25358, + 1396, + 1332, + 22025, + 370, + 7680, + 11953, + 12800, + 330, + 6656, + 1408, + 2046, + 2749, + 1158, + 1051, + 1078, + 2763, + 11286, + 1226, + 1220, + 1221, + 1604, + 6656, + 7379, + 67584, + 1464, + 5632, + 729, + 1129, + 645, + 3054, + 838, + 394, + 5120, + 4621, + 64512, + 392, + 4608, + 592, + 645, + 471, + 1248, + 7168, + 6613, + 81920, + 1188, + 6144, + 139, + 1084, + 1204, + 1082, + 645, + 1928, + 4192, + 18369, + 4979, + 7110, + 1390, + 6656, + 11429, + 78848, + 1310, + 6144, + 1120, + 805, + 5314, + 2613, + 1016, + 1097, + 591, + 3211, + 2542, + 4273, + 344, + 402, + 1584, + 408, + 1341, + 414, + 222486, + 65, + 74064, + 22528, + 22528, + 133, + 966656, + 966656, + 4176, + 44632, + 2560, + 1024, + 13824, + 9728, + 2560, + 11264, + 45568, + 6656, + 3072, + 4848952, + 4669136, + 10976, + 10976, + 11520, + 10976, + 11488, + 12288, + 13248, + 12800, + 13200, + 12720, + 9280, + 9504, + 9856, + 10064, + 9792, + 12304, + 12256, + 12336, + 12384, + 10976, + 12288, + 10224, + 10608, + 9472, + 10240, + 35808, + 36672, + 36656, + 37296, + 36672, + 37472, + 80896, + 70000, + 80896, + 70000, + 916684, + 866652, + 653588, + 649244, + 189124, + 182112, + 182096, + 189264, + 183276, + 188976, + 186728, + 182208, + 180452, + 188932, + 183412, + 184020, + 167620, + 414772, + 410464, + 415776, + 410988, + 10992, + 13552, + 17760, + 1330156, + 1297136, + 1094912, + 1133324, + 963568, + 1056136, + 1723352, + 809512, + 857200, + 822568, + 219524, + 227628, + 227684, + 229412, + 7216, + 6352, + 6672, + 6672, + 7232, + 7216, + 6336, + 5168, + 4320, + 5200, + 4640, + 5168, + 5168, + 4304, + 245572, + 229444, + 226704, + 224248, + 445180, + 383780, + 452056, + 392232, + 448368, + 451860, + 448788, + 455620, + 262288, + 276064, + 270728, + 281096, + 26432, + 26544, + 23440, + 35888, + 36032, + 31760, + 794216, + 793256, + 577340, + 23408, + 23440, + 25024, + 23440, + 25024, + 31712, + 31776, + 33344, + 31808, + 33360, + 667232, + 5600, + 12896, + 672300, + 611212, + 345208, + 611556, + 720012, + 631992, + 580168, + 576004, + 643852, + 313856, + 235848, + 241972, + 333636, + 341072, + 332036, + 338776, + 363200, + 316440, + 331128, + 338140, + 330012, + 65, + 57948, + 36336, + 36816, + 36656, + 876784, + 879640, + 9248, + 8384, + 8368, + 8704, + 9232, + 9248, + 8368, + 6192, + 5328, + 5344, + 5648, + 5280, + 6192, + 5312, + 84241, + 140748, + 154188, + 1805996, + 229912, + 228504, + 271648, + 250668, + 263504, + 269048, + 271832, + 249924, + 266156, + 272460, + 219644, + 207484, + 208428, + 138196, + 143448, + 136176, + 139324, + 143684, + 135328, + 139800, + 140268, + 141608, + 159464, + 140808, + 136228, + 211780, + 66660, + 75340, + 77384, + 76356, + 76352, + 76084, + 75832, + 76104, + 74244, + 74476, + 69916, + 68464, + 71600, + 82744, + 75980, + 70896, + 26040, + 26489, + 29779, + 43318, + 11056, + 12400, + 10032, + 573308, + 40264, + 5680, + 6512, + 214808, + 12896, + 14432, + 10656, + 304568, + 41584, + 38480, + 6528, + 7728, + 327420, + 393764, + 386264, + 117092, + 327516, + 13457192, + 12598388, + 5083240, + 27652, + 9533888, + 9749256, + 840752, + 291356, + 271860, + 8704, + 290236, + 9214528, + 21402208, + 14439388, + 12875900, + 23648676, + 16246936, + 12004804, + 301876, + 78272, + 272840, + 304076, + 309956, + 306076, + 298668, + 295152, + 1422772, + 1377980, + 1462828, + 75160, + 69316, + 206612, + 472216, + 419976, + 336672, + 413712, + 94412, + 99464, + 74520, + 76972, + 74200, + 76300, + 78136, + 76184, + 78756, + 74944, + 73820, + 76080, + 77632, + 73660, + 77284, + 73352, + 13312, + 11056, + 12384, + 17760, + 12288, + 202428, + 173700, + 173080, + 596924, + 581228, + 925736, + 914092, + 509768, + 878372, + 816540, + 523052, + 324448, + 351908, + 1690384, + 1383320, + 441372, + 941172, + 439396, + 448756, + 2454648, + 62944, + 65392, + 59024, + 89456, + 95488, + 84080, + 57936, + 59952, + 60752, + 63296, + 61024, + 81728, + 85360, + 86256, + 90736, + 84848, + 18214352, + 17064020, + 944436, + 932572, + 997912, + 987736, + 25216, + 32512, + 24672, + 20448, + 37952, + 19904, + 26112, + 24784, + 28912, + 24832, + 29200, + 21504, + 19600, + 23120, + 19760, + 23008, + 69232, + 73216, + 65456, + 72192, + 95840, + 67328, + 90336, + 102400, + 64656, + 66464, + 65328, + 68848, + 64400, + 89856, + 92032, + 90288, + 98256, + 89456, + 18087936, + 5680, + 12896, + 257052, + 71000, + 839004, + 768964, + 68260, + 60480, + 2576, + 1110940, + 1093272, + 826840, + 884748, + 254448, + 244240, + 225940, + 252300, + 243284, + 211316, + 223308, + 163324, + 166940, + 163128, + 165288, + 164360, + 157596, + 161736, + 160860, + 166668, + 155584, + 159576, + 158924, + 229848, + 5168, + 5168, + 5232, + 6160, + 5120, + 5552, + 5184, + 5184, + 5200, + 5184, + 6128, + 5184, + 7232, + 6272, + 6304, + 6272, + 5952, + 6528, + 5376, + 7168, + 5360, + 5376, + 6112, + 5600, + 6112, + 5168, + 7104, + 7648, + 6656, + 8704, + 7280, + 6608, + 7008, + 6912, + 6912, + 122784, + 84776, + 14542540, + 13827216, + 13760848, + 13697012, + 3869801, + 2964, + 1555440, + 12958, + 16, + 6686208, + 3592, + 3936, + 358328, + 3912, + 788768, + 354016, + 3944, + 25675936, + 3368788, + 1000444, + 2475780, + 2470724, + 2944004, + 93962, + 398424, + 696279, + 278216, + 278216, + 95294, + 24285, + 76827, + 75202, + 79881, + 91664, + 73901, + 63945, + 94637, + 47381, + 76837, + 75209, + 78636, + 87270, + 73848, + 63938, + 123207, + 170846, + 163655, + 167149, + 190382, + 153710, + 181388, + 192658, + 161077, + 155948, + 173135, + 167996, + 175365, + 175142, + 193292, + 176173, + 208311, + 184305, + 152003, + 166960, + 191011, + 172588, + 179346, + 181738, + 193635, + 172483, + 173778, + 196545, + 168973, + 133549, + 137150, + 133821, + 135595, + 137643, + 133803, + 135918, + 138784, + 134220, + 134548, + 133996, + 136312, + 134303, + 140091, + 139146, + 134894, + 142998, + 136681, + 134007, + 136206, + 137845, + 134156, + 135178, + 137714, + 139707, + 138470, + 136571, + 141663, + 136969, + 820959, + 837651, + 841715, + 852003, + 858806, + 815642, + 836702, + 862614, + 816732, + 829627, + 824255, + 838193, + 831598, + 855467, + 849236, + 832468, + 890837, + 856899, + 821074, + 813929, + 851738, + 822220, + 834980, + 854788, + 859328, + 857391, + 831954, + 870512, + 851084, + 60199, + 54388, + 55658, + 55914, + 55229, + 54883, + 55844, + 56461, + 55369, + 55528, + 55209, + 55065, + 55780, + 54999, + 55374, + 55329, + 58244, + 55876, + 55263, + 54598, + 55896, + 55350, + 55013, + 55676, + 55948, + 55812, + 57234, + 56767, + 55447, + 51921, + 50525, + 50600, + 51372, + 50556, + 50003, + 50750, + 51665, + 52094, + 50200, + 50176, + 50753, + 50648, + 50991, + 51055, + 50490, + 51838, + 50686, + 50748, + 49804, + 50825, + 50376, + 50348, + 50585, + 50627, + 50823, + 52845, + 50831, + 50655, + 80529, + 1180712, + 1177049, + 1166899, + 1170755, + 1174183, + 1156877, + 1163286, + 1172109, + 1175470, + 1161012, + 1156568, + 1165993, + 1158947, + 1176781, + 1181107, + 1161986, + 1193441, + 1171979, + 1157102, + 1168877, + 1180549, + 1160990, + 1163072, + 1172432, + 1180765, + 1171788, + 1165080, + 1184896, + 1166673, + 234710, + 68593, + 17013, + 29907, + 43386, + 230849, + 219577, + 60300, + 15070, + 29907, + 39939, + 1586, + 77849, + 19410, + 610, + 32573, + 1584, + 2409, + 41256, + 10954, + 610, + 19250, + 975360, + 18432, + 286208, + 9728, + 2546176, + 103936, + 2139136, + 65536, + 257024, + 7680, + 321, + 26605, + 8686, + 8762, + 30720, + 7702016, + 199168, + 210432, + 516, + 4, + 117416, + 116608, + 1462, + 20071, + 1392, + 294680, + 9766, + 162, + 22020, + 1527, + 82, + 2560, + 2560, + 147456, + 812544, + 8017408, + 7378944, + 40310, + 40310, + 33170, + 33170, + 177806, + 177806, + 2589632, + 7390720, + 46287, + 48350, + 1618106, + 912766, + 1331040, + 528404, + 1322024, + 404904, + 893472, + 377968, + 429472, + 7393280, + 188278, + 3692612, + 16629137, + 1523154, + 1562816, + 127488, + 319, + 1346, + 8685, + 5632, + 5120, + 162, + 167, + 765, + 977, + 565, + 766, + 368, + 1136, + 883, + 1064, + 417, + 354, + 354, + 354, + 529, + 612, + 791, + 2085, + 406, + 406, + 542, + 595, + 747, + 1881, + 354, + 354, + 354, + 529, + 529, + 612, + 612, + 791, + 791, + 2085, + 2085, + 642, + 1232, + 2946, + 2946, + 4048, + 4901, + 8060, + 22343, + 2851, + 2851, + 3886, + 4751, + 7782, + 21801, + 2946, + 2946, + 4048, + 4901, + 8060, + 22343, + 569, + 375, + 977, + 977, + 1252, + 1826, + 2338, + 5709, + 1010, + 1010, + 1270, + 1775, + 2227, + 5481, + 977, + 977, + 1252, + 1826, + 2338, + 5709, + 893, + 569, + 569, + 689, + 911, + 1250, + 2924, + 526, + 526, + 736, + 864, + 1199, + 2811, + 569, + 569, + 689, + 911, + 1250, + 2924, + 741, + 175, + 184, + 583, + 1185, + 508, + 496, + 434, + 857, + 654, + 835, + 353, + 547, + 1357, + 324, + 618, + 502, + 4, + 1648, + 1624, + 8000, + 861, + 1011, + 991, + 1005, + 1058, + 945, + 963, + 939, + 945, + 945, + 905, + 947, + 914, + 930, + 877, + 897, + 884, + 912, + 901, + 897, + 906, + 900, + 885, + 891, + 906, + 906, + 866, + 872, + 928, + 904, + 886, + 931, + 881, + 857, + 897, + 877, + 904, + 889, + 901, + 885, + 839, + 866, + 892, + 908, + 920, + 893, + 901, + 933, + 874, + 880, + 872, + 872, + 896, + 877, + 873, + 869, + 868, + 826, + 820, + 823, + 814, + 817, + 802, + 846, + 1009, + 1003, + 988, + 823, + 829, + 808, + 814, + 796, + 805, + 832, + 838, + 862, + 838, + 829, + 803, + 799, + 808, + 827, + 823, + 823, + 862, + 850, + 838, + 841, + 847, + 829, + 838, + 814, + 799, + 808, + 790, + 814, + 835, + 817, + 835, + 823, + 844, + 838, + 814, + 817, + 808, + 811, + 832, + 826, + 826, + 829, + 823, + 844, + 823, + 814, + 829, + 832, + 841, + 855, + 832, + 823, + 850, + 814, + 820, + 823, + 826, + 829, + 829, + 876, + 817, + 835, + 814, + 817, + 826, + 847, + 826, + 826, + 820, + 835, + 796, + 793, + 859, + 799, + 796, + 864, + 832, + 832, + 787, + 808, + 885, + 891, + 882, + 878, + 1002, + 1002, + 1017, + 1005, + 1003, + 1015, + 1037, + 1004, + 1036, + 1038, + 1011, + 1077, + 1068, + 1053, + 1005, + 1001, + 1033, + 1038, + 1050, + 1035, + 1006, + 1048, + 1057, + 1057, + 1050, + 1038, + 1017, + 1017, + 1020, + 1018, + 948, + 1035, + 1037, + 1033, + 981, + 972, + 1036, + 1042, + 1054, + 1018, + 964, + 998, + 991, + 976, + 982, + 976, + 970, + 979, + 976, + 1024, + 952, + 955, + 1018, + 973, + 958, + 1007, + 921, + 1050, + 961, + 975, + 981, + 954, + 958, + 1000, + 979, + 981, + 964, + 973, + 970, + 964, + 968, + 1010, + 1012, + 1027, + 1046, + 1012, + 1004, + 977, + 967, + 976, + 999, + 1005, + 1018, + 1012, + 982, + 974, + 972, + 1001, + 998, + 998, + 968, + 971, + 1022, + 1016, + 995, + 977, + 1002, + 1008, + 1026, + 1006, + 1011, + 1036, + 990, + 999, + 1006, + 966, + 1020, + 975, + 929, + 962, + 953, + 1016, + 1048, + 1000, + 1032, + 1000, + 1032, + 1008, + 1040, + 982, + 991, + 988, + 982, + 983, + 998, + 1016, + 979, + 976, + 987, + 1013, + 1025, + 1009, + 1003, + 974, + 951, + 978, + 969, + 954, + 975, + 975, + 969, + 969, + 956, + 972, + 974, + 1001, + 1001, + 1017, + 996, + 1000, + 1024, + 1009, + 987, + 984, + 993, + 1023, + 1053, + 986, + 1011, + 1030, + 1011, + 1030, + 991, + 991, + 975, + 1009, + 987, + 954, + 978, + 969, + 966, + 949, + 982, + 974, + 956, + 989, + 989, + 982, + 956, + 956, + 941, + 956, + 986, + 974, + 920, + 980, + 1056, + 1056, + 1052, + 1009, + 1014, + 1020, + 1008, + 999, + 998, + 1020, + 984, + 932, + 929, + 953, + 967, + 920, + 932, + 920, + 940, + 973, + 962, + 1022, + 1008, + 944, + 957, + 1045, + 953, + 952, + 943, + 952, + 973, + 952, + 962, + 938, + 981, + 984, + 984, + 998, + 975, + 818, + 470294, + 1202, + 1181, + 1045, + 1135, + 1019, + 981, + 1153, + 1019, + 962, + 851, + 961, + 1206, + 1011, + 913, + 830, + 1164, + 865, + 1232, + 898, + 991, + 970, + 1206, + 1168, + 1169, + 1214, + 982, + 937, + 924, + 973, + 937, + 956, + 946, + 1030, + 1154, + 1048, + 978, + 1011, + 1074, + 837, + 1116, + 1020, + 1000, + 969, + 1116, + 991, + 1159, + 1036, + 1014, + 912, + 1092, + 1067, + 988, + 998, + 1055, + 881, + 866, + 1019, + 1089, + 966, + 1024, + 1118, + 1114, + 923, + 925, + 959, + 961, + 1000, + 1206, + 821, + 991, + 824, + 929, + 979, + 1061, + 1156, + 1131, + 944, + 1183, + 995, + 1105, + 1022, + 983, + 1020, + 920, + 1039, + 954, + 1048, + 1042, + 1118, + 974, + 1243, + 1016, + 930, + 1030, + 1068, + 1130, + 938, + 981, + 1149, + 1074, + 959, + 956, + 919, + 941, + 950, + 1006, + 1020, + 913, + 1033, + 867, + 843, + 1149, + 957, + 1068, + 964, + 941, + 914, + 999, + 937, + 837, + 1000, + 1089, + 963, + 998, + 1022, + 1149, + 832, + 855, + 980, + 807, + 1062, + 938, + 947, + 979, + 1022, + 992, + 1030, + 998, + 1014, + 961, + 940, + 957, + 827, + 1153, + 866, + 1114, + 921, + 1012, + 944, + 1151, + 887, + 1060, + 937, + 912, + 1077, + 923, + 1037, + 1071, + 1192, + 986, + 985, + 968, + 994, + 1004, + 824, + 1176, + 990, + 1040, + 947, + 1062, + 1232, + 938, + 1148, + 1032, + 911, + 895, + 743, + 774, + 846, + 5877760, + 95104, + 504, + 1043968, + 53760, + 36, + 36, + 829, + 54230, + 45, + 45, + 811, + 52828, + 42, + 42, + 1055, + 166446, + 65, + 65, + 444, + 98700, + 53, + 53, + 444, + 98752, + 33, + 33, + 381, + 1288, + 36, + 36, + 6067, + 1517020, + 11222, + 20076, + 4034, + 10124, + 4510, + 4150, + 10500, + 3816, + 7532, + 2500, + 7060, + 3124, + 7660, + 2560, + 7612, + 23024, + 28740, + 9932, + 14572, + 6256, + 12140, + 124744, + 46912, + 64756, + 31, + 7177, + 995542, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 6537, + 819516, + 30, + 7177, + 997498, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 6537, + 819522, + 36, + 318, + 42996, + 357050, + 2242, + 6108, + 7442, + 4242, + 7500, + 3228, + 3686, + 52958, + 3754, + 7356, + 8924, + 2766, + 2846, + 2770, + 1479, + 2558, + 89110, + 6336, + 10140, + 8106, + 12492, + 17880, + 5428, + 5946, + 4008, + 1648, + 5276, + 3424, + 8372, + 6578, + 10812, + 8294, + 11572, + 3202, + 7772, + 37872, + 15974, + 16396, + 28690, + 53252, + 32834, + 20812, + 4288, + 10052, + 4746, + 7788, + 12934, + 19588, + 1154, + 1012, + 2764, + 7052, + 1008, + 690, + 3972, + 1060, + 1022, + 1128, + 692, + 3964, + 2100, + 1062, + 2306, + 6252, + 1416, + 962, + 972, + 1056, + 4500, + 1264, + 2870, + 7748, + 1992, + 1158, + 4676, + 1130, + 4612, + 1164, + 4684, + 1136, + 4636, + 1158, + 4668, + 1158, + 4700, + 1154, + 4660, + 1136, + 4644, + 1104, + 4564, + 1148, + 4652, + 1152, + 4692, + 1190, + 4764, + 1156, + 4692, + 1136, + 4628, + 1162, + 4692, + 1132, + 4620, + 1154, + 4684, + 1128, + 4668, + 1150, + 4660, + 3140, + 1202, + 2452, + 5604, + 5776, + 1546, + 1406, + 1120, + 700, + 3844, + 680, + 4012, + 1116, + 4532, + 7646, + 1316, + 1014, + 1128, + 2570, + 6876, + 1472, + 960, + 1032, + 1044, + 2572, + 1178, + 1080, + 4548, + 1180, + 1344, + 1010, + 1078, + 1114, + 1240, + 1806, + 5380, + 1680, + 5396, + 666, + 3940, + 1006, + 2326, + 6324, + 1144, + 4644, + 1356, + 1010, + 1028, + 6106, + 974, + 1126, + 1478, + 1058, + 4500, + 2694, + 6996, + 2652, + 6972, + 1162, + 3266, + 1176, + 1108, + 1842, + 1084, + 1208, + 1112, + 4580, + 1016, + 1182, + 7232, + 12444, + 31632, + 29344, + 29344, + 8156, + 7756, + 12784, + 17044, + 3426, + 7668, + 3952, + 584, + 39622, + 78064, + 2826, + 7496, + 6270, + 8332, + 110927, + 3108, + 8700, + 975476, + 500344, + 975476, + 35700, + 2230, + 6460, + 5792, + 10036, + 700038, + 5324, + 7326, + 4418, + 8124, + 2058, + 5276, + 3698, + 2314, + 6044, + 10572, + 105198, + 103572, + 68300, + 2554, + 7484, + 4156, + 10156, + 7744, + 4148, + 8660, + 5154, + 9460, + 3958, + 9700, + 70670, + 34596, + 4572, + 3716, + 9768, + 20532, + 1786, + 6036, + 26824, + 31580, + 3724, + 7516, + 4070, + 8156, + 11662, + 12916, + 11968, + 14052, + 13876, + 18172, + 15402, + 22036, + 9956, + 12724, + 10380, + 13964, + 8122, + 12612, + 12616, + 16692, + 4166, + 27662, + 73928, + 153148, + 34544, + 10586, + 34544, + 34544, + 10586, + 34544, + 34544, + 10586, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 229, + 10586, + 229, + 4134, + 7628, + 4010, + 7148, + 60840, + 7160, + 11332, + 6450, + 9740, + 84218, + 118548, + 68062, + 134140, + 26432, + 9832, + 18844, + 2864, + 6574, + 12300, + 17868, + 27084, + 22396, + 27068, + 5378, + 9844, + 145968, + 156116, + 4588, + 8668, + 4754, + 93080, + 107772, + 65972, + 13482, + 80568, + 171806, + 5730, + 27262, + 19720, + 120372, + 28978, + 8198, + 15558, + 49800, + 14466, + 105144, + 20416, + 25830, + 88896, + 24836, + 55742, + 63380, + 8450, + 29398, + 25790, + 12086, + 137326, + 26092, + 56996, + 7526, + 12050, + 243776, + 56662, + 11166, + 23974, + 118782, + 111928, + 107186, + 45598, + 26536, + 19476, + 18622, + 266006, + 86868, + 35708, + 152552, + 19952, + 31048, + 82068, + 22124, + 89728, + 47188, + 98330, + 89444, + 98810, + 104296, + 1574382, + 94068, + 152526, + 205386, + 80412, + 216596, + 126054, + 38968, + 5028, + 66028, + 100404, + 144846, + 40530, + 35686, + 137064, + 88352, + 28582, + 8938, + 11452, + 20706, + 46182, + 44850, + 19038, + 10228, + 88788, + 72772, + 16954, + 143864, + 97254, + 254856, + 10430, + 16894, + 832958, + 24040, + 5732, + 106688, + 23304, + 9538, + 9602, + 8244, + 8322, + 76410, + 23248, + 12244, + 24678, + 24328, + 8714, + 16054, + 17254, + 8372, + 29516, + 142858, + 9088, + 61202, + 38408, + 111000, + 21148, + 6480, + 75332, + 15414, + 103226, + 24976, + 81708, + 85148, + 158182, + 53316, + 27596, + 13248, + 98472, + 10102, + 43146, + 58978, + 230698, + 55956, + 91872, + 32492, + 36630, + 26488, + 36130, + 19834, + 25730, + 18860, + 71780, + 44666, + 27150, + 6068, + 23790, + 61154, + 99100, + 6860, + 4858, + 31168, + 242920, + 75430, + 216056, + 103516, + 157736, + 207412, + 13974, + 15700, + 8942, + 11804, + 318550, + 364956, + 3200, + 8972, + 2388, + 4126, + 5912, + 12516, + 86462, + 76452, + 9070, + 790436, + 1176964, + 61436, + 2190, + 3682, + 3864, + 4182, + 3864, + 768, + 49, + 49, + 49, + 705, + 131728, + 47, + 47, + 705, + 135800, + 43838, + 5884, + 11804, + 60908, + 69412, + 58210, + 98652, + 31186, + 37644, + 3452, + 7972, + 26808, + 38398, + 3852, + 7828, + 1044, + 7892, + 13524, + 33988, + 3386, + 2208, + 25160, + 2982, + 2712, + 6404, + 176484, + 125868, + 51026, + 62572, + 29228, + 40564, + 12568, + 22628, + 19112, + 68176, + 60244, + 30092, + 40810, + 248286, + 551212, + 5276, + 6980, + 30894, + 31930, + 434302, + 98426, + 71644, + 2656, + 10542, + 13516, + 723666, + 83830, + 99418, + 97762, + 329418, + 273392, + 261692, + 37444, + 3174, + 4370, + 13582, + 45834, + 101928, + 19080, + 430184, + 82502, + 13446, + 2140, + 6166, + 87594, + 93928, + 2460, + 214348, + 2154, + 83726, + 35016, + 4186, + 4794, + 8618, + 307862, + 285242, + 64914, + 24424, + 23620, + 5292, + 8186, + 11886, + 33690, + 268356, + 110094, + 40642, + 230496, + 2380, + 5136, + 6788, + 95530, + 8470, + 13622, + 15068, + 33734, + 6066, + 116538, + 34764, + 6694, + 7100, + 3798, + 8272, + 3442, + 398670, + 136934, + 319876, + 28282, + 991868, + 15784, + 1014176, + 243844, + 526428, + 45578, + 3010, + 7756, + 15134, + 2678, + 18102, + 8926, + 10148, + 2818, + 8236, + 20190, + 20596, + 6955, + 1046848, + 369, + 1046848, + 369, + 12338, + 3113, + 91662, + 471312, + 76048, + 15032, + 3130, + 128374, + 530416, + 75288, + 16920, + 3096, + 139821, + 486344, + 75288, + 125728, + 89872, + 89144, + 90608, + 404752, + 1028, + 19667, + 28511, + 65288, + 11194, + 155192, + 315888, + 36472, + 316736, + 13916, + 3066, + 126310, + 401376, + 76048, + 12420, + 3066, + 115628, + 400656, + 75288, + 125728, + 89144, + 89872, + 404072, + 212, + 121440, + 2810, + 60778, + 155128, + 36472, + 54392, + 35424, + 9033, + 6668, + 117460, + 187392, + 36472, + 61632, + 404072, + 121440, + 10476, + 3114, + 87177, + 495376, + 73480, + 13106, + 3130, + 122503, + 501216, + 73512, + 19440, + 2716, + 191560, + 302464, + 11126, + 3093, + 89526, + 497424, + 73480, + 13024, + 3097, + 154115, + 498672, + 76784, + 16988, + 3097, + 190046, + 499184, + 76784, + 9802, + 3097, + 42986, + 499184, + 76784, + 11446, + 3315, + 140902, + 302296, + 36472, + 125728, + 90608, + 91936, + 101216, + 89888, + 90608, + 89888, + 89144, + 98496, + 60608, + 404752, + 1081, + 9697, + 2777, + 20667, + 138512, + 64168, + 14848, + 3049, + 132659, + 411120, + 89072, + 36472, + 92144, + 405488, + 256, + 19667, + 28511, + 65288, + 9311, + 166032, + 36472, + 316736, + 12590, + 3050, + 87645, + 271024, + 68264, + 14850, + 3050, + 153989, + 370968, + 73512, + 11362, + 3050, + 117277, + 370968, + 73512, + 36472, + 125728, + 92864, + 91936, + 92448, + 89872, + 79720, + 404072, + 256, + 9732, + 3046, + 84534, + 357856, + 76232, + 9782, + 3075, + 20816, + 131584, + 73480, + 5174, + 2939, + 12442, + 3114, + 92354, + 468752, + 73480, + 15038, + 3130, + 128291, + 529392, + 73512, + 17742, + 3097, + 176198, + 523248, + 76784, + 11729, + 3097, + 44389, + 522736, + 76784, + 36472, + 125728, + 90608, + 91936, + 89888, + 90608, + 80672, + 404752, + 1083, + 11897, + 2743, + 22579, + 131344, + 73480, + 16770, + 3049, + 144852, + 442864, + 89072, + 36472, + 92144, + 80880, + 405488, + 260, + 12717, + 3043, + 56912, + 318944, + 89072, + 19667, + 28511, + 2236928, + 2239488, + 48464, + 65288, + 11361, + 156656, + 10997, + 10224, + 8796, + 12249, + 8148, + 9369, + 8944, + 10400, + 494960, + 503664, + 473968, + 10758, + 12146, + 483184, + 163696, + 10046, + 10040, + 165232, + 8657, + 9915, + 71952, + 279024, + 60752, + 316400, + 36472, + 316736, + 1721576, + 16797, + 3050, + 162256, + 352024, + 73512, + 13277, + 3050, + 126428, + 352024, + 73512, + 36472, + 125728, + 91936, + 92448, + 89872, + 80672, + 404072, + 268, + 11656, + 3046, + 91773, + 388040, + 76232, + 11904, + 3075, + 22837, + 133392, + 73480, + 121440, + 12423, + 3114, + 92426, + 468752, + 73480, + 15026, + 3130, + 128070, + 529392, + 73512, + 19440, + 2716, + 191560, + 302464, + 13073, + 3093, + 94851, + 469264, + 73480, + 14946, + 3097, + 163489, + 470512, + 76784, + 18910, + 3097, + 199105, + 523248, + 76784, + 11725, + 3097, + 45051, + 522736, + 76784, + 11446, + 3315, + 140902, + 302296, + 36472, + 125728, + 90608, + 91936, + 101216, + 89888, + 90608] diff --git a/tests/fragmentation/tfragment_alloc.nim b/tests/fragmentation/tfragment_alloc.nim new file mode 100644 index 000000000..031588d27 --- /dev/null +++ b/tests/fragmentation/tfragment_alloc.nim @@ -0,0 +1,27 @@ + +discard """ + output: '''occupied ok: true +total ok: true''' +""" + +import strutils, data + +proc main = + var m = 0 + for i in 0..1000_000: + let size = sizes[i mod sizes.len] + let p = alloc(size) + if p == nil: + quit "could not serve request!" + dealloc p + # c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size) + +main() + +let occ = getOccupiedMem() +let total = getTotalMem() + +# Current values on Win64: 824KiB / 106.191MiB + +echo "occupied ok: ", occ < 2 * 1024 * 1024 +echo "total ok: ", total < 120 * 1024 * 1024 diff --git a/tests/fragmentation/tfragment_gc.nim b/tests/fragmentation/tfragment_gc.nim new file mode 100644 index 000000000..1781f6610 --- /dev/null +++ b/tests/fragmentation/tfragment_gc.nim @@ -0,0 +1,30 @@ +discard """ + output: '''occupied ok: true +total ok: true''' +""" + +import strutils, data + +proc main = + var m = 0 + # Since the GC test is slower than the alloc test, we only iterate 100_000 times here: + for i in 0..100_000: + let size = sizes[i mod sizes.len] + let p = newString(size) + # c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size) + +main() + +let occ = getOccupiedMem() +let total = getTotalMem() + +# Concrete values on Win64: 58.152MiB / 188.285MiB + +let occupiedOk = occ < 64 * 1024 * 1024 +if not occupiedOk: + echo "occupied ", formatSize(occ) +echo "occupied ok: ", occupiedOk +let totalOk = total < 210 * 1024 * 1024 +if not totalOk: + echo "total peak memory ", formatSize(total) +echo "total ok: ", totalOk diff --git a/tests/generics/toverloading_typedesc.nim b/tests/generics/toverloading_typedesc.nim index 5882640f2..94f4d860d 100644 --- a/tests/generics/toverloading_typedesc.nim +++ b/tests/generics/toverloading_typedesc.nim @@ -1,5 +1,6 @@ discard """ exitcode: 0 + disabled: '''true''' """ import moverloading_typedesc import tables diff --git a/tests/generics/treentranttypes.nim b/tests/generics/treentranttypes.nim index 9b4774e9b..2ef049ce2 100644 --- a/tests/generics/treentranttypes.nim +++ b/tests/generics/treentranttypes.nim @@ -1,6 +1,6 @@ discard """ output: ''' -(Field0: 10, Field1: (Field0: test, Field1: 1.2)) +(Field0: 10, Field1: (Field0: "test", Field1: 1.2)) 3x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0], [2.0, 0.0, 5.0]] 2x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0]] @@ -43,7 +43,7 @@ type Matrix*[M: static[int]; N: static[int]; T] = Vector[M, Vector[N, T]] - + proc arrayTest = # every kind of square matrix works just fine let mat_good: Matrix[3, 3, float] = [[0.0, 2.0, 3.0], diff --git a/tests/js/tarrayboundscheck.nim b/tests/js/tarrayboundscheck.nim new file mode 100644 index 000000000..f0eaeb89d --- /dev/null +++ b/tests/js/tarrayboundscheck.nim @@ -0,0 +1,44 @@ +discard """ + output: '''idx out of bounds: -1 +month out of bounds: 0 +Jan +Feb +Mar +Apr +May +Jun +Jul +Aug +Sep +Oct +Nov +Dec +month out of bounds: 13 +idx out of bounds: 14 +''' +""" + +{.push boundChecks:on.} + +# see issue #6532: +# js backend 0.17.3: array bounds check for non zero based arrays is buggy + +proc test_arrayboundscheck() = + var months: array[1..12, string] = + ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + + var indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13] + + for i in -1 .. 14: + try: + let idx = indices[i] + try: + echo months[idx] + except: + echo "month out of bounds: ", idx + except: + echo "idx out of bounds: ", i + +test_arrayboundscheck() +{.pop.} \ No newline at end of file diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim new file mode 100644 index 000000000..34ef97b8b --- /dev/null +++ b/tests/js/tasync.nim @@ -0,0 +1,32 @@ +discard """ + disabled: true + output: ''' +x +e +''' +""" + +import asyncjs + +# demonstrate forward definition +# for js +proc y(e: int): Future[string] {.async.} + +proc e: int {.discardable.} = + echo "e" + return 2 + +proc x(e: int): Future[void] {.async.} = + var s = await y(e) + echo s + e() + +proc y(e: int): Future[string] {.async.} = + if e > 0: + return await y(0) + else: + return "x" + + +discard x(2) + diff --git a/tests/js/tcodegendeclproc.nim b/tests/js/tcodegendeclproc.nim new file mode 100644 index 000000000..3acf0bc13 --- /dev/null +++ b/tests/js/tcodegendeclproc.nim @@ -0,0 +1,11 @@ +discard """ + output: ''' +-1 +8 +''' + ccodecheck: "'console.log(-1); function fac_' \\d+ '(n_' \\d+ ')'" +""" +proc fac(n: int): int {.codegenDecl: "console.log(-1); function $2($3)".} = + return n + +echo fac(8) diff --git a/tests/js/tcodegendeclvar.nim b/tests/js/tcodegendeclvar.nim new file mode 100644 index 000000000..645443ef7 --- /dev/null +++ b/tests/js/tcodegendeclvar.nim @@ -0,0 +1,10 @@ +discard """ + output: ''' +-1 +2 +''' + ccodecheck: "'console.log(-1); var v_' \\d+ ' = [2]'" +""" + +var v {.codegenDecl: "console.log(-1); var $2".} = 2 +echo v diff --git a/tests/js/test2.nim b/tests/js/test2.nim index 0f460d6f8..0bfb99139 100644 --- a/tests/js/test2.nim +++ b/tests/js/test2.nim @@ -2,7 +2,9 @@ discard """ output: '''foo js 3.14 7 -1''' +1 +-21550 +-21550''' """ # This file tests the JavaScript generator @@ -40,3 +42,14 @@ 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) + +# bug #6753 +let x = -1861876800 +const y = 86400 +echo (x - (y - 1)) div y # Now gives `-21550` + +proc foo09() = + let x = -1861876800 + const y = 86400 + echo (x - (y - 1)) div y # Still gives `-21551` +foo09() diff --git a/tests/js/trefbyvar.nim b/tests/js/trefbyvar.nim index d440fcc64..5b168044e 100644 --- a/tests/js/trefbyvar.nim +++ b/tests/js/trefbyvar.nim @@ -66,4 +66,4 @@ proc initTypeA1(a: int; b: string; c: pointer = nil): TypeA1 = result.c_impl = c let x = initTypeA1(1, "a") -doAssert($x == "(a_impl: 1, b_impl: a, c_impl: ...)") +doAssert($x == "(a_impl: 1, b_impl: \"a\", c_impl: ...)") diff --git a/tests/js/ttimes.nim b/tests/js/ttimes.nim index 2868c6d0f..63a4bb04f 100644 --- a/tests/js/ttimes.nim +++ b/tests/js/ttimes.nim @@ -1,4 +1,3 @@ -# test times module with js discard """ action: run """ @@ -9,21 +8,37 @@ import times # Tue 19 Jan 03:14:07 GMT 2038 block yeardayTest: - # check if yearday attribute is properly set on TimeInfo creation - doAssert fromSeconds(2147483647).getGMTime().yearday == 18 - -block localTimezoneTest: - # check if timezone is properly set during Time to TimeInfo conversion - doAssert fromSeconds(2147483647).getLocalTime().timezone == getTimezone() - -block timestampPersistenceTest: - # check if timestamp persists during TimeInfo to Time conversion - const - timeString = "2017-03-21T12:34:56+03:00" - timeStringGmt = "2017-03-21T09:34:56+00:00" - timeStringGmt2 = "2017-03-21T08:34:56+00:00" - fmt = "yyyy-MM-dd'T'HH:mm:sszzz" - # XXX Check which one is the right solution here: - - let x = $timeString.parse(fmt).toTime().getGMTime() - doAssert x == timeStringGmt or x == timeStringGmt2 + doAssert fromUnix(2147483647).utc.yearday == 18 + +block localTime: + var local = now() + let utc = local.utc + doAssert local.toTime == utc.toTime + +let a = fromUnix(1_000_000_000) +let b = fromUnix(1_500_000_000) +doAssert b - a == 500_000_000 + +# Because we can't change the timezone JS uses, we define a simple static timezone for testing. + +proc staticZoneInfoFromUtc(time: Time): ZonedTime = + result.utcOffset = -7200 + result.isDst = false + result.adjTime = (time.toUnix + 7200).Time + +proc staticZoneInfoFromTz(adjTime: Time): ZonedTIme = + result.utcOffset = -7200 + result.isDst = false + result.adjTime = adjTime + +let utcPlus2 = Timezone(zoneInfoFromUtc: staticZoneInfoFromUtc, zoneInfoFromTz: staticZoneInfoFromTz, name: "") + +block timezoneTests: + let dt = initDateTime(01, mJan, 2017, 12, 00, 00, utcPlus2) + doAssert $dt == "2017-01-01T12:00:00+02:00" + doAssert $dt.utc == "2017-01-01T10:00:00+00:00" + doAssert $dt.utc.inZone(utcPlus2) == $dt + +doAssert $initDateTime(01, mJan, 1911, 12, 00, 00, utc()) == "1911-01-01T12:00:00+00:00" +# See #6752 +# doAssert $initDateTime(01, mJan, 1900, 12, 00, 00, utc()) == "0023-01-01T12:00:00+00:00" \ No newline at end of file diff --git a/tests/lexer/tind1.nim b/tests/lexer/tind1.nim index 8a2aea9b2..ffbde48fd 100644 --- a/tests/lexer/tind1.nim +++ b/tests/lexer/tind1.nim @@ -1,6 +1,6 @@ discard """ line: 24 - errormsg: "expression expected, but found 'keyword else'" + errormsg: "invalid indentation" """ import macros @@ -11,7 +11,7 @@ var x = if 4 != 5: else: "no" -macro mymacro(n): untyped {.immediate.} = +macro mymacro(n, b): untyped = discard mymacro: diff --git a/tests/macros/tgettypeinst.nim b/tests/macros/tgettypeinst.nim index 8e1d9bc13..2f1abe193 100644 --- a/tests/macros/tgettypeinst.nim +++ b/tests/macros/tgettypeinst.nim @@ -27,9 +27,10 @@ macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed = let inst = x.getTypeInst let instr = inst.symToIdent.treeRepr let inst0r = inst0.symToIdent.treeRepr - #echo instr - #echo inst0r - doAssert(instr == inst0r) + if instr != inst0r: + echo "instr:\n", instr + echo "inst0r:\n", inst0r + doAssert(instr == inst0r) # check that getTypeImpl(x) is correct # if implX is nil then compare to inst0 @@ -41,9 +42,10 @@ macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed = else: implX[0][2] let implr = impl.symToIdent.treerepr let impl0r = impl0.symToIdent.treerepr - #echo implr - #echo impl0r - doAssert(implr == impl0r) + if implr != impl0r: + echo "implr:\n", implr + echo "impl0r:\n", impl0r + doAssert(implr == impl0r) result = newStmtList() #template echoString(s: string) = echo s.replace("\n","\n ") @@ -111,6 +113,18 @@ type Generic[T] = seq[int] Concrete = Generic[int] + Generic2[T1, T2] = seq[T1] + Concrete2 = Generic2[int, float] + + Alias1 = float + Alias2 = Concrete + Alias3 = Concrete2 + + Vec[N: static[int],T] = object + arr: array[N,T] + Vec4[T] = Vec[4,T] + + test(bool) test(char) test(int) @@ -144,11 +158,27 @@ test(Tree): left: ref Tree right: ref Tree test(Concrete): - type _ = Generic[int] + type _ = seq[int] test(Generic[int]): type _ = seq[int] test(Generic[float]): type _ = seq[int] +test(Concrete2): + type _ = seq[int] +test(Generic2[int,float]): + type _ = seq[int] +test(Alias1): + type _ = float +test(Alias2): + type _ = seq[int] +test(Alias3): + type _ = seq[int] +test(Vec[4,float32]): + type _ = object + arr: array[0..3,float32] +test(Vec4[float32]): + type _ = object + arr: array[0..3,float32] # bug #4862 static: diff --git a/tests/macros/tnimnode_for_runtime.nim b/tests/macros/tnimnode_for_runtime.nim deleted file mode 100644 index 0520cd0dd..000000000 --- a/tests/macros/tnimnode_for_runtime.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: "bla" -""" - -import macros -proc makeMacro: NimNode = - result = nil - -var p = makeMacro() - -echo "bla" - diff --git a/tests/metatype/ttypedesc2.nim b/tests/metatype/ttypedesc2.nim index 7650a6f6b..4b6cfe6bc 100644 --- a/tests/metatype/ttypedesc2.nim +++ b/tests/metatype/ttypedesc2.nim @@ -1,5 +1,5 @@ discard """ - output: "(x: a)" + output: '''(x: 'a')''' """ type diff --git a/tests/misc/tatomic.nim b/tests/misc/tatomic.nim deleted file mode 100644 index f3c56ffe3..000000000 --- a/tests/misc/tatomic.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tatomic.nim" - line: 7 - errormsg: "identifier expected, but found 'keyword atomic'" -""" -var - atomic: int - -echo atomic - - - diff --git a/tests/misc/tevents.nim b/tests/misc/tevents.nim index 5f2169f29..caf674084 100644 --- a/tests/misc/tevents.nim +++ b/tests/misc/tevents.nim @@ -8,19 +8,19 @@ HandlePrintEvent2: Output -> printing for ME''' import events type - TPrintEventArgs = object of TEventArgs + PrintEventArgs = object of EventArgs user*: string -proc handleprintevent*(e: TEventArgs) = +proc handleprintevent*(e: EventArgs) = write(stdout, "HandlePrintEvent: Output -> Handled print event\n") -proc handleprintevent2*(e: TEventArgs) = - var args: TPrintEventArgs = TPrintEventArgs(e) +proc handleprintevent2*(e: EventArgs) = + var args: PrintEventArgs = PrintEventArgs(e) write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user) var ee = initEventEmitter() -var eventargs: TPrintEventArgs +var eventargs: PrintEventArgs eventargs.user = "ME\n" ##method one test @@ -33,16 +33,16 @@ ee.emit("print", eventargs) ##method two test type - TSomeObject = object of TObject - PrintEvent: TEventHandler + SomeObject = object of RootObj + printEvent: EventHandler -var obj: TSomeObject -obj.PrintEvent = initEventHandler("print") -obj.PrintEvent.addHandler(handleprintevent2) +var obj: SomeObject +obj.printEvent = initEventHandler("print") +obj.printEvent.addHandler(handleprintevent2) -ee.emit(obj.PrintEvent, eventargs) +ee.emit(obj.printEvent, eventargs) -obj.PrintEvent.removeHandler(handleprintevent2) +obj.printEvent.removeHandler(handleprintevent2) -ee.emit(obj.PrintEvent, eventargs) +ee.emit(obj.printEvent, eventargs) diff --git a/tests/misc/tlocals.nim b/tests/misc/tlocals.nim index 3e240d3c8..09b7432f5 100644 --- a/tests/misc/tlocals.nim +++ b/tests/misc/tlocals.nim @@ -1,5 +1,5 @@ discard """ - output: "(x: string here, a: 1)" + output: '''(x: "string here", a: 1)''' """ proc simple[T](a: T) = diff --git a/tests/misc/tromans.nim b/tests/misc/tromans.nim deleted file mode 100644 index 132c73ddd..000000000 --- a/tests/misc/tromans.nim +++ /dev/null @@ -1,71 +0,0 @@ -discard """ - file: "tromans.nim" - output: "success" -""" -import - strutils - -## Convert an integer to a Roman numeral -# See http://en.wikipedia.org/wiki/Roman_numerals for reference - -proc raiseInvalidValue(msg: string) {.noreturn.} = - # Yes, we really need a shorthand for this code... - var e: ref EInvalidValue - new(e) - e.msg = msg - raise e - -# I should use a class, perhaps. -# --> No. Why introduce additional state into such a simple and nice -# interface? State is evil. :D - -proc RomanToDecimal(romanVal: string): int = - result = 0 - var prevVal = 0 - for i in countdown(romanVal.len - 1, 0): - var val = 0 - case romanVal[i] - of 'I', 'i': val = 1 - of 'V', 'v': val = 5 - of 'X', 'x': val = 10 - of 'L', 'l': val = 50 - of 'C', 'c': val = 100 - of 'D', 'd': val = 500 - of 'M', 'm': val = 1000 - else: raiseInvalidValue("Incorrect character in roman numeral! (" & - $romanVal[i] & ")") - if val >= prevVal: - inc(result, val) - else: - dec(result, val) - prevVal = val - -proc DecimalToRoman(decValParam: int): string = - # Apparently numbers cannot be above 4000 - # Well, they can be (using overbar or parenthesis notation) - # but I see little interest (beside coding challenge) in coding them as - # we rarely use huge Roman numeral. - const romanComposites = [ - ("M", 1000), ("CM", 900), - ("D", 500), ("CD", 400), ("C", 100), - ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), - ("V", 5), ("IV", 4), ("I", 1)] - if decValParam < 1 or decValParam > 3999: - raiseInvalidValue("number not representable") - result = "" - var decVal = decValParam - for key, val in items(romanComposites): - while decVal >= val: - dec(decVal, val) - result.add(key) - -for i in 1..100: - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -for i in items([1238, 1777, 3830, 2401, 379, 33, 940, 3973]): - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -echo "success" #OUT success - - - diff --git a/tests/misc/tupcomingfeatures.nim b/tests/misc/tupcomingfeatures.nim index cf07b06df..d37ce85cf 100644 --- a/tests/misc/tupcomingfeatures.nim +++ b/tests/misc/tupcomingfeatures.nim @@ -6,12 +6,8 @@ discard """ {.this: self.} type - Foo {.partial.} = object - a, b: int - -type - tupcomingfeatures.Foo = object - x: int + Foo = object + a, b, x: int proc yay(self: Foo) = echo a, " ", b, " ", x diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index a5c30c7eb..5daa2c4b8 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -67,7 +67,7 @@ proc toNum64(b: TBuffer): int64 = proc toNum(b: TBuffer): int32 = # treat first byte different: - result = ze(b[0]) and 63 + result = int32 ze(b[0]) and 63 var i = 0 Shift = 6'i32 diff --git a/tests/modules/mrange.nim b/tests/modules/mrange.nim new file mode 100644 index 000000000..20c424a8c --- /dev/null +++ b/tests/modules/mrange.nim @@ -0,0 +1,5 @@ + +proc range*() = echo "yo" + +proc set*(a: int) = + discard diff --git a/tests/modules/tambig_range.nim b/tests/modules/tambig_range.nim new file mode 100644 index 000000000..010350521 --- /dev/null +++ b/tests/modules/tambig_range.nim @@ -0,0 +1,13 @@ +discard """ + errormsg: "ambiguous identifier: 'range' --use system.range or mrange.range" + line: 13 +""" + +import mrange + +# bug #6965 +type SomeObj = object + s: set[int8] + +# bug #6726 +range() diff --git a/tests/modules/treorder.nim b/tests/modules/treorder.nim index 25280c429..8715e4548 100644 --- a/tests/modules/treorder.nim +++ b/tests/modules/treorder.nim @@ -9,7 +9,6 @@ defined {.reorder: on.} {.experimental.} -{.push callconv: stdcall.} proc bar(x: T) proc foo() = @@ -22,15 +21,16 @@ proc bar(x: T) = echo "works ", x foo(x) +when defined(testdef): + proc whendep() = echo "defined" +else: + proc whendep() = echo "undefined" + foo() type T = int -when defined(testdef): - proc whendep() = echo "defined" -else: - proc whendep() = echo "undefined" when not declared(goo): proc goo(my, omy) = echo my @@ -42,5 +42,3 @@ using my, omy: int goo(3, 4) - -{.pop.} diff --git a/tests/notnil/tmust_compile.nim b/tests/notnil/tmust_compile.nim new file mode 100644 index 000000000..10da154f0 --- /dev/null +++ b/tests/notnil/tmust_compile.nim @@ -0,0 +1,78 @@ +discard """ + output: '''success''' +""" + +# bug #6682 + +type + Fields = enum + A=1, B, C + + Obj = object + fld: array[Fields, int] + + AsGeneric[T] = array[Fields, T] + Obj2[T] = object + fld: AsGeneric[T] + +var a: Obj # this works + +var arr: array[Fields, int] + +var b = Obj() # this doesn't (also doesn't works with additional fields) + +var z = Obj2[int]() + +echo "success" + +# bug #6555 + +import tables + +type + TaskOrNil = ref object + Task = TaskOrNil not nil + +let table = newTable[string, Task]() +table.del("task") + +# bug #6121 + +import json + +type + + foo = object + thing: string not nil + + CTS = ref object + subs_by_sid: Table[int, foo] + + +proc parse(cts: CTS, jn: JsonNode) = + + let ces = foo( + thing: jn.getStr("thing") + ) + + cts.subs_by_sid[0] = ces + + +# bug #6489 + +proc p(x: proc(){.closure.} not nil) = discard +p(proc(){.closure.} = discard) + +# bug #3993 + +type + List[T] = seq[T] not nil + +proc `^^`[T](v: T, lst: List[T]): List[T] = + result = @[v] + result.add(lst) + +proc Nil[T](): List[T] = @[] + +when isMainModule: + let lst = 1 ^^ 2 ^^ Nil[int]() diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index 12478f621..b7da176aa 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -1,14 +1,14 @@ discard """ - output: '''(k: kindA, a: (x: abc, z: [1, 1, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 2, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 3, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 4, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 5, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 6, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 7, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 8, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 9, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 10, 3]), method: ()) + output: '''(k: kindA, a: (x: "abc", z: [1, 1, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 2, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 3, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 4, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 5, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 6, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 7, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 8, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 9, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 10, 3]), method: ()) (x: 123) (x: 123) (z: 89, y: 0, x: 128) diff --git a/tests/osproc/texecps.nim b/tests/osproc/texecps.nim new file mode 100644 index 000000000..887d79bfb --- /dev/null +++ b/tests/osproc/texecps.nim @@ -0,0 +1,32 @@ +discard """ + file: "texecps.nim" + output: "" +""" + +import osproc, streams, strutils, os + +const NumberOfProcesses = 13 + +var gResults {.threadvar.}: seq[string] + +proc execCb(idx: int, p: Process) = + let exitCode = p.peekExitCode + if exitCode < len(gResults): + gResults[exitCode] = p.outputStream.readAll.strip + +when isMainModule: + + if paramCount() == 0: + gResults = newSeq[string](NumberOfProcesses) + var checks = newSeq[string](NumberOfProcesses) + var commands = newSeq[string](NumberOfProcesses) + for i in 0..len(commands) - 1: + commands[i] = getAppFileName() & " " & $i + checks[i] = $i + let cres = execProcesses(commands, options = {poStdErrToStdOut}, + afterRunEvent = execCb) + doAssert(cres == len(commands) - 1) + doAssert(gResults == checks) + else: + echo paramStr(1) + programResult = parseInt(paramStr(1)) diff --git a/tests/overload/tprefer_tygenericinst.nim b/tests/overload/tprefer_tygenericinst.nim index 56541c7e8..ab461a0f4 100644 --- a/tests/overload/tprefer_tygenericinst.nim +++ b/tests/overload/tprefer_tygenericinst.nim @@ -2,7 +2,11 @@ discard """ output: '''Version 2 was called. This has the highest precedence. This has the second-highest precedence. -This has the lowest precedence.''' +This has the lowest precedence. +baseobj == +true +even better! == +true''' """ # bug #2220 @@ -26,13 +30,13 @@ template testPred(a: untyped) = type SomeA = A|A # A hack to make "A" a typeclass. when a >= 3: - proc p[X](x: X) = - echo "This has the highest precedence." - when a >= 2: proc p[X: A](x: X) = + echo "This has the highest precedence." + when a == 2: + proc p[X: SomeA](x: X) = echo "This has the second-highest precedence." when a >= 1: - proc p[X: SomeA](x: X) = + proc p[X](x: X) = echo "This has the lowest precedence." p(B()) @@ -40,3 +44,25 @@ template testPred(a: untyped) = testPred(3) testPred(2) testPred(1) + +# bug #6526 +type + BaseObj = ref object of RootObj + DerivedObj = ref object of BaseObj + OtherDerivate = ref object of BaseObj + +proc `==`*[T1, T2: BaseObj](a: T1, b: T2): bool = + echo "baseobj ==" + return true + +let a = DerivedObj() +let b = DerivedObj() +echo a == b + +proc `==`*[T1, T2: OtherDerivate](a: T1, b: T2): bool = + echo "even better! ==" + return true + +let a2 = OtherDerivate() +let b2 = OtherDerivate() +echo a2 == b2 diff --git a/tests/overload/tstatic_with_converter.nim b/tests/overload/tstatic_with_converter.nim new file mode 100644 index 000000000..2871744eb --- /dev/null +++ b/tests/overload/tstatic_with_converter.nim @@ -0,0 +1,47 @@ +discard """ +output: ''' +9.0''' +""" + +### bug #6773 + +{.emit: """ /*INCLUDESECTION*/ +typedef double cimported; + +cimported set1_imported(double x) { + return x; +} + +"""} + +type vfloat{.importc: "cimported".} = object + +proc set1(a: float): vfloat {.importc: "set1_imported".} + +converter scalar_to_vector(x: float): vfloat = + set1(x) + +proc sqrt(x: vfloat): vfloat = + x + +proc pow(x, y: vfloat): vfloat = + y + +proc `^`(x: vfloat, exp: static[int]): vfloat = + when exp == 0: + 1.0 + else: + x + +proc `^`(x: vfloat, exp: static[float]): vfloat = + when exp == 0.5: + sqrt(x) + else: + pow(x, exp) + +proc `$`(x: vfloat): string = + let y = cast[ptr float](unsafeAddr x) + echo y[] + +let x = set1(9.0) +echo x^0.5 diff --git a/tests/package_level_objects/definefoo.nim b/tests/package_level_objects/definefoo.nim new file mode 100644 index 000000000..36576ab59 --- /dev/null +++ b/tests/package_level_objects/definefoo.nim @@ -0,0 +1,3 @@ +type + Foo* {.package.} = object + x, y: int diff --git a/tests/package_level_objects/mypackage.nimble b/tests/package_level_objects/mypackage.nimble new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/package_level_objects/mypackage.nimble diff --git a/tests/package_level_objects/tusefoo.nim b/tests/package_level_objects/tusefoo.nim new file mode 100644 index 000000000..f9bae9545 --- /dev/null +++ b/tests/package_level_objects/tusefoo.nim @@ -0,0 +1,16 @@ +discard """ + output: '''@[(x: 3, y: 4)]''' +""" + +type + mypackage.Foo = object + Other = proc (inp: Foo) + +import definefoo + +# after this import, Foo is a completely resolved type, so +# we can create a sequence of it: +var s: seq[Foo] = @[] + +s.add Foo(x: 3, y: 4) +echo s diff --git a/tests/package_level_objects/tusefoo2.nim b/tests/package_level_objects/tusefoo2.nim new file mode 100644 index 000000000..be6b3fcda --- /dev/null +++ b/tests/package_level_objects/tusefoo2.nim @@ -0,0 +1,19 @@ +discard """ + output: '''compiles''' +""" + +# Test that the object type does not need to be resolved at all: + +type + mypackage.Foo = object + Other = proc (inp: Foo) + + Node = ref object + external: ptr Foo + data: string + +var x: Node +new(x) +x.data = "compiles" + +echo x.data diff --git a/tests/parallel/tdisjoint_slice2.nim b/tests/parallel/tdisjoint_slice2.nim index 1e86ea644..25cb2362f 100644 --- a/tests/parallel/tdisjoint_slice2.nim +++ b/tests/parallel/tdisjoint_slice2.nim @@ -11,12 +11,19 @@ discard """ sortoutput: true """ -import threadpool +import threadpool, locks + +var echoLock: Lock +initLock echoLock proc f(a: openArray[int]) = - for x in a: echo x + for x in a: + withLock echoLock: + echo x -proc f(a: int) = echo a +proc f(a: int) = + withLock echoLock: + echo a proc main() = var a: array[0..9, int] = [0,1,2,3,4,5,6,7,8,9] diff --git a/tests/parser/tletcolon.nim b/tests/parser/tletcolon.nim index 6b86535c8..7eaa5e3e5 100644 --- a/tests/parser/tletcolon.nim +++ b/tests/parser/tletcolon.nim @@ -4,7 +4,8 @@ discard """ 44 3 more body code yes -yes''' +yes +block expression works''' """ template x(body): untyped = @@ -32,3 +33,29 @@ let other = x: echo "no" let outer = y(5): echo "yes" + + +# bug #6609 +type + TextureInternalFormat = enum RED, RGB, RGBA + +const channels = 4 + +let format = + if channels == 1: + TextureInternalFormat.RED + elif channels == 3: + TextureInternalFormat.RGB + elif channels == 4: + TextureInternalFormat.RGBA + else: + echo "Texture Format Unknown, assuming RGB" #This echo causes an error + TextureInternalFormat.RGB + +# Block as expressions #3827 +block: + let x = block: + var y = 2 + echo "block expression works" + y*y + doAssert x == 4 \ No newline at end of file diff --git a/tests/parser/tpostexprblocks.nim b/tests/parser/tpostexprblocks.nim index 341ca737a..3b9c956c2 100644 --- a/tests/parser/tpostexprblocks.nim +++ b/tests/parser/tpostexprblocks.nim @@ -1,82 +1,82 @@ discard """ nimout: ''' StmtList - Ident !"foo010" + Ident ident"foo010" Call - Ident !"foo020" + Ident ident"foo020" Call - Ident !"foo030" - Ident !"x" + Ident ident"foo030" + Ident ident"x" Command - Ident !"foo040" - Ident !"x" + Ident ident"foo040" + Ident ident"x" Call - Ident !"foo050" + Ident ident"foo050" StmtList DiscardStmt Empty Call - Ident !"foo060" + Ident ident"foo060" StmtList DiscardStmt Empty Call - Ident !"foo070" + Ident ident"foo070" StrLit test StmtList DiscardStmt Empty Call - Ident !"foo080" + Ident ident"foo080" StrLit test StmtList DiscardStmt Empty Command - Ident !"foo090" + Ident ident"foo090" StrLit test StmtList DiscardStmt Empty Command - Ident !"foo100" + Ident ident"foo100" Call StrLit test StmtList DiscardStmt Empty Command - Ident !"foo101" + Ident ident"foo101" Call IntLit 10 StmtList DiscardStmt Empty Command - Ident !"foo110" + Ident ident"foo110" IntLit 1 Par Infix - Ident !"+" + Ident ident"+" IntLit 2 IntLit 3 StmtList DiscardStmt Empty Command - Ident !"foo120" + Ident ident"foo120" IntLit 1 Call Par Infix - Ident !"+" + Ident ident"+" IntLit 2 IntLit 3 StmtList DiscardStmt Empty Call - Ident !"foo130" + Ident ident"foo130" Do Empty Empty @@ -84,7 +84,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"x" + Ident ident"x" Empty Empty Empty @@ -93,7 +93,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo140" + Ident ident"foo140" Do Empty Empty @@ -101,8 +101,8 @@ StmtList FormalParams Empty IdentDefs - Ident !"x" - Ident !"int" + Ident ident"x" + Ident ident"int" Empty Empty Empty @@ -110,16 +110,16 @@ StmtList DiscardStmt Empty Call - Ident !"foo150" + Ident ident"foo150" Do Empty Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"x" - Ident !"int" + Ident ident"x" + Ident ident"int" Empty Empty Empty @@ -127,9 +127,9 @@ StmtList DiscardStmt Empty Command - Ident !"foo160" + Ident ident"foo160" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -137,7 +137,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -146,7 +146,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo170" + Ident ident"foo170" StmtList DiscardStmt Empty @@ -155,7 +155,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo180" + Ident ident"foo180" StmtList DiscardStmt Empty @@ -167,9 +167,9 @@ StmtList DiscardStmt Empty Command - Ident !"foo190" + Ident ident"foo190" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -177,7 +177,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -190,9 +190,9 @@ StmtList Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"z" + Ident ident"z" Empty Empty Empty @@ -205,10 +205,10 @@ StmtList Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"w" - Ident !"int" + Ident ident"w" + Ident ident"int" Empty Empty Empty @@ -223,10 +223,10 @@ StmtList DiscardStmt Empty Call - Ident !"foo200" - Ident !"x" + Ident ident"foo200" + Ident ident"x" Call - Ident !"bar" + Ident ident"bar" StmtList DiscardStmt Empty @@ -236,53 +236,53 @@ StmtList Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty - Ident !"foo210" + Ident ident"foo210" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo220" + Ident ident"foo220" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo230" - Ident !"x" + Ident ident"foo230" + Ident ident"x" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Command - Ident !"foo240" - Ident !"x" + Ident ident"foo240" + Ident ident"x" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo250" + Ident ident"foo250" StmtList DiscardStmt Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo260" + Ident ident"foo260" StmtList DiscardStmt Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo270" + Ident ident"foo270" StmtList DiscardStmt Empty @@ -292,12 +292,12 @@ StmtList Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Command - Ident !"foo280" + Ident ident"foo280" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -305,7 +305,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -318,40 +318,40 @@ StmtList DiscardStmt Empty Asgn - Ident !"a" - Ident !"foo290" + Ident ident"a" + Ident ident"foo290" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo300" + Ident ident"foo300" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo310" - Ident !"x" + Ident ident"foo310" + Ident ident"x" Asgn - Ident !"a" + Ident ident"a" Command - Ident !"foo320" - Ident !"x" + Ident ident"foo320" + Ident ident"x" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo330" + Ident ident"foo330" StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo340" + Ident ident"foo340" StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo350" + Ident ident"foo350" StmtList DiscardStmt Empty @@ -360,13 +360,13 @@ StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Command - Ident !"foo360" + Ident ident"foo360" Call DotExpr - Ident !"x" - Ident !"bar" + Ident ident"x" + Ident ident"bar" Do Empty Empty @@ -374,7 +374,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -388,20 +388,20 @@ StmtList Empty Command DotExpr - Ident !"foo370" - Ident !"add" + Ident ident"foo370" + Ident ident"add" Call - Ident !"quote" + Ident ident"quote" StmtList DiscardStmt Empty Call DotExpr - Ident !"foo380" - Ident !"add" + Ident ident"foo380" + Ident ident"add" BracketExpr Call - Ident !"quote" + Ident ident"quote" StmtList DiscardStmt Empty diff --git a/tests/pragmas/tnoreturn.nim b/tests/pragmas/tnoreturn.nim new file mode 100644 index 000000000..4d00c6034 --- /dev/null +++ b/tests/pragmas/tnoreturn.nim @@ -0,0 +1,22 @@ +discard """ +ccodeCheck: "\\i @'__attribute__((noreturn))' .*" +""" + +proc noret1*(i: int) {.noreturn.} = + echo i + + +proc noret2*(i: int): void {.noreturn.} = + echo i + +var p {.used.}: proc(i: int): int +doAssert(not compiles( + p = proc(i: int): int {.noreturn.} = i # noreturn lambda returns int +)) + + +doAssert(not compiles( + block: + noret1(5) + echo 1 # statement after noreturn +)) diff --git a/tests/pragmas/treorder.nim b/tests/pragmas/treorder.nim new file mode 100644 index 000000000..6a6bbff4d --- /dev/null +++ b/tests/pragmas/treorder.nim @@ -0,0 +1,75 @@ +discard """ +output:'''0 +1 +2 +3''' +""" + +import macros +{.reorder: on .} + +echo foo(-1) +echo callWithFoo(0) +echo(CA+CD) +echo useTypes(TA(x:TB(x:1)), 2) +second(0) + +template callWithFoo(arg: untyped): untyped = + foo(arg) + +proc first(i: int): void + +proc second(i: int): void = + make(first) + first(i) + +proc useTypes(a: TA, d: TD): int = + result = a.x.x+d + +type + TDoubleCyclic = ref object + x: TCyclicA + y: TCyclicB + +type + TCyclicA = ref object + x: TDoubleCyclic + +type + TCyclicB = ref object + x: TDoubleCyclic + +const + CA = 1 + CB = CC + +type + TA = object + x: TB + TC = type(CC) + TD = type(CA) + +const + CC = 1 + CD = CB + +type + TB = object + x: TC + +proc foo(x: int): int = + result = bar(x) + +proc bar(x: int): int = + result = x+1 + +macro make(arg: untyped): untyped = + ss &= arg.repr + ss &= " " + discard + +proc first(i: int): void = + make(second) + +static: + var ss: string = "" \ No newline at end of file diff --git a/tests/range/tn8vsint16.nim b/tests/range/tn8vsint16.nim new file mode 100644 index 000000000..bf4f78e3b --- /dev/null +++ b/tests/range/tn8vsint16.nim @@ -0,0 +1,18 @@ +discard """ + output: '''-9''' +""" + +type + n32 = range[0..high(int)] + n8* = range[0'i8..high(int8)] + +proc `+`*(a: n32, b: n32{nkIntLit}): n32 = discard + +proc `-`*(a: n8, b: n8): n8 = n8(system.`-`(a, b)) + +var x, y: n8 +var z: int16 + +# ensure this doesn't call our '-' but system.`-` for int16: +echo z - n8(9) + diff --git a/tests/rational/trat_init.nim b/tests/rational/trat_init.nim index df29ff6e3..360a48537 100644 --- a/tests/rational/trat_init.nim +++ b/tests/rational/trat_init.nim @@ -1,10 +1,14 @@ discard """ - file: "trat_init.nim" - exitcode: "1" + output: '''true''' """ import rationals var z = Rational[int](num: 0, den: 1) o = initRational(num=1, den=1) a = initRational(1, 2) - r = initRational(1, 0) # this fails - no zero denominator + +try: + var + r = initRational(1, 0) # this fails - no zero denominator +except AssertionError: + echo "true" diff --git a/tests/showoff/thello2.nim b/tests/showoff/thello2.nim index d2e2f6227..3ccb4e3be 100644 --- a/tests/showoff/thello2.nim +++ b/tests/showoff/thello2.nim @@ -1,5 +1,5 @@ discard """ - output: '''(a: 3, b: 4, s: abc)''' + output: '''(a: 3, b: 4, s: "abc")''' """ type diff --git a/tests/specialops/tdotops.nim b/tests/specialops/tdotops.nim index bca949922..227204f51 100644 --- a/tests/specialops/tdotops.nim +++ b/tests/specialops/tdotops.nim @@ -11,7 +11,8 @@ no params call to a no params call to b 100 one param call to c with 10 -100''' +100 +0 4''' """ type @@ -23,16 +24,16 @@ type T2 = object x: int -proc `.`*(v: T1, f: string): int = - echo "reading field ", f - return v.x +template `.`*(v: T1, f: untyped): int = + echo "reading field ", astToStr(f) + v.x -proc `.=`(x: var T1, f: string{lit}, v: int) = - echo "assigning ", f, " = ", v - x.x = v +template `.=`(t: var T1, f: untyped, v: int) = + echo "assigning ", astToStr(f), " = ", v + t.x = v -template `.()`(x: T1, f: string, args: varargs[typed]): string = - echo "call to ", f +template `.()`(x: T1, f: untyped, args: varargs[typed]): string = + echo "call to ", astToStr(f) "dot call" echo "" @@ -47,13 +48,13 @@ echo t.y() var d = TD(t) assert(not compiles(d.y)) -proc `.`(v: T2, f: string): int = - echo "no params call to ", f - return v.x +template `.`(v: T2, f: untyped): int = + echo "no params call to ", astToStr(f) + v.x -proc `.`*(v: T2, f: string, a: int): int = - echo "one param call to ", f, " with ", a - return v.x +template `.`*(v: T2, f: untyped, a: int): int = + echo "one param call to ", astToStr(f), " with ", a + v.x var tt = T2(x: 100) @@ -63,3 +64,24 @@ echo tt.c(10) assert(not compiles(tt.d("x"))) assert(not compiles(tt.d(1, 2))) + +# test simple usage that delegates fields: +type + Other = object + a: int + b: string + MyObject = object + nested: Other + x, y: int + +template `.`(x: MyObject; field: untyped): untyped = + x.nested.field + +template `.=`(x: MyObject; field, value: untyped) = + x.nested.field = value + +var m: MyObject + +m.a = 4 +m.b = "foo" +echo m.x, " ", m.a diff --git a/tests/stdlib/somesql.sql b/tests/stdlib/somesql.sql new file mode 100644 index 000000000..285f93cec --- /dev/null +++ b/tests/stdlib/somesql.sql @@ -0,0 +1,298 @@ +create table anon40( + anon41 anon42 primary key default anon43(), + anon44 text unique not null, + anon45 text unique not null, + anon46 text not null, + anon47 text not null, + anon48 text default null, + anon49 text default null, + anon50 text default null, + anon51 text default null, + anon52 text default null, + anon53 text default null, + anon54 text default null, + anon55 text default null, + anon56 text default null, + anon57 text default null, + anon58 text default null, + anon59 text default null, + anon60 text default null, + anon61 text default null, + anon62 varchar(30) default null, + anon63 varchar(30) default null); +create table anon64( + anon41 serial primary key, + anon65 varchar(30) not null unique, + anon46 varchar(30) not null, + anon66 varchar(30) not null, + anon47 varchar(30) not null, + anon67 text not null, + anon55 varchar(30) not null unique, + anon68 varchar(30) default 'o', + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon71( + anon72 varchar(30) not null primary key, + anon73 varchar(30) not null unique, + anon70 int not null references anon40(anon41)); +create table anon74( + anon72 varchar(30) not null primary key, + anon73 varchar(30) not null unique, + anon75 varchar(30) not null, + anon70 int not null references anon40(anon41), + foreign key(anon75) references anon71(anon72)); +create table anon76( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 varchar(30) not null unique, + anon77 varchar(30) not null, + anon70 int not null references anon40(anon41), + foreign key(anon77) references anon74(anon72)); +create table anon78( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 varchar(30) not null unique, + anon79 int not null, + anon80 varchar(30) default null, + anon81 int not null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41), + foreign key(anon79) references anon78(anon41), + foreign key(anon81) references anon76(anon41)); +create table anon82( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 text not null unique, + anon79 int not null, + anon80 text default null, + anon83 varchar(30) not null default 'd', + anon84 decimal default 0.00, + anon69 boolean not null default true, + anon85 decimal default 0.00, + anon86 decimal default 0.00, + anon87 decimal default 0.00, + anon70 int not null references anon40(anon41), + foreign key(anon79) references anon78(anon41)); +create table anon88( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon80 text default '', + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon89( + anon90 int not null primary key, + anon91 anon92 default 0.00, + anon93 varchar(30), + anon69 boolean not null default true, + anon70 int not null references anon40(anon41), + foreign key(anon90) references anon82(anon41)); +create table anon94( + anon41 serial primary key, + anon73 text unique not null, + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon95( + anon41 serial primary key, + anon73 text unique not null, + anon96 int not null references anon94(anon41), + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon97( + anon41 serial primary key, + anon73 text unique not null, + anon98 int not null references anon95(anon41), + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon99( + anon41 serial primary key, + anon73 varchar(30) unique not null, + anon100 varchar(30) default null, + anon101 anon102 default 0, + anon103 varchar(30) default 'g', + anon104 int not null, + anon105 decimal not null default 1, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon106( + anon107 varchar(30) default 'g', + anon108 int references anon99(anon41) not null, + anon109 decimal default 1, + anon110 int references anon99(anon41) not null, + anon70 int not null references anon40(anon41)); +create table anon111( + anon41 serial primary key, + anon112 text unique not null, + anon73 text unique not null, + anon113 anon102 references anon97(anon41) not null, + anon114 varchar(30) not null, + anon115 int not null references anon88(anon41), + anon116 int not null references anon82(anon41), + anon117 int not null references anon82(anon41), + anon118 int not null references anon82(anon41), + anon119 int not null references anon82(anon41), + anon120 int not null references anon82(anon41), + anon121 int not null references anon82(anon41), + anon122 int references anon99(anon41) not null, + anon123 decimal default 0.00, + anon124 decimal default 0.00, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon125( + anon41 serial primary key, + anon126 int references anon111(anon41) not null, + anon80 text not null, + anon127 varchar(30) not null, + anon128 decimal default 0.00, + anon129 decimal default 0, + anon130 decimal default 0, + anon131 decimal default 0, + anon132 decimal default 0, + anon133 decimal default 0.00, + anon134 decimal default 0.00, + anon135 decimal default 0.00, + anon70 int not null references anon40(anon41), constraint anon136 check anon137(anon126, anon127, anon129)); +create table anon138( + anon41 serial primary key, + anon126 int references anon111(anon41) not null, + anon80 text not null, + anon127 varchar(30) not null, + anon139 date not null, + anon129 decimal default 0, + anon130 decimal default 0, + anon131 decimal default 0, + anon132 decimal default 0, + anon70 int not null references anon40(anon41), constraint anon136 check anon137(anon127, anon129)); +create table anon140( + anon41 serial primary key, + anon141 text unique not null, + anon46 text default null, + anon47 text default null, + anon57 varchar(30) default null, + anon142 text default null, + anon51 text default null, + anon143 varchar(30) default null, + anon53 text default null, + anon54 text default null, + anon55 text default null, + anon45 text default null, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon144( + anon41 serial primary key, + anon72 varchar(30) unique not null, + anon73 varchar(30) unique not null, + anon80 varchar(30) default null, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon145( + anon41 serial primary key, + anon72 varchar(30) unique not null, + anon73 varchar(30) unique not null, + anon146 int not null, + anon147 anon92 default 1, + anon148 anon92 default 9999999, + anon80 varchar(30) default null, + anon69 boolean default true, + anon149 int default 0, + anon150 int not null, + anon151 anon92 default 0, + anon70 int not null references anon40(anon41), + foreign key(anon150) references anon82(anon41), + foreign key(anon146) references anon144(anon41)); +create table anon152( + anon41 serial primary key, + anon73 varchar(30) not null unique, + anon153 varchar(30) not null unique, + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon154( + anon41 serial primary key not null, + anon155 int not null unique, + date date default anon156 not null, + anon157 anon102 references anon140(anon41) not null, + anon158 anon102 references anon64(anon41) not null, + anon159 decimal default 0 not null, + anon160 decimal default 0 not null, + anon161 decimal default 0 not null, + anon162 decimal default 0 not null, + anon163 decimal default 0 not null, + anon164 decimal default 0 not null, + anon165 decimal default 0.00, + anon166 decimal default 0 not null, + anon167 decimal default 0.00, + anon168 decimal default 0 not null, + anon169 boolean default false, + anon170 varchar(30) default 'ca', + anon171 varchar(30) default 'n', + anon172 varchar(30) not null default 'd', + anon173 decimal default 0.00, + anon174 decimal default 0.00, + anon175 int, + anon176 varchar(30) default null, + anon177 varchar(30) default '', + anon178 varchar(30) default null, + anon70 int not null references anon40(anon41)); +create table anon179( + anon41 serial primary key not null, + anon180 anon102 references anon154(anon41) not null, + anon181 int references anon125(anon41) not null, + anon182 int references anon82(anon41) not null, + anon122 int references anon99(anon41) not null, + anon183 decimal not null, + anon184 decimal default 0.00, + anon174 decimal default 0, + anon160 decimal default 0.00, + anon185 decimal default 0, + anon162 decimal default 0.00, + anon186 decimal default 0, + anon163 decimal default 0.00, + anon187 decimal default 0, + anon164 decimal default 0.00, + anon188 decimal default 0, + anon161 decimal default 0.00, + anon189 decimal default 0.00, + anon168 decimal default 0.00, + anon190 decimal not null, + anon191 decimal default 0, + anon83 varchar(30) not null default 't', + anon192 decimal default 0, + anon193 decimal not null, + anon194 decimal not null, + anon70 int not null references anon40(anon41)); +create table anon195( + anon41 serial not null, + anon196 int not null, + anon175 char not null, + anon90 int not null references anon82, + anon165 decimal default 0.00, + anon70 int not null references anon40(anon41), primary key(anon196, anon175)); +create table anon197( + anon41 serial not null, + anon196 int not null, + anon175 char not null, + anon198 int not null, + anon189 decimal default 0.00, + anon199 varchar(30) default null, + anon200 varchar(30) default null, + anon70 int not null references anon40(anon41), + primary key(anon196, anon175), + foreign key(anon198) references anon145(anon41)); +create table anon201( + anon41 serial primary key, + anon202 varchar(30) not null, + anon203 varchar(30) not null, + anon204 varchar(30) not null, + anon205 varchar(30) not null, + anon206 boolean default null, + anon70 int not null references anon40(anon41)); +create table anon207( + anon41 serial primary key, + anon208 varchar(30) not null, + anon209 varchar(30) not null, + anon204 varchar(30) default null, + anon70 int not null references anon40(anon41)); + diff --git a/tests/stdlib/tfrexp1.nim b/tests/stdlib/tfrexp1.nim new file mode 100644 index 000000000..c6bb2b38c --- /dev/null +++ b/tests/stdlib/tfrexp1.nim @@ -0,0 +1,44 @@ +discard """ + targets: "js c c++" + output: '''ok''' +""" + +import math +import strformat + +const manualTest = false + +proc frexp_test(lo, hi, step: float64) = + var exp: int + var frac: float64 + + var eps = 1e-15.float64 + + var x:float64 = lo + while x <= hi: + frac = frexp(x.float, exp) + let rslt = pow(2.0, float(exp)) * frac + + doAssert(abs(rslt - x) < eps) + + when manualTest: + echo fmt("x: {x:10.3f} exp: {exp:4d} frac: {frac:24.20f} check: {$(abs(rslt - x) < eps):-5s} {rslt: 9.3f}") + x += step + +when manualTest: + var exp: int + var frac: float64 + + for flval in [1.7976931348623157e+308, -1.7976931348623157e+308, # max, min float64 + 3.4028234663852886e+38, -3.4028234663852886e+38, # max, min float32 + 4.9406564584124654e-324, -4.9406564584124654e-324, # smallest/largest positive/negative float64 + 1.4012984643248171e-45, -1.4012984643248171e-45, # smallest/largest positive/negative float32 + 2.2250738585072014e-308, 1.1754943508222875e-38]: # smallest normal float64/float32 + frac = frexp(flval, exp) + echo fmt("{flval:25.16e}, {exp: 6d}, {frac: .20f} {frac * pow(2.0, float(exp)): .20e}") + + frexp_test(-1000.0, 1000.0, 0.0125) +else: + frexp_test(-1000000.0, 1000000.0, 0.125) + +echo "ok" diff --git a/tests/stdlib/tgetfileinfo.nim b/tests/stdlib/tgetfileinfo.nim index 1c897b702..019c2eb7f 100644 --- a/tests/stdlib/tgetfileinfo.nim +++ b/tests/stdlib/tgetfileinfo.nim @@ -61,7 +61,7 @@ proc testGetFileInfo = block: let testFile = open(getAppFilename()) - testHandle = fileHandle(testFile) + testHandle = getFileHandle(testFile) try: discard getFileInfo(testFile) #echo("Handle : Valid File : Success") diff --git a/tests/stdlib/thttpclient.nim b/tests/stdlib/thttpclient.nim index e759e2977..fff02722a 100644 --- a/tests/stdlib/thttpclient.nim +++ b/tests/stdlib/thttpclient.nim @@ -2,6 +2,8 @@ discard """ cmd: "nim c --threads:on -d:ssl $file" exitcode: 0 output: "OK" + disabled: "travis" + disabled: "appveyor" """ import strutils diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 153cf8556..2cdd82305 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -2,7 +2,7 @@ discard """ file: "tjsonmacro.nim" output: "" """ -import json, strutils +import json, strutils, options, tables when isMainModule: # Tests inspired by own use case (with some additional tests). @@ -246,4 +246,138 @@ when isMainModule: var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue]) let jnode = %b let data = jnode.to(Bird) - doAssert data == b \ No newline at end of file + doAssert data == b + + block: + type + MsgBase = ref object of RootObj + name*: string + + MsgChallenge = ref object of MsgBase + challenge*: string + + let data = %*{"name": "foo", "challenge": "bar"} + let msg = data.to(MsgChallenge) + doAssert msg.name == "foo" + doAssert msg.challenge == "bar" + + block: + type + Color = enum Red, Brown + Thing = object + animal: tuple[fur: bool, legs: int] + color: Color + + var j = parseJson(""" + {"animal":{"fur":true,"legs":6},"color":"Red"} + """) + + let parsed = to(j, Thing) + doAssert parsed.animal.fur + doAssert parsed.animal.legs == 6 + doAssert parsed.color == Red + + block: + type + Car = object + engine: tuple[name: string, capacity: float] + model: string + + let j = """ + {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} + """ + + var i = 0 + proc mulTest: JsonNode = + i.inc() + return parseJson(j) + + let parsed = mulTest().to(Car) + doAssert parsed.engine.name == "V8" + + doAssert i == 1 + + block: + # Option[T] support! + type + Car1 = object # TODO: Codegen bug when `Car` + engine: tuple[name: string, capacity: Option[float]] + model: string + year: Option[int] + + let noYear = """ + {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} + """ + + let noYearParsed = parseJson(noYear) + let noYearDeser = to(noYearParsed, Car1) + doAssert noYearDeser.engine.capacity == some(5.5) + doAssert noYearDeser.year.isNone + doAssert noYearDeser.engine.name == "V8" + + # Table[T, Y] support. + block: + type + Friend = object + name: string + age: int + + Dynamic = object + name: string + friends: Table[string, Friend] + + let data = """ + {"friends": { + "John": {"name": "John", "age": 35}, + "Elizabeth": {"name": "Elizabeth", "age": 23} + }, "name": "Dominik"} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Dynamic) + doAssert dataDeser.name == "Dominik" + doAssert dataDeser.friends["John"].age == 35 + doAssert dataDeser.friends["Elizabeth"].age == 23 + + # JsonNode support + block: + type + Test = object + name: string + fallback: JsonNode + + let data = """ + {"name": "FooBar", "fallback": 56.42} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Test) + doAssert dataDeser.name == "FooBar" + doAssert dataDeser.fallback.kind == JFloat + doAssert dataDeser.fallback.getFloat() == 56.42 + + # int64, float64 etc support. + block: + type + Test1 = object + a: int8 + b: int16 + c: int32 + d: int64 + e: uint8 + f: uint16 + g: uint32 + h: uint64 + i: float32 + j: float64 + + let data = """ + {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, + "h": 8, "i": 9.9, "j": 10.10} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Test1) + doAssert dataDeser.a == 1 + doAssert dataDeser.f == 6 + doAssert dataDeser.i == 9.9'f32 \ No newline at end of file diff --git a/tests/stdlib/tjsonmacro_reject.nim b/tests/stdlib/tjsonmacro_reject.nim new file mode 100644 index 000000000..00506449f --- /dev/null +++ b/tests/stdlib/tjsonmacro_reject.nim @@ -0,0 +1,18 @@ +discard """ + file: "tjsonmacro_reject.nim" + line: 11 + errormsg: "Use a named tuple instead of: (string, float)" +""" + +import json + +type + Car = object + engine: (string, float) + model: string + +let j = """ + {"engine": {"name": "V8", "capacity": 5.5}, model: "Skyline"} +""" +let parsed = parseJson(j) +echo(to(parsed, Car)) \ No newline at end of file diff --git a/tests/stdlib/tjsonmacro_reject2.nim b/tests/stdlib/tjsonmacro_reject2.nim new file mode 100644 index 000000000..b01153553 --- /dev/null +++ b/tests/stdlib/tjsonmacro_reject2.nim @@ -0,0 +1,21 @@ +discard """ + file: "tjsonmacro_reject2.nim" + line: 10 + errormsg: "The `to` macro does not support ref objects with cycles." +""" +import json + +type + Misdirection = object + cycle: Cycle + + Cycle = ref object + foo: string + cycle: Misdirection + +let data = """ + {"cycle": null} +""" + +let dataParsed = parseJson(data) +let dataDeser = to(dataParsed, Cycle) \ No newline at end of file diff --git a/tests/stdlib/tlists.nim b/tests/stdlib/tlists.nim index 4caa05c90..37e73c53f 100644 --- a/tests/stdlib/tlists.nim +++ b/tests/stdlib/tlists.nim @@ -17,7 +17,7 @@ block SinglyLinkedListTest1: block SinglyLinkedListTest2: var L: TSinglyLinkedList[string] for d in items(data): L.prepend($d) - assert($L == "[6, 5, 4, 3, 2, 1]") + assert($L == """["6", "5", "4", "3", "2", "1"]""") assert("4" in L) diff --git a/tests/stdlib/tmemfiles2.nim b/tests/stdlib/tmemfiles2.nim index 665e92e8a..7ea94cffc 100644 --- a/tests/stdlib/tmemfiles2.nim +++ b/tests/stdlib/tmemfiles2.nim @@ -1,10 +1,8 @@ discard """ file: "tmemfiles2.nim" - disabled: true output: '''Full read size: 20 Half read size: 10 Data: Hello''' """ -# doesn't work on windows. fmReadWrite doesn't create a file. import memfiles, os var mm, mm_full, mm_half: MemFile diff --git a/tests/stdlib/tnetdial.nim b/tests/stdlib/tnetdial.nim index da6088d70..695150179 100644 --- a/tests/stdlib/tnetdial.nim +++ b/tests/stdlib/tnetdial.nim @@ -2,6 +2,7 @@ discard """ cmd: "nim c --threads:on $file" exitcode: 0 output: "OK" + disabled: "travis" """ import os, net, nativesockets, asyncdispatch diff --git a/tests/stdlib/tparsesql.nim b/tests/stdlib/tparsesql.nim new file mode 100644 index 000000000..3dc949ea1 --- /dev/null +++ b/tests/stdlib/tparsesql.nim @@ -0,0 +1,191 @@ +discard """ + file: "tparsesql.nim" +""" + +import parsesql + +doAssert $parseSQL("SELECT foo FROM table;") == "select foo from table;" +doAssert $parseSQL(""" +SELECT + CustomerName, + ContactName, + Address, + City, + PostalCode, + Country, + CustomerName, + ContactName, + Address, + City, + PostalCode, + Country +FROM table;""") == "select CustomerName, ContactName, Address, City, PostalCode, Country, CustomerName, ContactName, Address, City, PostalCode, Country from table;" + +doAssert $parseSQL("SELECT foo FROM table limit 10") == "select foo from table limit 10;" +doAssert $parseSQL("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;" +doAssert $parseSQL("SELECT foo AS bar FROM table") == "select foo as bar from table;" +doAssert $parseSQL("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;" +doAssert $parseSQL("SELECT * FROM table") == "select * from table;" + + +#TODO add count(*) +#doAssert $parseSQL("SELECT COUNT(*) FROM table" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE a = b and c = d +""") == "select * from table where a = b and c = d;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE not b +""") == "select * from table where not b;" + +doAssert $parseSQL(""" +SELECT + * +FROM + table +WHERE + a and not b +""") == "select * from table where a and not b;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE a = b and c = d or n is null and not b + 1 = 3 +""") == "select * from table where a = b and c = d or n is null and not b + 1 = 3;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE (a = b and c = d) or (n is null and not b + 1 = 3) +""") == "select * from table where(a = b and c = d) or (n is null and not b + 1 = 3);" + +doAssert $parseSQL(""" +SELECT * FROM table +HAVING a = b and c = d +""") == "select * from table having a = b and c = d;" + +doAssert $parseSQL(""" +SELECT a, b FROM table +GROUP BY a +""") == "select a, b from table group by a;" + +doAssert $parseSQL(""" +SELECT a, b FROM table +GROUP BY 1, 2 +""") == "select a, b from table group by 1, 2;" + +doAssert $parseSQL("SELECT t.a FROM t as t") == "select t.a from t as t;" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM t +) +""") == "select a, b from(select * from t);" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM t +) as foo +""") == "select a, b from(select * from t) as foo;" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM innerTable as inner1 + ) as inner2 + ) as inner3 + ) as inner4 +) as inner5 +""") == "select a, b from(select * from(select * from(select * from(select * from innerTable as inner1) as inner2) as inner3) as inner4) as inner5;" + +doAssert $parseSQL(""" +SELECT a, b FROM + (SELECT * FROM a), + (SELECT * FROM b), + (SELECT * FROM c) +""") == "select a, b from(select * from a),(select * from b),(select * from c);" + +doAssert $parseSQL(""" +SELECT * FROM Products +WHERE Price BETWEEN 10 AND 20; +""") == "select * from Products where Price between 10 and 20;" + +doAssert $parseSQL(""" +SELECT id FROM a +JOIN b +ON a.id == b.id +""") == "select id from a join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +JOIN (SELECT id from c) as b +ON a.id == b.id +""") == "select id from a join(select id from c) as b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +INNER JOIN b +ON a.id == b.id +""") == "select id from a inner join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +OUTER JOIN b +ON a.id == b.id +""") == "select id from a outer join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +CROSS JOIN b +ON a.id == b.id +""") == "select id from a cross join b on a.id == b.id;" + +doAssert $parseSQL(""" +CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); +CREATE TABLE holidays ( + num_weeks int, + happiness happiness +); +CREATE INDEX table1_attr1 ON table1(attr1); +SELECT * FROM myTab WHERE col1 = 'happy'; +""") == "create type happiness as enum ('happy' , 'very happy' , 'ecstatic' ); create table holidays(num_weeks int , happiness happiness );; create index table1_attr1 on table1(attr1 );; select * from myTab where col1 = 'happy';" + +doAssert $parseSQL(""" +INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) +VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway'); +""") == "insert into Customers (CustomerName , ContactName , Address , City , PostalCode , Country ) values ('Cardinal' , 'Tom B. Erichsen' , 'Skagen 21' , 'Stavanger' , '4006' , 'Norway' );" + +doAssert $parseSQL(""" +INSERT INTO TableName DEFAULT VALUES +""") == "insert into TableName default values;" + +doAssert $parseSQL(""" +UPDATE Customers +SET ContactName = 'Alfred Schmidt', City= 'Frankfurt' +WHERE CustomerID = 1; +""") == "update Customers set ContactName = 'Alfred Schmidt' , City = 'Frankfurt' where CustomerID = 1;" + +doAssert $parseSQL("DELETE FROM table_name;") == "delete from table_name;" + +doAssert $parseSQL("DELETE * FROM table_name;") == "delete from table_name;" + +doAssert $parseSQL(""" +--Select all: +SELECT * FROM Customers; +""") == "select * from Customers;" + +doAssert $parseSQL(""" +SELECT * FROM Customers WHERE (CustomerName LIKE 'L%' +OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%' +OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%') +AND Country='USA' +ORDER BY CustomerName; +""") == "select * from Customers where(CustomerName like 'L%' or CustomerName like 'R%' or CustomerName like 'W%') and Country = 'USA' order by CustomerName;" + +# parse keywords as identifires +doAssert $parseSQL(""" +SELECT `SELECT`, `FROM` as `GROUP` FROM `WHERE`; +""") == """select "SELECT", "FROM" as "GROUP" from "WHERE";""" diff --git a/tests/stdlib/treloop.nim b/tests/stdlib/treloop.nim index 35236708c..b4221525d 100644 --- a/tests/stdlib/treloop.nim +++ b/tests/stdlib/treloop.nim @@ -1,5 +1,5 @@ discard """ - output: "@[(, +, 1, 2, )]" + output: '''@["(", "+", " 1", " 2", ")"]''' """ import re diff --git a/tests/stdlib/tsqlparser.nim b/tests/stdlib/tsqlparser.nim new file mode 100644 index 000000000..4a7b2f7d7 --- /dev/null +++ b/tests/stdlib/tsqlparser.nim @@ -0,0 +1,12 @@ +discard """ + output: '''true''' +""" + +# Just check that we can parse 'somesql' and render it without crashes. + +import parsesql, streams, os + +var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") +discard renderSql(tree) + +echo "true" diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim index ddf533a17..660746150 100644 --- a/tests/stdlib/tstring.nim +++ b/tests/stdlib/tstring.nim @@ -50,6 +50,30 @@ proc test_string_slice() = s[2..0] = numbers doAssert s == "ab1234567890cdefghijklmnopqrstuvwxyz" + # bug #6223 + doAssertRaises(IndexError): + discard s[0..999] + echo("OK") +proc test_string_cmp() = + let world = "hello\0world" + let earth = "hello\0earth" + let short = "hello\0" + let hello = "hello" + let goodbye = "goodbye" + + doAssert world == world + doAssert world != earth + doAssert world != short + doAssert world != hello + doAssert world != goodbye + + doAssert cmp(world, world) == 0 + doAssert cmp(world, earth) > 0 + doAssert cmp(world, short) > 0 + doAssert cmp(world, hello) > 0 + doAssert cmp(world, goodbye) > 0 + test_string_slice() +test_string_cmp() diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index fef1b38c2..071dae5a7 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -13,15 +13,13 @@ proc testStrip() = proc testRemoveSuffix = var s = "hello\n\r" s.removeSuffix - assert s == "hello\n" - s.removeSuffix assert s == "hello" s.removeSuffix assert s == "hello" s = "hello\n\n" s.removeSuffix - assert s == "hello\n" + assert s == "hello" s = "hello\r" s.removeSuffix @@ -41,7 +39,31 @@ proc testRemoveSuffix = s.removeSuffix({'s','z'}) assert s == "hello" s.removeSuffix({'l','o'}) - assert s == "hell" + assert s == "he" + + s = "aeiou" + s.removeSuffix("") + assert s == "aeiou" + + s = "" + s.removeSuffix("") + assert s == "" + + s = " " + s.removeSuffix + assert s == " " + + s = " " + s.removeSuffix("") + assert s == " " + + s = " " + s.removeSuffix(" ") + assert s == " " + + s = " " + s.removeSuffix(' ') + assert s == "" # Contrary to Chomp in other languages # empty string does not change behaviour @@ -49,9 +71,71 @@ proc testRemoveSuffix = s.removeSuffix("") assert s == "hello\r\n\r\n" +proc testRemovePrefix = + var s = "\n\rhello" + s.removePrefix + assert s == "hello" + s.removePrefix + assert s == "hello" + + s = "\n\nhello" + s.removePrefix + assert s == "hello" + + s = "\rhello" + s.removePrefix + assert s == "hello" + + s = "hello \n there" + s.removePrefix + assert s == "hello \n there" + + s = "hello" + s.removePrefix("hel") + assert s == "lo" + s.removePrefix('l') + assert s == "o" + + s = "hellos" + s.removePrefix({'h','e'}) + assert s == "llos" + s.removePrefix({'l','o'}) + assert s == "s" + + s = "aeiou" + s.removePrefix("") + assert s == "aeiou" + + s = "" + s.removePrefix("") + assert s == "" + + s = " " + s.removePrefix + assert s == " " + + s = " " + s.removePrefix("") + assert s == " " + + s = " " + s.removePrefix(" ") + assert s == " " + + s = " " + s.removePrefix(' ') + assert s == "" + + # Contrary to Chomp in other languages + # empty string does not change behaviour + s = "\r\n\r\nhello" + s.removePrefix("") + assert s == "\r\n\r\nhello" + proc main() = testStrip() testRemoveSuffix() + testRemovePrefix() for p in split("/home/a1:xyz:/usr/bin", {':'}): write(stdout, p) @@ -64,6 +148,25 @@ proc testDelete = delete(s, 0, 0) assert s == "1236789ABCDEFG" + +proc testIsAlphaNumeric = + assert isAlphaNumeric("abcdABC1234") == true + assert isAlphaNumeric("a") == true + assert isAlphaNumeric("abcABC?1234") == false + assert isAlphaNumeric("abcABC 1234") == false + assert isAlphaNumeric(".") == false + +testIsAlphaNumeric() + +proc testIsDigit = + assert isDigit("1") == true + assert isDigit("1234") == true + assert isDigit("abcABC?1234") == false + assert isDigit(".") == false + assert isDigit(":") == false + +testIsDigit() + proc testFind = assert "0123456789ABCDEFGH".find('A') == 10 assert "0123456789ABCDEFGH".find('A', 5) == 10 diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim index 05c91ccb2..a6ac186cc 100644 --- a/tests/stdlib/ttimes.nim +++ b/tests/stdlib/ttimes.nim @@ -1,16 +1,17 @@ # test the new time module discard """ file: "ttimes.nim" - action: "run" + output: '''[Suite] ttimes +''' """ import - times, strutils + times, os, strutils, unittest # $ date --date='@2147483647' # Tue 19 Jan 03:14:07 GMT 2038 -proc checkFormat(t: TimeInfo, format, expected: string) = +proc checkFormat(t: DateTime, format, expected: string) = let actual = t.format(format) if actual != expected: echo "Formatting failure!" @@ -18,7 +19,7 @@ proc checkFormat(t: TimeInfo, format, expected: string) = echo "actual : ", actual doAssert false -let t = getGMTime(fromSeconds(2147483647)) +let t = fromUnix(2147483647).utc t.checkFormat("ddd dd MMM hh:mm:ss yyyy", "Tue 19 Jan 03:14:07 2038") t.checkFormat("ddd ddMMMhh:mm:ssyyyy", "Tue 19Jan03:14:072038") t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & @@ -27,107 +28,41 @@ t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & t.checkFormat("yyyyMMddhhmmss", "20380119031407") -let t2 = getGMTime(fromSeconds(160070789)) # Mon 27 Jan 16:06:29 GMT 1975 +let t2 = fromUnix(160070789).utc # Mon 27 Jan 16:06:29 GMT 1975 t2.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & " ss t tt y yy yyy yyyy yyyyy z zz zzz", "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 +0 +00 +00:00") -var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 +var t4 = fromUnix(876124714).utc # Mon 6 Oct 08:58:34 BST 1997 t4.checkFormat("M MM MMM MMMM", "10 10 Oct October") # Interval tests (t4 - initInterval(years = 2)).checkFormat("yyyy", "1995") (t4 - initInterval(years = 7, minutes = 34, seconds = 24)).checkFormat("yyyy mm ss", "1990 24 10") -proc parseTest(s, f, sExpected: string, ydExpected: int) = - let - parsed = s.parse(f) - parsedStr = $getGMTime(toTime(parsed)) - if parsedStr != sExpected: - echo "Parsing failure!" - echo "expected: ", sExpected - echo "actual : ", parsedStr - doAssert false - doAssert(parsed.yearday == ydExpected) -proc parseTestTimeOnly(s, f, sExpected: string) = - doAssert(sExpected in $s.parse(f)) - -# because setting a specific timezone for testing is platform-specific, we use -# explicit timezone offsets in all tests. - -parseTest("Tuesday at 09:04am on Dec 15, 2015 +0", - "dddd at hh:mmtt on MMM d, yyyy z", "2015-12-15T09:04:00+00:00", 348) -# ANSIC = "Mon Jan _2 15:04:05 2006" -parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", - "2006-01-12T15:04:05+00:00", 11) -# UnixDate = "Mon Jan _2 15:04:05 MST 2006" -parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", - "2006-01-12T15:04:05+00:00", 11) -# RubyDate = "Mon Jan 02 15:04:05 -0700 2006" -parseTest("Mon Feb 29 15:04:05 -07:00 2016 +0", "ddd MMM dd HH:mm:ss zzz yyyy z", - "2016-02-29T15:04:05+00:00", 59) # leap day -# RFC822 = "02 Jan 06 15:04 MST" -parseTest("12 Jan 16 15:04 +0", "dd MMM yy HH:mm z", - "2016-01-12T15:04:00+00:00", 11) -# RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone -parseTest("01 Mar 16 15:04 -07:00", "dd MMM yy HH:mm zzz", - "2016-03-01T22:04:00+00:00", 60) # day after february in leap year -# RFC850 = "Monday, 02-Jan-06 15:04:05 MST" -parseTest("Monday, 12-Jan-06 15:04:05 +0", "dddd, dd-MMM-yy HH:mm:ss z", - "2006-01-12T15:04:05+00:00", 11) -# RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" -parseTest("Sun, 01 Mar 2015 15:04:05 +0", "ddd, dd MMM yyyy HH:mm:ss z", - "2015-03-01T15:04:05+00:00", 59) # day after february in non-leap year -# RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone -parseTest("Thu, 12 Jan 2006 15:04:05 -07:00", "ddd, dd MMM yyyy HH:mm:ss zzz", - "2006-01-12T22:04:05+00:00", 11) -# RFC3339 = "2006-01-02T15:04:05Z07:00" -parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-ddTHH:mm:ssZzzz", - "2006-01-12T22:04:05+00:00", 11) -parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-dd'T'HH:mm:ss'Z'zzz", - "2006-01-12T22:04:05+00:00", 11) -# RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" -parseTest("2006-01-12T15:04:05.999999999Z-07:00", - "yyyy-MM-ddTHH:mm:ss.999999999Zzzz", "2006-01-12T22:04:05+00:00", 11) -for tzFormat in ["z", "zz", "zzz"]: - # formatting timezone as 'Z' for UTC - parseTest("2001-01-12T22:04:05Z", "yyyy-MM-dd'T'HH:mm:ss" & tzFormat, - "2001-01-12T22:04:05+00:00", 11) -# Kitchen = "3:04PM" -parseTestTimeOnly("3:04PM", "h:mmtt", "15:04:00") -#when not defined(testing): -# echo "Kitchen: " & $s.parse(f) -# var ti = timeToTimeInfo(getTime()) -# echo "Todays date after decoding: ", ti -# var tint = timeToTimeInterval(getTime()) -# echo "Todays date after decoding to interval: ", tint - # checking dayOfWeek matches known days -doAssert getDayOfWeek(21, 9, 1900) == dFri -doAssert getDayOfWeek(1, 1, 1970) == dThu -doAssert getDayOfWeek(21, 9, 1970) == dMon -doAssert getDayOfWeek(1, 1, 2000) == dSat -doAssert getDayOfWeek(1, 1, 2021) == dFri -# Julian tests -doAssert getDayOfWeekJulian(21, 9, 1900) == dFri -doAssert getDayOfWeekJulian(21, 9, 1970) == dMon -doAssert getDayOfWeekJulian(1, 1, 2000) == dSat -doAssert getDayOfWeekJulian(1, 1, 2021) == dFri - -# toSeconds tests with GM timezone -let t4L = getGMTime(fromSeconds(876124714)) -doAssert toSeconds(toTime(t4L)) == 876124714 -doAssert toSeconds(toTime(t4L)) + t4L.timezone.float == toSeconds(toTime(t4)) +doAssert getDayOfWeek(01, mJan, 0000) == dSat +doAssert getDayOfWeek(01, mJan, -0023) == dSat +doAssert getDayOfWeek(21, mSep, 1900) == dFri +doAssert getDayOfWeek(01, mJan, 1970) == dThu +doAssert getDayOfWeek(21, mSep, 1970) == dMon +doAssert getDayOfWeek(01, mJan, 2000) == dSat +doAssert getDayOfWeek(01, mJan, 2021) == dFri + +# toUnix tests with GM timezone +let t4L = fromUnix(876124714).utc +doAssert toUnix(toTime(t4L)) == 876124714 +doAssert toUnix(toTime(t4L)) + t4L.utcOffset == toUnix(toTime(t4)) # adding intervals var - a1L = toSeconds(toTime(t4L + initInterval(hours = 1))) + t4L.timezone.float - a1G = toSeconds(toTime(t4)) + 60.0 * 60.0 + a1L = toUnix(toTime(t4L + initInterval(hours = 1))) + t4L.utcOffset + a1G = toUnix(toTime(t4)) + 60 * 60 doAssert a1L == a1G # subtracting intervals -a1L = toSeconds(toTime(t4L - initInterval(hours = 1))) + t4L.timezone.float -a1G = toSeconds(toTime(t4)) - (60.0 * 60.0) +a1L = toUnix(toTime(t4L - initInterval(hours = 1))) + t4L.utcOffset +a1G = toUnix(toTime(t4)) - (60 * 60) doAssert a1L == a1G # add/subtract TimeIntervals and Time/TimeInfo @@ -143,45 +78,16 @@ doAssert ti1 == getTime() ti1 += 1.days doAssert ti1 == getTime() + 1.days -# overflow of TimeIntervals on initalisation -doAssert initInterval(milliseconds = 25000) == initInterval(seconds = 25) -doAssert initInterval(seconds = 65) == initInterval(seconds = 5, minutes = 1) -doAssert initInterval(hours = 25) == initInterval(hours = 1, days = 1) -doAssert initInterval(months = 13) == initInterval(months = 1, years = 1) - # Bug with adding a day to a Time let day = 24.hours let tomorrow = getTime() + day doAssert tomorrow - getTime() == 60*60*24 -doAssert milliseconds(1000 * 60) == minutes(1) -doAssert milliseconds(1000 * 60 * 60) == hours(1) -doAssert milliseconds(1000 * 60 * 60 * 24) == days(1) -doAssert seconds(60 * 60) == hours(1) -doAssert seconds(60 * 60 * 24) == days(1) -doAssert seconds(60 * 60 + 65) == (hours(1) + minutes(1) + seconds(5)) - -# Bug with parse not setting DST properly if the current local DST differs from -# the date being parsed. Need to test parse dates both in and out of DST. We -# are testing that be relying on the fact that tranforming a TimeInfo to a Time -# and back again will correctly set the DST value. With the incorrect parse -# behavior this will introduce a one hour offset from the named time and the -# parsed time if the DST value differs between the current time and the date we -# are parsing. -# -# Unfortunately these tests depend on the locale of the system in which they -# are run. They will not be meaningful when run in a locale without DST. They -# also assume that Jan. 1 and Jun. 1 will have differing isDST values. -let dstT1 = parse("2016-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss") -let dstT2 = parse("2016-06-01 00:00:00", "yyyy-MM-dd HH:mm:ss") -doAssert dstT1 == getLocalTime(toTime(dstT1)) -doAssert dstT2 == getLocalTime(toTime(dstT2)) - # Comparison between Time objects should be detected by compiler # as 'noSideEffect'. proc cmpTimeNoSideEffect(t1: Time, t2: Time): bool {.noSideEffect.} = result = t1 == t2 -doAssert cmpTimeNoSideEffect(0.fromSeconds, 0.fromSeconds) +doAssert cmpTimeNoSideEffect(0.fromUnix, 0.fromUnix) # Additionally `==` generic for seq[T] has explicit 'noSideEffect' pragma # so we can check above condition by comparing seq[Time] sequences let seqA: seq[Time] = @[] @@ -195,43 +101,197 @@ for tz in [ (-1800, "+0", "+00", "+00:30"), # half an hour (7200, "-2", "-02", "-02:00"), # positive (38700, "-10", "-10", "-10:45")]: # positive with three quaters hour - let ti = TimeInfo(monthday: 1, timezone: tz[0]) + let ti = DateTime(month: mJan, monthday: 1, utcOffset: tz[0]) doAssert ti.format("z") == tz[1] doAssert ti.format("zz") == tz[2] doAssert ti.format("zzz") == tz[3] -block formatDst: - var ti = TimeInfo(monthday: 1, isDst: true) - - # BST - ti.timezone = 0 - doAssert ti.format("z") == "+1" - doAssert ti.format("zz") == "+01" - doAssert ti.format("zzz") == "+01:00" - - # EDT - ti.timezone = 5 * 60 * 60 - doAssert ti.format("z") == "-4" - doAssert ti.format("zz") == "-04" - doAssert ti.format("zzz") == "-04:00" - -block dstTest: - let nonDst = TimeInfo(year: 2015, month: mJan, monthday: 01, yearday: 0, - weekday: dThu, hour: 00, minute: 00, second: 00, isDST: false, timezone: 0) - var dst = nonDst - dst.isDst = true - # note that both isDST == true and isDST == false are valid here because - # DST is in effect on January 1st in some southern parts of Australia. - # FIXME: Fails in UTC - # doAssert nonDst.toTime() - dst.toTime() == 3600 - doAssert nonDst.format("z") == "+0" - doAssert dst.format("z") == "+1" - - # parsing will set isDST in relation to the local time. We take a date in - # January and one in July to maximize the probability to hit one date with DST - # and one without on the local machine. However, this is not guaranteed. +block countLeapYears: + # 1920, 2004 and 2020 are leap years, and should be counted starting at the following year + doAssert countLeapYears(1920) + 1 == countLeapYears(1921) + doAssert countLeapYears(2004) + 1 == countLeapYears(2005) + doAssert countLeapYears(2020) + 1 == countLeapYears(2021) + +block timezoneConversion: + var l = now() + let u = l.utc + l = u.local + + doAssert l.timezone == local() + doAssert u.timezone == utc() + +template parseTest(s, f, sExpected: string, ydExpected: int) = let - parsedJan = parse("2016-01-05 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") - parsedJul = parse("2016-07-01 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") - doAssert toTime(parsedJan) == fromSeconds(1451962800) - doAssert toTime(parsedJul) == fromSeconds(1467342000) + parsed = s.parse(f, utc()) + parsedStr = $parsed + check parsedStr == sExpected + if parsed.yearday != ydExpected: + echo s + echo parsed.repr + echo parsed.yearday, " exp: ", ydExpected + check(parsed.yearday == ydExpected) + +template parseTestTimeOnly(s, f, sExpected: string) = + check sExpected in $s.parse(f, utc()) + +# because setting a specific timezone for testing is platform-specific, we use +# explicit timezone offsets in all tests. +template runTimezoneTests() = + parseTest("Tuesday at 09:04am on Dec 15, 2015 +0", + "dddd at hh:mmtt on MMM d, yyyy z", "2015-12-15T09:04:00+00:00", 348) + # ANSIC = "Mon Jan _2 15:04:05 2006" + parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", + "2006-01-12T15:04:05+00:00", 11) + # UnixDate = "Mon Jan _2 15:04:05 MST 2006" + parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", + "2006-01-12T15:04:05+00:00", 11) + # RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + parseTest("Mon Feb 29 15:04:05 -07:00 2016 +0", "ddd MMM dd HH:mm:ss zzz yyyy z", + "2016-02-29T15:04:05+00:00", 59) # leap day + # RFC822 = "02 Jan 06 15:04 MST" + parseTest("12 Jan 16 15:04 +0", "dd MMM yy HH:mm z", + "2016-01-12T15:04:00+00:00", 11) + # RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone + parseTest("01 Mar 16 15:04 -07:00", "dd MMM yy HH:mm zzz", + "2016-03-01T22:04:00+00:00", 60) # day after february in leap year + # RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + parseTest("Monday, 12-Jan-06 15:04:05 +0", "dddd, dd-MMM-yy HH:mm:ss z", + "2006-01-12T15:04:05+00:00", 11) + # RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + parseTest("Sun, 01 Mar 2015 15:04:05 +0", "ddd, dd MMM yyyy HH:mm:ss z", + "2015-03-01T15:04:05+00:00", 59) # day after february in non-leap year + # RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone + parseTest("Thu, 12 Jan 2006 15:04:05 -07:00", "ddd, dd MMM yyyy HH:mm:ss zzz", + "2006-01-12T22:04:05+00:00", 11) + # RFC3339 = "2006-01-02T15:04:05Z07:00" + parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-ddTHH:mm:ssZzzz", + "2006-01-12T22:04:05+00:00", 11) + parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-dd'T'HH:mm:ss'Z'zzz", + "2006-01-12T22:04:05+00:00", 11) + # RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + parseTest("2006-01-12T15:04:05.999999999Z-07:00", + "yyyy-MM-ddTHH:mm:ss.999999999Zzzz", "2006-01-12T22:04:05+00:00", 11) + for tzFormat in ["z", "zz", "zzz"]: + # formatting timezone as 'Z' for UTC + parseTest("2001-01-12T22:04:05Z", "yyyy-MM-dd'T'HH:mm:ss" & tzFormat, + "2001-01-12T22:04:05+00:00", 11) + # Kitchen = "3:04PM" + parseTestTimeOnly("3:04PM", "h:mmtt", "15:04:00") + #when not defined(testing): + # echo "Kitchen: " & $s.parse(f) + # var ti = timeToTimeInfo(getTime()) + # echo "Todays date after decoding: ", ti + # var tint = timeToTimeInterval(getTime()) + # echo "Todays date after decoding to interval: ", tint + + # Bug with parse not setting DST properly if the current local DST differs from + # the date being parsed. Need to test parse dates both in and out of DST. We + # are testing that be relying on the fact that tranforming a TimeInfo to a Time + # and back again will correctly set the DST value. With the incorrect parse + # behavior this will introduce a one hour offset from the named time and the + # parsed time if the DST value differs between the current time and the date we + # are parsing. + let dstT1 = parse("2016-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss") + let dstT2 = parse("2016-06-01 00:00:00", "yyyy-MM-dd HH:mm:ss") + check dstT1 == toTime(dstT1).local + check dstT2 == toTime(dstT2).local + + block dstTest: + # parsing will set isDST in relation to the local time. We take a date in + # January and one in July to maximize the probability to hit one date with DST + # and one without on the local machine. However, this is not guaranteed. + let + parsedJan = parse("2016-01-05 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") + parsedJul = parse("2016-07-01 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") + doAssert toTime(parsedJan) == fromUnix(1451962800) + doAssert toTime(parsedJul) == fromUnix(1467342000) + +suite "ttimes": + + # Generate tests for multiple timezone files where available + # Set the TZ env var for each test + when defined(Linux) or defined(macosx): + const tz_dir = "/usr/share/zoneinfo" + const f = "yyyy-MM-dd HH:mm zzz" + + let orig_tz = getEnv("TZ") + var tz_cnt = 0 + for tz_fn in walkFiles(tz_dir & "/*"): + if symlinkExists(tz_fn) or tz_fn.endsWith(".tab") or + tz_fn.endsWith(".list"): + continue + + test "test for " & tz_fn: + tz_cnt.inc + putEnv("TZ", tz_fn) + runTimezoneTests() + + test "enough timezone files tested": + check tz_cnt > 10 + + test "dst handling": + putEnv("TZ", "Europe/Stockholm") + # In case of an impossible time, the time is moved to after the impossible time period + check initDateTime(26, mMar, 2017, 02, 30, 00).format(f) == "2017-03-26 03:30 +02:00" + # In case of an ambiguous time, the earlier time is choosen + check initDateTime(29, mOct, 2017, 02, 00, 00).format(f) == "2017-10-29 02:00 +02:00" + # These are just dates on either side of the dst switch + check initDateTime(29, mOct, 2017, 01, 00, 00).format(f) == "2017-10-29 01:00 +02:00" + check initDateTime(29, mOct, 2017, 01, 00, 00).isDst + check initDateTime(29, mOct, 2017, 03, 01, 00).format(f) == "2017-10-29 03:01 +01:00" + check (not initDateTime(29, mOct, 2017, 03, 01, 00).isDst) + + check initDateTime(21, mOct, 2017, 01, 00, 00).format(f) == "2017-10-21 01:00 +02:00" + + test "issue #6520": + putEnv("TZ", "Europe/Stockholm") + var local = fromUnix(1469275200).local + var utc = fromUnix(1469275200).utc + + let claimedOffset = local.utcOffset + local.utcOffset = 0 + check claimedOffset == utc.toTime - local.toTime + + test "issue #5704": + putEnv("TZ", "Asia/Seoul") + let diff = parse("19700101-000000", "yyyyMMdd-hhmmss").toTime - parse("19000101-000000", "yyyyMMdd-hhmmss").toTime + check diff == 2208986872 + + test "issue #6465": + putEnv("TZ", "Europe/Stockholm") + let dt = parse("2017-03-25 12:00", "yyyy-MM-dd hh:mm") + check $(dt + 1.days) == "2017-03-26T12:00:00+02:00" + + test "datetime before epoch": + check $fromUnix(-2147483648).utc == "1901-12-13T20:45:52+00:00" + + test "adding/subtracting time across dst": + putenv("TZ", "Europe/Stockholm") + + let dt1 = initDateTime(26, mMar, 2017, 03, 00, 00) + check $(dt1 - 1.seconds) == "2017-03-26T01:59:59+01:00" + + var dt2 = initDateTime(29, mOct, 2017, 02, 59, 59) + check $(dt2 + 1.seconds) == "2017-10-29T02:00:00+01:00" + + putEnv("TZ", orig_tz) + + else: + # not on Linux or macosx: run one parseTest only + test "parseTest": + runTimezoneTests() + + test "isLeapYear": + check isLeapYear(2016) + check (not isLeapYear(2015)) + check isLeapYear(2000) + check (not isLeapYear(1900)) + + test "subtract months": + var dt = initDateTime(1, mFeb, 2017, 00, 00, 00, utc()) + check $(dt - 1.months) == "2017-01-01T00:00:00+00:00" + dt = initDateTime(15, mMar, 2017, 00, 00, 00, utc()) + check $(dt - 1.months) == "2017-02-15T00:00:00+00:00" + dt = initDateTime(31, mMar, 2017, 00, 00, 00, utc()) + # This happens due to monthday overflow. It's consistent with Phobos. + check $(dt - 1.months) == "2017-03-03T00:00:00+00:00" \ No newline at end of file diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim index e4a801871..86b9fd037 100644 --- a/tests/stdlib/tunittest.nim +++ b/tests/stdlib/tunittest.nim @@ -13,6 +13,8 @@ discard """ [Suite] bug #5784 +[Suite] test name filtering + ''' """ @@ -120,3 +122,39 @@ suite "bug #5784": field: int var obj: Obj check obj.isNil or obj.field == 0 + +when defined(testing): + suite "test name filtering": + test "test name": + check matchFilter("suite1", "foo", "") + check matchFilter("suite1", "foo", "foo") + check matchFilter("suite1", "foo", "::") + check matchFilter("suite1", "foo", "*") + check matchFilter("suite1", "foo", "::foo") + check matchFilter("suite1", "::foo", "::foo") + + test "test name - glob": + check matchFilter("suite1", "foo", "f*") + check matchFilter("suite1", "foo", "*oo") + check matchFilter("suite1", "12345", "12*345") + check matchFilter("suite1", "q*wefoo", "q*wefoo") + check false == matchFilter("suite1", "foo", "::x") + check false == matchFilter("suite1", "foo", "::x*") + check false == matchFilter("suite1", "foo", "::*x") + # overlap + check false == matchFilter("suite1", "12345", "123*345") + check matchFilter("suite1", "ab*c::d*e::f", "ab*c::d*e::f") + + test "suite name": + check matchFilter("suite1", "foo", "suite1::") + check false == matchFilter("suite1", "foo", "suite2::") + check matchFilter("suite1", "qwe::foo", "qwe::foo") + check matchFilter("suite1", "qwe::foo", "suite1::qwe::foo") + + test "suite name - glob": + check matchFilter("suite1", "foo", "::*") + check matchFilter("suite1", "foo", "*::*") + check matchFilter("suite1", "foo", "*::foo") + check false == matchFilter("suite1", "foo", "*ite2::") + check matchFilter("suite1", "q**we::foo", "q**we::foo") + check matchFilter("suite1", "a::b*c::d*e", "a::b*c::d*e") diff --git a/tests/system/toString.nim b/tests/system/toString.nim index 1279897a7..ea9d6b05b 100644 --- a/tests/system/toString.nim +++ b/tests/system/toString.nim @@ -3,13 +3,13 @@ discard """ """ doAssert "@[23, 45]" == $(@[23, 45]) -doAssert "[32, 45]" == $([32, 45]) -doAssert "@[, foo, bar]" == $(@["", "foo", "bar"]) -doAssert "[, foo, bar]" == $(["", "foo", "bar"]) +doAssert "[32, 45]" == $([32, 45]) +doAssert """@["", "foo", "bar"]""" == $(@["", "foo", "bar"]) +doAssert """["", "foo", "bar"]""" == $(["", "foo", "bar"]) # bug #2395 let alphaSet: set[char] = {'a'..'c'} -doAssert "{a, b, c}" == $alphaSet +doAssert "{'a', 'b', 'c'}" == $alphaSet doAssert "2.3242" == $(2.3242) doAssert "2.982" == $(2.982) doAssert "123912.1" == $(123912.1) @@ -49,5 +49,5 @@ import strutils # array test let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0'] -doAssert $arr == "[H, e, l, l, o, , W, o, r, l, d, !, \0]" +doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']" doAssert $cstring(unsafeAddr arr) == "Hello World!" diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim new file mode 100644 index 000000000..ce36895a1 --- /dev/null +++ b/tests/system/tsystem_misc.nim @@ -0,0 +1,22 @@ +discard """ + output:"" +""" + +# check high/low implementations +doAssert high(int) > low(int) +doAssert high(int8) > low(int8) +doAssert high(int16) > low(int16) +doAssert high(int32) > low(int32) +doAssert high(int64) > low(int64) +# doAssert high(uint) > low(uint) # reconsider depending on issue #6620 +doAssert high(uint8) > low(uint8) +doAssert high(uint16) > low(uint16) +doAssert high(uint32) > low(uint32) +# doAssert high(uint64) > low(uint64) # reconsider depending on issue #6620 +doAssert high(float) > low(float) +doAssert high(float32) > low(float32) +doAssert high(float64) > low(float64) + +# bug #6710 +var s = @[1] +s.delete(0) diff --git a/tests/test_nimscript.nims b/tests/test_nimscript.nims index 2500bac73..d3eb9808e 100644 --- a/tests/test_nimscript.nims +++ b/tests/test_nimscript.nims @@ -21,5 +21,6 @@ import subexes import tables import unicode import uri +import macros echo "Nimscript imports are successful." diff --git a/tests/testament/backend.nim b/tests/testament/backend.nim index 8f0961566..4acef9ca4 100644 --- a/tests/testament/backend.nim +++ b/tests/testament/backend.nim @@ -1,56 +1,16 @@ # # # The Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # Look at license.txt for more info. # All rights reserved. -import strutils, db_sqlite, os, osproc - -var db: DbConn - -proc createDb() = - db.exec(sql""" - create table if not exists Machine( - id integer primary key, - name varchar(100) not null, - os varchar(20) not null, - cpu varchar(20) not null - );""") - - db.exec(sql""" - create table if not exists [Commit]( - id integer primary key, - hash varchar(256) not null, - branch varchar(50) not null - );""") - - db.exec(sql""" - create table if not exists TestResult( - id integer primary key, - name varchar(100) not null, - category varchar(100) not null, - target varchar(20) not null, - action varchar(10) not null, - result varchar(30) not null, - [commit] int not null, - machine int not null, - expected varchar(10000) not null, - given varchar(10000) not null, - created timestamp not null default (DATETIME('now')), - - foreign key ([commit]) references [commit](id), - foreign key (machine) references machine(id) - );""") - - #db.exec(sql""" - # --create unique index if not exists TsstNameIx on TestResult(name); - # """, []) +import strutils, os, osproc, json type - MachineId* = distinct int64 - CommitId = distinct int64 + MachineId* = distinct string + CommitId = distinct string proc `$`*(id: MachineId): string {.borrow.} proc `$`(id: CommitId): string {.borrow.} @@ -58,11 +18,12 @@ proc `$`(id: CommitId): string {.borrow.} var thisMachine: MachineId thisCommit: CommitId + thisBranch: string {.experimental.} proc `()`(cmd: string{lit}): string = cmd.execProcess.string.strip -proc getMachine*(db: DbConn): MachineId = +proc getMachine*(): MachineId = var name = "hostname"() if name.len == 0: name = when defined(posix): getenv"HOSTNAME".string @@ -70,54 +31,45 @@ proc getMachine*(db: DbConn): MachineId = if name.len == 0: quit "cannot determine the machine name" - let id = db.getValue(sql"select id from Machine where name = ?", name) - if id.len > 0: - result = id.parseInt.MachineId - else: - result = db.insertId(sql"insert into Machine(name, os, cpu) values (?,?,?)", - name, system.hostOS, system.hostCPU).MachineId + result = MachineId(name) -proc getCommit(db: DbConn): CommitId = +proc getCommit(): CommitId = const commLen = "commit ".len let hash = "git log -n 1"()[commLen..commLen+10] - let branch = "git symbolic-ref --short HEAD"() - if hash.len == 0 or branch.len == 0: quit "cannot determine git HEAD" + thisBranch = "git symbolic-ref --short HEAD"() + if hash.len == 0 or thisBranch.len == 0: quit "cannot determine git HEAD" + result = CommitId(hash) - let id = db.getValue(sql"select id from [Commit] where hash = ? and branch = ?", - hash, branch) - if id.len > 0: - result = id.parseInt.CommitId - else: - result = db.insertId(sql"insert into [Commit](hash, branch) values (?, ?)", - hash, branch).CommitId +var + results: File + currentCategory: string + entries: int proc writeTestResult*(name, category, target, action, result, expected, given: string) = - let id = db.getValue(sql"""select id from TestResult - where name = ? and category = ? and target = ? and - machine = ? and [commit] = ?""", - name, category, target, - thisMachine, thisCommit) - if id.len > 0: - db.exec(sql"""update TestResult - set action = ?, result = ?, expected = ?, given = ? - where id = ?""", action, result, expected, given, id) - else: - db.exec(sql"""insert into TestResult(name, category, target, - action, - result, expected, given, - [commit], machine) - values (?,?,?,?,?,?,?,?,?) """, name, category, target, - action, - result, expected, given, - thisCommit, thisMachine) + createDir("testresults") + if currentCategory != category: + if currentCategory.len > 0: + results.writeLine("]") + close(results) + currentCategory = category + results = open("testresults" / category.addFileExt"json", fmWrite) + results.writeLine("[") + entries = 0 + + let jentry = %*{"name": name, "category": category, "target": target, + "action": action, "result": result, "expected": expected, "given": given, + "machine": thisMachine.string, "commit": thisCommit.string, "branch": thisBranch} + if entries > 0: + results.writeLine(",") + results.write($jentry) + inc entries proc open*() = - let dbFile = if existsEnv("TRAVIS") or existsEnv("APPVEYOR"): ":memory:" else: "testament.db" - db = open(connection=dbFile, user="testament", password="", - database="testament") - createDb() - thisMachine = getMachine(db) - thisCommit = getCommit(db) + thisMachine = getMachine() + thisCommit = getCommit() -proc close*() = close(db) +proc close*() = + if currentCategory.len > 0: + results.writeLine("]") + close(results) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index a93c79f5c..33b93e3c4 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -15,58 +15,52 @@ const rodfilesDir = "tests/rodfiles" - nimcacheDir = rodfilesDir / "nimcache" -proc delNimCache() = +proc delNimCache(filename, options: string) = + let dir = nimcacheDir(filename, options) try: - removeDir(nimcacheDir) + removeDir(dir) except OSError: - echo "[Warning] could not delete: ", nimcacheDir + echo "[Warning] could not delete: ", dir proc runRodFiles(r: var TResults, cat: Category, options: string) = - template test(filename: untyped) = + template test(filename: string, clearCacheFirst=false) = + if clearCacheFirst: delNimCache(filename, options) testSpec r, makeTest(rodfilesDir / filename, options, cat, actionRun) - delNimCache() # test basic recompilation scheme: - test "hallo" + test "hallo", true test "hallo" when false: # test incremental type information: test "hallo2" - delNimCache() # test type converters: - test "aconv" + test "aconv", true test "bconv" - delNimCache() # test G, A, B example from the documentation; test init sections: - test "deada" + test "deada", true test "deada2" - delNimCache() when false: # test method generation: - test "bmethods" + test "bmethods", true test "bmethods2" - delNimCache() # test generics: - test "tgeneric1" + test "tgeneric1", true test "tgeneric2" - delNimCache() proc compileRodFiles(r: var TResults, cat: Category, options: string) = - template test(filename: untyped) = + template test(filename: untyped, clearCacheFirst=true) = + if clearCacheFirst: delNimCache(filename, options) testSpec r, makeTest(rodfilesDir / filename, options, cat) - delNimCache() # test DLL interfacing: - test "gtkex1" + test "gtkex1", true test "gtkex2" - delNimCache() # --------------------- DLL generation tests ---------------------------------- @@ -83,9 +77,9 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = "" testSpec c, makeTest("lib/nimrtl.nim", - options & " --app:lib -d:createNimRtl", cat) + options & " --app:lib -d:createNimRtl --threads:on", cat) testSpec c, makeTest("tests/dll/server.nim", - options & " --app:lib -d:useNimRtl" & rpath, cat) + options & " --app:lib -d:useNimRtl --threads:on" & rpath, cat) when defined(Windows): @@ -101,7 +95,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = var nimrtlDll = DynlibFormat % "nimrtl" safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) - testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl" & rpath, + testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl --threads:on" & rpath, cat, actionRun) proc dllTests(r: var TResults, cat: Category, options: string) = @@ -205,7 +199,6 @@ proc ioTests(r: var TResults, cat: Category, options: string) = proc asyncTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = testSpec r, makeTest(filename, options, cat) - testSpec r, makeTest(filename, options & " -d:upcoming", cat) for t in os.walkFiles("tests/async/t*.nim"): test(t) @@ -219,9 +212,9 @@ proc debuggerTests(r: var TResults, cat: Category, options: string) = proc jsTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = testSpec r, makeTest(filename, options & " -d:nodejs", cat, - actionRun, targetJS) + actionRun), targetJS testSpec r, makeTest(filename, options & " -d:nodejs -d:release", cat, - actionRun, targetJS) + actionRun), targetJS for t in os.walkFiles("tests/js/t*.nim"): test(t) @@ -245,10 +238,10 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) = testSpec r, makeTest(filename, options, cat, action) template testJS(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile, targetJS) + testSpec r, makeTest(filename, options, cat, actionCompile), targetJS template testCPP(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile, targetCPP) + testSpec r, makeTest(filename, options, cat, actionCompile), targetCPP let tests = [ "niminaction/Chapter3/ChatApp/src/server", @@ -324,9 +317,10 @@ type PackageFilter = enum pfExtraOnly pfAll +var nimbleDir = getEnv("NIMBLE_DIR").string +if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble" let nimbleExe = findExe("nimble") - nimbleDir = getHomeDir() / ".nimble" packageDir = nimbleDir / "pkgs" packageIndex = nimbleDir / "packages.json" @@ -386,7 +380,7 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) = installStatus = waitForExitEx(installProcess) installProcess.close if installStatus != QuitSuccess: - r.addResult(test, "", "", reInstallFailed) + r.addResult(test, targetC, "", "", reInstallFailed) continue let @@ -395,12 +389,12 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) = buildStatus = waitForExitEx(buildProcess) buildProcess.close if buildStatus != QuitSuccess: - r.addResult(test, "", "", reBuildFailed) - r.addResult(test, "", "", reSuccess) - r.addResult(packageFileTest, "", "", reSuccess) + r.addResult(test, targetC, "", "", reBuildFailed) + r.addResult(test, targetC, "", "", reSuccess) + r.addResult(packageFileTest, targetC, "", "", reSuccess) except JsonParsingError: echo("[Warning] - Cannot run nimble tests: Invalid package file.") - r.addResult(packageFileTest, "", "", reBuildFailed) + r.addResult(packageFileTest, targetC, "", "", reBuildFailed) # ---------------------------------------------------------------------------- @@ -417,8 +411,9 @@ proc `&?.`(a, b: string): string = proc processSingleTest(r: var TResults, cat: Category, options, test: string) = let test = "tests" & DirSep &.? cat.string / test + let target = if cat.string.normalize == "js": targetJS else: targetC - if existsFile(test): testSpec r, makeTest(test, options, cat) + if existsFile(test): testSpec r, makeTest(test, options, cat), target else: echo "[Warning] - ", test, " test does not exist" proc processCategory(r: var TResults, cat: Category, options: string) = diff --git a/tests/testament/css/boilerplate.css b/tests/testament/css/boilerplate.css deleted file mode 100644 index b209b5aa1..000000000 --- a/tests/testament/css/boilerplate.css +++ /dev/null @@ -1,138 +0,0 @@ -/* ==== Scroll down to find where to put your styles :) ==== */ - -/* HTML5 ✰ Boilerplate */ - -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} - -blockquote, q { quotes: none; } -blockquote:before, blockquote:after, -q:before, q:after { content: ''; content: none; } -ins { background-color: #ff9; color: #000; text-decoration: none; } -mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } -del { text-decoration: line-through; } -abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } -table { border-collapse: collapse; border-spacing: 0; } -hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } -input, select { vertical-align: middle; } - -body { font:13px/1.231 sans-serif; *font-size:small; } -select, input, textarea, button { font:99% sans-serif; } -pre, code, kbd, samp { font-family: monospace, sans-serif; } - -html { overflow-y: scroll; } -a:hover, a:active { outline: none; } -ul, ol { margin-left: 2em; } -ol { list-style-type: decimal; } -nav ul, nav li { margin: 0; list-style:none; list-style-image: none; } -small { font-size: 85%; } -strong, th { font-weight: bold; } -td { vertical-align: top; } - -sub, sup { font-size: 75%; line-height: 0; position: relative; } -sup { top: -0.5em; } -sub { bottom: -0.25em; } - -pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 15px; } -textarea { overflow: auto; } -.ie6 legend, .ie7 legend { margin-left: -7px; } -input[type="radio"] { vertical-align: text-bottom; } -input[type="checkbox"] { vertical-align: bottom; } -.ie7 input[type="checkbox"] { vertical-align: baseline; } -.ie6 input { vertical-align: text-bottom; } -label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; } -button, input, select, textarea { margin: 0; } -input:valid, textarea:valid { } -input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; } -.no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; } - -a:link { -webkit-tap-highlight-color: #FF5E99; } - -button { width: auto; overflow: visible; } -.ie7 img { -ms-interpolation-mode: bicubic; } - -body, select, input, textarea { color: #444; } -h1, h2, h3, h4, h5, h6 { font-weight: bold; } -a, a:active, a:visited { color: #607890; } -a:hover { color: #036; } - -/* - // ========================================== \\ - || || - || Your styles ! || - || || - \\ ========================================== // -*/ - - - - - - - - - - - - - - - -.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; } -.hidden { display: none; visibility: hidden; } -.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } -.visuallyhidden.focusable:active, -.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; } -.invisible { visibility: hidden; } -.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } -.clearfix:after { clear: both; } -.clearfix { zoom: 1; } - - -@media all and (orientation:portrait) { - -} - -@media all and (orientation:landscape) { - -} - -@media screen and (max-device-width: 480px) { - - /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ -} - - -@media print { - * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; - -ms-filter: none !important; } - a, a:visited { color: #444 !important; text-decoration: underline; } - a[href]:after { content: " (" attr(href) ")"; } - abbr[title]:after { content: " (" attr(title) ")"; } - .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } - pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } - thead { display: table-header-group; } - tr, img { page-break-inside: avoid; } - @page { margin: 0.5cm; } - p, h2, h3 { orphans: 3; widows: 3; } - h2, h3{ page-break-after: avoid; } -} diff --git a/tests/testament/css/style.css b/tests/testament/css/style.css deleted file mode 100644 index 43a8add68..000000000 --- a/tests/testament/css/style.css +++ /dev/null @@ -1,114 +0,0 @@ -body { - font-size: medium; -} - -div#header { - font-size: 2em; - background-color: #3d3d3d; - border-bottom: solid 2px #000000; - padding: 0.25em; - color: #ffffff; -} - -div#content { - margin: 0.5em; -} - -table { - text-align: left; - margin-bottom: 0.5em; -} - -table td, table th { - padding: 0.15em 0.5em; -} - -tr:nth-child(even) { - background-color: #eee; -} - -/* Awesome buttons :P */ - -a.button { - border-radius: 2px 2px 2px 2px; - background: -moz-linear-gradient(top, #f7f7f7, #ebebeb); - background: -webkit-linear-gradient(top, #f7f7f7, #ebebeb); - background: -o-linear-gradient(top, #f7f7f7, #ebebeb); - text-decoration: none; - color: #3d3d3d; - padding: 5px; - border: solid 1px #9d9d9d; - display: inline-block; - position: relative; - text-align: center; - font-size: small; -} - -a.button.active { - background: -moz-linear-gradient(top, #00B40C, #03A90E); - background: -webkit-linear-gradient(top, #00B40C, #03A90E); - background: -o-linear-gradient(top, #00B40C, #03A90E); - border: solid 1px #148420; - color: #ffffff; -} - -a.button.left { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -a.button.middle { - border-radius: 0; - border-left: 0; -} - -a.button.right { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left: 0; -} - -a.button:hover { - background: -moz-linear-gradient(top, #0099c7, #0294C1); - background: -webkit-linear-gradient(top, #0099c7, #0294C1); - background: -o-linear-gradient(top, #0099c7, #0294C1); - border: solid 1px #077A9C; - color: #ffffff; -} - -a.button.middle:hover, a.button.right:hover { - border-left: 0; -} - -a.button span.download { - background-image: url("../images/icons.png"); - background-repeat: no-repeat; - display: inline-block; - margin: auto 3px auto auto; - height: 15px; - width: 14px; - position: relative; - background-position: 0 -30px; - top: 3px; -} - -a.button span.book { - background-image: url("../images/icons.png"); - background-repeat: no-repeat; - display: inline-block; - margin: auto 3px auto auto; - height: 15px; - width: 14px; - position: relative; - background-position: 0 0; - top: 3px; -} - -a.button.active span.download, a.button:hover span.download { - background-position: 0 -45px; -} - -a.button.active span.book, a.button:hover span.book { - background-position: 0 -15px; -} - diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim index 15960f09a..bf26a956d 100644 --- a/tests/testament/htmlgen.nim +++ b/tests/testament/htmlgen.nim @@ -1,7 +1,7 @@ # # # Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,220 +9,140 @@ ## HTML generator for the tester. -import db_sqlite, cgi, backend, strutils, json - -const - TableHeader = """<table border="1"> - <tr><td>Test</td><td>Category</td><td>Target</td> - <td>Action</td> - <td>Expected</td> - <td>Given</td> - <td>Success</td></tr>""" - TableFooter = "</table>" - HtmlBegin = """<html> - <head> - <title>Test results</title> - <style type="text/css"> - <!--""" & slurp("css/boilerplate.css") & "\n" & - slurp("css/style.css") & - """ -ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; } -ul#tabs li { display: inline; } -ul#tabs li a { color: #42454a; background-color: #dedbde; - border: 1px solid #c9c3ba; border-bottom: none; - padding: 0.3em; text-decoration: none; } -ul#tabs li a:hover { background-color: #f1f0ee; } -ul#tabs li a.selected { color: #000; background-color: #f1f0ee; - font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; } -div.tabContent { border: 1px solid #c9c3ba; - padding: 0.5em; background-color: #f1f0ee; } -div.tabContent.hide { display: none; } - --> - </style> - <script> - - var tabLinks = new Array(); - var contentDivs = new Array(); - - function init() { - // Grab the tab links and content divs from the page - var tabListItems = document.getElementById('tabs').childNodes; - for (var i = 0; i < tabListItems.length; i++) { - if (tabListItems[i].nodeName == "LI") { - var tabLink = getFirstChildWithTagName(tabListItems[i], 'A'); - var id = getHash(tabLink.getAttribute('href')); - tabLinks[id] = tabLink; - contentDivs[id] = document.getElementById(id); - } - } - // Assign onclick events to the tab links, and - // highlight the first tab - var i = 0; - for (var id in tabLinks) { - tabLinks[id].onclick = showTab; - tabLinks[id].onfocus = function() { this.blur() }; - if (i == 0) tabLinks[id].className = 'selected'; - i++; - } - // Hide all content divs except the first - var i = 0; - for (var id in contentDivs) { - if (i != 0) contentDivs[id].className = 'tabContent hide'; - i++; - } - } - - function showTab() { - var selectedId = getHash(this.getAttribute('href')); - - // Highlight the selected tab, and dim all others. - // Also show the selected content div, and hide all others. - for (var id in contentDivs) { - if (id == selectedId) { - tabLinks[id].className = 'selected'; - contentDivs[id].className = 'tabContent'; - } else { - tabLinks[id].className = ''; - contentDivs[id].className = 'tabContent hide'; - } - } - // Stop the browser following the link - return false; - } - - function getFirstChildWithTagName(element, tagName) { - for (var i = 0; i < element.childNodes.length; i++) { - if (element.childNodes[i].nodeName == tagName) return element.childNodes[i]; - } - } - function getHash(url) { - var hashPos = url.lastIndexOf('#'); - return url.substring(hashPos + 1); - } - </script> - - </head> - <body onload="init()">""" - - HtmlEnd = "</body></html>" - -proc td(s: string): string = - result = "<td>" & s.substr(0, 200).xmlEncode & "</td>" - -proc getCommit(db: DbConn, c: int): string = - var commit = c - for thisCommit in db.rows(sql"select id from [Commit] order by id desc"): - if commit == 0: result = thisCommit[0] - inc commit - -proc generateHtml*(filename: string, commit: int; onlyFailing: bool) = - const selRow = """select name, category, target, action, - expected, given, result - from TestResult - where [commit] = ? and machine = ? - order by category""" - var db = open(connection="testament.db", user="testament", password="", - database="testament") - # search for proper commit: - let lastCommit = db.getCommit(commit) - +import cgi, backend, strutils, json, os, tables, times + +import "testamenthtml.templ" + +proc generateTestResultPanelPartial(outfile: File, testResultRow: JsonNode) = + let + trId = htmlQuote(testResultRow["category"].str & "_" & testResultRow["name"].str). + multiReplace({".": "_", " ": "_", ":": "_"}) + name = testResultRow["name"].str.htmlQuote() + category = testResultRow["category"].str.htmlQuote() + target = testResultRow["target"].str.htmlQuote() + action = testResultRow["action"].str.htmlQuote() + result = htmlQuote testResultRow["result"].str + expected = testResultRow["expected"].str + gotten = testResultRow["given"].str + timestamp = "unknown" + var + panelCtxClass, textCtxClass, bgCtxClass: string + resultSign, resultDescription: string + case result + of "reSuccess": + panelCtxClass = "success" + textCtxClass = "success" + bgCtxClass = "success" + resultSign = "ok" + resultDescription = "PASS" + of "reIgnored": + panelCtxClass = "info" + textCtxClass = "info" + bgCtxClass = "info" + resultSign = "question" + resultDescription = "SKIP" + else: + panelCtxClass = "danger" + textCtxClass = "danger" + bgCtxClass = "danger" + resultSign = "exclamation" + resultDescription = "FAIL" + + outfile.generateHtmlTestresultPanelBegin( + trId, name, target, category, action, resultDescription, + timestamp, result, resultSign, panelCtxClass, textCtxClass, bgCtxClass + ) + if expected.isNilOrWhitespace() and gotten.isNilOrWhitespace(): + outfile.generateHtmlTestresultOutputNone() + else: + outfile.generateHtmlTestresultOutputDetails( + expected.strip().htmlQuote, + gotten.strip().htmlQuote + ) + outfile.generateHtmlTestresultPanelEnd() + +type + AllTests = object + data: JSonNode + totalCount, successCount, ignoredCount, failedCount: int + successPercentage, ignoredPercentage, failedPercentage: BiggestFloat + +proc allTestResults(onlyFailing = false): AllTests = + result.data = newJArray() + for file in os.walkFiles("testresults/*.json"): + let data = parseFile(file) + if data.kind != JArray: + echo "[ERROR] ignoring json file that is not an array: ", file + else: + for elem in data: + let state = elem["result"].str + inc result.totalCount + if state.contains("reSuccess"): inc result.successCount + elif state.contains("reIgnored"): inc result.ignoredCount + if not onlyFailing or not(state.contains("reSuccess")): + result.data.add elem + result.successPercentage = 100 * + (result.successCount.toBiggestFloat / result.totalCount.toBiggestFloat) + result.ignoredPercentage = 100 * + (result.ignoredCount.toBiggestFloat / result.totalCount.toBiggestFloat) + result.failedCount = result.totalCount - + result.successCount - result.ignoredCount + result.failedPercentage = 100 * + (result.failedCount.toBiggestFloat / result.totalCount.toBiggestFloat) + +proc generateTestResultsPanelGroupPartial(outfile: File, allResults: JsonNode) = + for testresultRow in allResults: + generateTestResultPanelPartial(outfile, testresultRow) + +proc generateAllTestsContent(outfile: File, allResults: AllTests, + onlyFailing = false) = + if allResults.data.len < 1: return # Nothing to do if there is no data. + # Only results from one test run means that test run environment info is the + # same for all tests + let + firstRow = allResults.data[0] + commit = htmlQuote firstRow["commit"].str + branch = htmlQuote firstRow["branch"].str + machine = htmlQuote firstRow["machine"].str + + outfile.generateHtmlAllTestsBegin( + machine, commit, branch, + allResults.totalCount, + allResults.successCount, + formatBiggestFloat(allResults.successPercentage, ffDecimal, 2) & "%", + allResults.ignoredCount, + formatBiggestFloat(allResults.ignoredPercentage, ffDecimal, 2) & "%", + allResults.failedCount, + formatBiggestFloat(allResults.failedPercentage, ffDecimal, 2) & "%", + onlyFailing + ) + generateTestResultsPanelGroupPartial(outfile, allResults.data) + outfile.generateHtmlAllTestsEnd() + +proc generateHtml*(filename: string, onlyFailing: bool) = + let + currentTime = getTime().getLocalTime() + timestring = htmlQuote format(currentTime, "yyyy-MM-dd HH:mm:ss 'UTC'zzz") var outfile = open(filename, fmWrite) - outfile.write(HtmlBegin) - - let commit = db.getValue(sql"select hash from [Commit] where id = ?", - lastCommit) - let branch = db.getValue(sql"select branch from [Commit] where id = ?", - lastCommit) - outfile.write("<p><b>$# $#</b></p>" % [branch, commit]) - - # generate navigation: - outfile.write("""<ul id="tabs">""") - for m in db.rows(sql"select id, name, os, cpu from Machine order by id"): - outfile.writeLine """<li><a href="#$#">$#: $#, $#</a></li>""" % m - outfile.write("</ul>") - - for currentMachine in db.rows(sql"select id from Machine order by id"): - let m = currentMachine[0] - outfile.write("""<div class="tabContent" id="$#">""" % m) - - outfile.write(TableHeader) - for row in db.rows(sql(selRow), lastCommit, m): - if onlyFailing and row.len > 0 and row[row.high] == "reSuccess": - discard - else: - outfile.write("<tr>") - for x in row: - outfile.write(x.td) - outfile.write("</tr>") - - outfile.write(TableFooter) - outfile.write("</div>") - outfile.write(HtmlEnd) - close(db) - close(outfile) -proc generateJson*(filename: string, commit: int) = - const - selRow = """select count(*), - sum(result = 'reSuccess'), - sum(result = 'reIgnored') - from TestResult - where [commit] = ? and machine = ? - order by category""" - selDiff = """select A.category || '/' || A.target || '/' || A.name, - A.result, - B.result - from TestResult A - inner join TestResult B - on A.name = B.name and A.category = B.category - where A.[commit] = ? and B.[commit] = ? and A.machine = ? - and A.result != B.result""" - selResults = """select - category || '/' || target || '/' || name, - category, target, action, result, expected, given - from TestResult - where [commit] = ?""" - var db = open(connection="testament.db", user="testament", password="", - database="testament") - let lastCommit = db.getCommit(commit) - if lastCommit.isNil: - quit "cannot determine commit " & $commit - - let previousCommit = db.getCommit(commit-1) + outfile.generateHtmlBegin() - var outfile = open(filename, fmWrite) + generateAllTestsContent(outfile, allTestResults(onlyFailing), onlyFailing) + + outfile.generateHtmlEnd(timestring) - let machine = $backend.getMachine(db) - let data = db.getRow(sql(selRow), lastCommit, machine) - - outfile.writeLine("""{"total": $#, "passed": $#, "skipped": $#""" % data) - - let results = newJArray() - for row in db.rows(sql(selResults), lastCommit): - var obj = newJObject() - obj["name"] = %row[0] - obj["category"] = %row[1] - obj["target"] = %row[2] - obj["action"] = %row[3] - obj["result"] = %row[4] - obj["expected"] = %row[5] - obj["given"] = %row[6] - results.add(obj) - outfile.writeLine(""", "results": """) - outfile.write(results.pretty) - - if not previousCommit.isNil: - let diff = newJArray() - - for row in db.rows(sql(selDiff), previousCommit, lastCommit, machine): - var obj = newJObject() - obj["name"] = %row[0] - obj["old"] = %row[1] - obj["new"] = %row[2] - diff.add obj - outfile.writeLine(""", "diff": """) - outfile.writeLine(diff.pretty) - - outfile.writeLine "}" - close(db) + outfile.flushFile() close(outfile) + +proc dumpJsonTestResults*(prettyPrint, onlyFailing: bool) = + var + outfile = stdout + jsonString: string + + let results = allTestResults(onlyFailing) + if prettyPrint: + jsonString = results.data.pretty() + else: + jsonString = $ results.data + + outfile.writeLine(jsonString) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index 89e786d48..ac79e3942 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -12,6 +12,9 @@ import parseutils, strutils, os, osproc, streams, parsecfg var compilerPrefix* = "compiler" / "nim " +let isTravis = existsEnv("TRAVIS") +let isAppVeyor = existsEnv("APPVEYOR") + proc cmdTemplate*(): string = compilerPrefix & "$target --lib:lib --hints:on -d:testing $options $file" @@ -113,7 +116,7 @@ proc specDefaults*(result: var TSpec) = result.maxCodeSize = 0 proc parseTargets*(value: string): set[TTarget] = - for v in value.normalize.split: + for v in value.normalize.splitWhitespace: case v of "c": result.incl(targetC) of "cpp", "c++": result.incl(targetCpp) @@ -149,6 +152,7 @@ proc parseSpec*(filename: string): TSpec = result.sortoutput = parseCfgBool(e.value) of "exitcode": discard parseInt(e.value, result.exitCode) + result.action = actionRun of "msg": result.msg = e.value if result.action != actionRun: @@ -174,6 +178,10 @@ proc parseSpec*(filename: string): TSpec = when defined(unix): result.err = reIgnored of "posix": when defined(posix): result.err = reIgnored + of "travis": + if isTravis: result.err = reIgnored + of "appveyor": + if isAppVeyor: result.err = reIgnored else: raise newException(ValueError, "cannot interpret as a bool: " & e.value) of "cmd": @@ -184,7 +192,7 @@ proc parseSpec*(filename: string): TSpec = of "ccodecheck": result.ccodeCheck = e.value of "maxcodesize": discard parseInt(e.value, result.maxCodeSize) of "target", "targets": - for v in e.value.normalize.split: + for v in e.value.normalize.splitWhitespace: case v of "c": result.targets.incl(targetC) of "cpp", "c++": result.targets.incl(targetCpp) diff --git a/tests/testament/testamenthtml.templ b/tests/testament/testamenthtml.templ new file mode 100644 index 000000000..9190f370e --- /dev/null +++ b/tests/testament/testamenthtml.templ @@ -0,0 +1,297 @@ +#? stdtmpl(subsChar = '%', metaChar = '#', emit = "outfile.write") +#import strutils +# +#proc htmlQuote*(raw: string): string = +# result = raw.multiReplace( +# ("&", "&"), +# ("\"", """), +# ("'", "'"), +# ("<", "<"), +# (">", ">") +# ) +# +#end proc +#proc generateHtmlBegin*(outfile: File) = +<!DOCTYPE html> +<html> +<head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Testament Test Results</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js" integrity="sha256-ihAoc6M/JPfrIiIeayPE9xjin4UWjsx2mjW/rtmxLM4=" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></script> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=" crossorigin="anonymous" /> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha256-ZT4HPpdCOt2lvDkXokHuhJfdOKSPFLzeAJik5U/Q+l4=" crossorigin="anonymous" /> + <script> + /** + * Callback function that is executed for each Element in an array. + * @callback executeForElement + * @param {Element} elem Element to operate on + */ + + /** + * + * @param {number} index + * @param {Element[]} elemArray + * @param {executeForElement} executeOnItem + */ + function executeAllAsync(elemArray, index, executeOnItem) { + for (var i = 0; index < elemArray.length && i < 100; i++ , index++) { + var item = elemArray[index]; + executeOnItem(item); + } + if (index < elemArray.length) { + setTimeout(executeAllAsync, 0, elemArray, index, executeOnItem); + } + } + + /** @param {Element} elem */ + function executeShowOnElement(elem) { + while (elem.classList.contains("hidden")) { + elem.classList.remove("hidden"); + } + } + + /** @param {Element} elem */ + function executeHideOnElement(elem) { + if (!elem.classList.contains("hidden")) { + elem.classList.add("hidden"); + } + } + + /** @param {Element} elem */ + function executeExpandOnElement(elem) { + $(elem).collapse("show"); + } + + /** @param {Element} elem */ + function executeCollapseOnElement(elem) { + $(elem).collapse("hide"); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + * @param {executeForElement} executeOnEachPanel + */ + function wholePanelAll(category, executeOnEachPanel) { + var selector = "div.panel"; + if (typeof category === "string" && category) { + selector += "-" + category; + } + + var jqPanels = $(selector); + /** @type {Element[]} */ + var elemArray = jqPanels.toArray(); + + setTimeout(executeAllAsync, 0, elemArray, 0, executeOnEachPanel); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + * @param {executeForElement} executeOnEachPanel + */ + function panelBodyAll(category, executeOnEachPanelBody) { + var selector = "div.panel"; + if (typeof category === "string" && category) { + selector += "-" + category; + } + + var jqPanels = $(selector); + + var jqPanelBodies = $("div.panel-body", jqPanels); + /** @type {Element[]} */ + var elemArray = jqPanelBodies.toArray(); + + setTimeout(executeAllAsync, 0, elemArray, 0, executeOnEachPanelBody); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function showAll(category) { + wholePanelAll(category, executeShowOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function hideAll(category) { + wholePanelAll(category, executeHideOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function expandAll(category) { + panelBodyAll(category, executeExpandOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function collapseAll(category) { + panelBodyAll(category, executeCollapseOnElement); + } + </script> +</head> +<body> + <div class="container"> + <h1>Testament Test Results <small>Nim Tester</small></h1> +#end proc +#proc generateHtmlAllTestsBegin*(outfile: File, machine, commit, branch: string, +# totalCount: BiggestInt, +# successCount: BiggestInt, successPercentage: string, +# ignoredCount: BiggestInt, ignoredPercentage: string, +# failedCount: BiggestInt, failedPercentage: string, onlyFailing = false) = + <dl class="dl-horizontal"> + <dt>Hostname</dt> + <dd>%machine</dd> + <dt>Git Commit</dt> + <dd><code>%commit</code></dd> + <dt title="Git Branch reference">Branch ref.</dt> + <dd>%branch</dd> + </dl> + <dl class="dl-horizontal"> + <dt>All Tests</dt> + <dd> + <span class="glyphicon glyphicon-th-list"></span> + %totalCount + </dd> + <dt>Successful Tests</dt> + <dd> + <span class="glyphicon glyphicon-ok-sign"></span> + %successCount (%successPercentage) + </dd> + <dt>Skipped Tests</dt> + <dd> + <span class="glyphicon glyphicon-question-sign"></span> + %ignoredCount (%ignoredPercentage) + </dd> + <dt>Failed Tests</dt> + <dd> + <span class="glyphicon glyphicon-exclamation-sign"></span> + %failedCount (%failedPercentage) + </dd> + </dl> + <div class="table-responsive"> + <table class="table table-condensed"> +# if not onlyFailing: + <tr> + <th class="text-right" style="vertical-align:middle">All Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll();">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll();">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll();">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll();">Collapse All</button> + </div> + </td> + </tr> + <tr> + <th class="text-right" style="vertical-align:middle">Successful Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('success');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('success');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('success');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('success');">Collapse All</button> + </div> + </td> + </tr> +# end if + <tr> + <th class="text-right" style="vertical-align:middle">Skipped Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('info');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('info');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('info');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('info');">Collapse All</button> + </div> + </td> + </tr> + <tr> + <th class="text-right" style="vertical-align:middle">Failed Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('danger');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('danger');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('danger');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('danger');">Collapse All</button> + </div> + </td> + </tr> + </table> + </div> + <div class="panel-group"> +#end proc +#proc generateHtmlTestresultPanelBegin*(outfile: File, trId, name, target, category, +# action, resultDescription, timestamp, result, resultSign, +# panelCtxClass, textCtxClass, bgCtxClass: string) = + <div id="panel-testResult-%trId" class="panel panel-%panelCtxClass"> + <div class="panel-heading" style="cursor:pointer" data-toggle="collapse" data-target="#panel-body-testResult-%trId" aria-controls="panel-body-testResult-%trId" aria-expanded="false"> + <div class="row"> + <h4 class="col-xs-3 col-sm-1 panel-title"> + <span class="glyphicon glyphicon-%resultSign-sign"></span> + <strong>%resultDescription</strong> + </h4> + <h4 class="col-xs-1 panel-title"><span class="badge">%target</span></h4> + <h4 class="col-xs-5 col-sm-7 panel-title" title="%name"><code class="text-%textCtxClass">%name</code></h4> + <h4 class="col-xs-3 col-sm-3 panel-title text-right"><span class="badge">%category</span></h4> + </div> + </div> + <div id="panel-body-testResult-%trId" class="panel-body collapse bg-%bgCtxClass"> + <dl class="dl-horizontal"> + <dt>Name</dt> + <dd><code class="text-%textCtxClass">%name</code></dd> + <dt>Category</dt> + <dd><span class="badge">%category</span></dd> + <dt>Timestamp</dt> + <dd>%timestamp</dd> + <dt>Nim Action</dt> + <dd><code class="text-%textCtxClass">%action</code></dd> + <dt>Nim Backend Target</dt> + <dd><span class="badge">%target</span></dd> + <dt>Code</dt> + <dd><code class="text-%textCtxClass">%result</code></dd> + </dl> +#end proc +#proc generateHtmlTestresultOutputDetails*(outfile: File, expected, gotten: string) = + <div class="table-responsive"> + <table class="table table-condensed"> + <thead> + <tr> + <th>Expected</th> + <th>Actual</th> + </tr> + </thead> + <tbody> + <tr> + <td><pre>%expected</pre></td> + <td><pre>%gotten</pre></td> + </tr> + </tbody> + </table> + </div> +#end proc +#proc generateHtmlTestresultOutputNone*(outfile: File) = + <p class="sr-only">No output details</p> +#end proc +#proc generateHtmlTestresultPanelEnd*(outfile: File) = + </div> + </div> +#end proc +#proc generateHtmlAllTestsEnd*(outfile: File) = + </div> +#end proc +#proc generateHtmlEnd*(outfile: File, timestamp: string) = + <hr /> + <footer> + <p> + Report generated by: <code>testament</code> – Nim Tester + <br /> + Made with Nim. Generated on: %timestamp + </p> + </footer> + </div> +</body> +</html> diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index e4bbc3a00..870f9f865 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -1,7 +1,7 @@ # # # Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -12,7 +12,7 @@ import parseutils, strutils, pegs, os, osproc, streams, parsecfg, json, marshal, backend, parseopt, specs, htmlgen, browsers, terminal, - algorithm, compiler/nodejs, re, times, sets + algorithm, compiler/nodejs, times, sets, md5 const resultsFile = "testresults.html" @@ -24,15 +24,12 @@ Command: all run all tests c|category <category> run all the tests of a certain category r|run <test> run single test file - html [commit] generate $1 from the database; uses the latest - commit or a specific one (use -1 for the commit - before latest etc) + html generate $1 from the database Arguments: arguments are passed to the compiler Options: --print also print results to the console --failing only show failing/ignored tests - --pedantic return non-zero status code if there are failures --targets:"c c++ js objc" run tests for specified targets (default: all) --nim:path use a particular nim executable (default: compiler/nim) """ % resultsFile @@ -47,7 +44,6 @@ type name: string cat: Category options: string - target: TTarget action: TTestAction startTime: float @@ -75,8 +71,14 @@ proc getFileDir(filename: string): string = if not result.isAbsolute(): result = getCurrentDir() / result +proc nimcacheDir(filename, options: string): string = + ## Give each test a private nimcache dir so they don't clobber each other's. + return "nimcache" / (filename & '_' & options.getMD5) + proc callCompiler(cmdTemplate, filename, options: string, - target: TTarget): TSpec = + target: TTarget, extraOptions=""): TSpec = + let nimcache = nimcacheDir(filename, options) + let options = options & " --nimCache:" & nimcache.quoteShell & extraOptions let c = parseCmdLine(cmdTemplate % ["target", targetToCmd[target], "options", options, "file", filename.quoteShell, "filedir", filename.getFileDir()]) @@ -158,20 +160,21 @@ proc `$`(x: TResults): string = "Tests skipped: $2 / $3 <br />\n") % [$x.passed, $x.skipped, $x.total] -proc addResult(r: var TResults, test: TTest, +proc addResult(r: var TResults, test: TTest, target: TTarget, expected, given: string, success: TResultEnum) = - let name = test.name.extractFilename & test.options + let name = test.name.extractFilename & " " & $target & test.options let duration = epochTime() - test.startTime + let durationStr = duration.formatFloat(ffDecimal, precision = 8) backend.writeTestResult(name = name, category = test.cat.string, - target = $test.target, + target = $target, action = $test.action, result = $success, expected = expected, given = given) r.data.addf("$#\t$#\t$#\t$#", name, expected, given, $success) if success == reSuccess: - styledEcho fgGreen, "PASS: ", fgCyan, name + styledEcho fgGreen, "PASS: ", fgCyan, alignLeft(name, 60), fgBlue, " (", durationStr, " secs)" elif success == reIgnored: styledEcho styleDim, fgYellow, "SKIP: ", styleBright, fgCyan, name else: @@ -191,49 +194,54 @@ proc addResult(r: var TResults, test: TTest, ("Skipped", "") else: ("Failed", "Failure: " & $success & "\nExpected:\n" & expected & "\n\n" & "Gotten:\n" & given) - var p = startProcess("appveyor", args=["AddTest", test.name.replace("\\", "/") & test.options, "-Framework", "nim-testament", "-FileName", test.cat.string, "-Outcome", outcome, "-ErrorMessage", msg, "-Duration", $(duration*1000).int], options={poStdErrToStdOut, poUsePath, poParentStreams}) + var p = startProcess("appveyor", args=["AddTest", test.name.replace("\\", "/") & test.options, + "-Framework", "nim-testament", "-FileName", + test.cat.string, + "-Outcome", outcome, "-ErrorMessage", msg, + "-Duration", $(duration*1000).int], + options={poStdErrToStdOut, poUsePath, poParentStreams}) discard waitForExit(p) close(p) -proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) = +proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest, target: TTarget) = if strip(expected.msg) notin strip(given.msg): - r.addResult(test, expected.msg, given.msg, reMsgsDiffer) + r.addResult(test, target, expected.msg, given.msg, reMsgsDiffer) elif expected.nimout.len > 0 and expected.nimout.normalizeMsg notin given.nimout.normalizeMsg: - r.addResult(test, expected.nimout, given.nimout, reMsgsDiffer) + r.addResult(test, target, expected.nimout, given.nimout, reMsgsDiffer) elif expected.tfile == "" and extractFilename(expected.file) != extractFilename(given.file) and "internal error:" notin expected.msg: - r.addResult(test, expected.file, given.file, reFilesDiffer) + r.addResult(test, target, expected.file, given.file, reFilesDiffer) elif expected.line != given.line and expected.line != 0 or expected.column != given.column and expected.column != 0: - r.addResult(test, $expected.line & ':' & $expected.column, + r.addResult(test, target, $expected.line & ':' & $expected.column, $given.line & ':' & $given.column, reLinesDiffer) elif expected.tfile != "" and extractFilename(expected.tfile) != extractFilename(given.tfile) and "internal error:" notin expected.msg: - r.addResult(test, expected.tfile, given.tfile, reFilesDiffer) + r.addResult(test, target, expected.tfile, given.tfile, reFilesDiffer) elif expected.tline != given.tline and expected.tline != 0 or expected.tcolumn != given.tcolumn and expected.tcolumn != 0: - r.addResult(test, $expected.tline & ':' & $expected.tcolumn, + r.addResult(test, target, $expected.tline & ':' & $expected.tcolumn, $given.tline & ':' & $given.tcolumn, reLinesDiffer) else: - r.addResult(test, expected.msg, given.msg, reSuccess) + r.addResult(test, target, expected.msg, given.msg, reSuccess) inc(r.passed) -proc generatedFile(path, name: string, target: TTarget): string = +proc generatedFile(test: TTest, target: TTarget): string = + let (_, name, _) = test.name.splitFile let ext = targetToExt[target] - result = path / "nimcache" / + result = nimcacheDir(test.name, test.options) / (if target == targetJS: "" else: "compiler_") & name.changeFileExt(ext) proc needsCodegenCheck(spec: TSpec): bool = result = spec.maxCodeSize > 0 or spec.ccodeCheck.len > 0 -proc codegenCheck(test: TTest, spec: TSpec, expectedMsg: var string, +proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var string, given: var TSpec) = try: - let (path, name, _) = test.name.splitFile - let genFile = generatedFile(path, name, test.target) + let genFile = generatedFile(test, target) let contents = readFile(genFile).string let check = spec.ccodeCheck if check.len > 0: @@ -265,13 +273,13 @@ proc makeDeterministic(s: string): string = sort(x, system.cmp) result = join(x, "\n") -proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; - r: var TResults) = +proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec, + expected: TSpec; r: var TResults) = var expectedmsg: string = "" var givenmsg: string = "" if given.err == reSuccess: if expected.needsCodegenCheck: - codegenCheck(test, expected, expectedmsg, given) + codegenCheck(test, target, expected, expectedmsg, given) givenmsg = given.msg if expected.nimout.len > 0: expectedmsg = expected.nimout @@ -280,29 +288,9 @@ proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; else: givenmsg = given.nimout.strip if given.err == reSuccess: inc(r.passed) - r.addResult(test, expectedmsg, givenmsg, given.err) - -proc analyzeAndConsolidateOutput(s: string): string = - result = "" - let rows = s.splitLines - for i in 0 ..< rows.len: - if (let pos = find(rows[i], "Traceback (most recent call last)"); pos != -1): - result = substr(rows[i], pos) & "\n" - for i in i+1 ..< rows.len: - result.add rows[i] & "\n" - if not (rows[i] =~ re"^[^(]+\(\d+\)\s+"): - return - elif (let pos = find(rows[i], "SIGSEGV: Illegal storage access."); pos != -1): - result = substr(rows[i], pos) - return - -proc testSpec(r: var TResults, test: TTest) = - # major entry point for a single test - if test.target notin targets: - r.addResult(test, "", "", reIgnored) - inc(r.skipped) - return + r.addResult(test, target, expectedmsg, givenmsg, given.err) +proc testSpec(r: var TResults, test: TTest, target = targetC) = let tname = test.name.addFileExt(".nim") #echo "TESTING ", tname inc(r.total) @@ -314,83 +302,90 @@ proc testSpec(r: var TResults, test: TTest) = expected.action = actionRunNoSpec if expected.err == reIgnored: - r.addResult(test, "", "", reIgnored) + r.addResult(test, target, "", "", reIgnored) inc(r.skipped) return - case expected.action - of actionCompile: - var given = callCompiler(expected.cmd, test.name, - test.options & " --stdout --hint[Path]:off --hint[Processing]:off", - test.target) - compilerOutputTests(test, given, expected, r) - of actionRun, actionRunNoSpec: - # In this branch of code "early return" pattern is clearer than deep - # nested conditionals - the empty rows in between to clarify the "danger" - var given = callCompiler(expected.cmd, test.name, test.options, - test.target) - - if given.err != reSuccess: - r.addResult(test, "", given.msg, given.err) - return - - let isJsTarget = test.target == targetJS - var exeFile: string - if isJsTarget: - let (dir, file, _) = splitFile(tname) - exeFile = dir / "nimcache" / file & ".js" # *TODO* hardcoded "nimcache" - else: - exeFile = changeFileExt(tname, ExeExt) - - if not existsFile(exeFile): - r.addResult(test, expected.outp, "executable not found", reExeNotFound) - return - - let nodejs = if isJsTarget: findNodeJs() else: "" - if isJsTarget and nodejs == "": - r.addResult(test, expected.outp, "nodejs binary not in PATH", - reExeNotFound) - return - - let exeCmd = (if isJsTarget: nodejs & " " else: "") & exeFile - var (buf, exitCode) = execCmdEx(exeCmd, options = {poStdErrToStdOut}) - - # Treat all failure codes from nodejs as 1. Older versions of nodejs used - # to return other codes, but for us it is sufficient to know that it's not 0. - if exitCode != 0: exitCode = 1 - - let bufB = if expected.sortoutput: makeDeterministic(strip(buf.string)) - else: strip(buf.string) - let expectedOut = strip(expected.outp) - - if exitCode != expected.exitCode: - r.addResult(test, "exitcode: " & $expected.exitCode, - "exitcode: " & $exitCode & "\n\nOutput:\n" & - analyzeAndConsolidateOutput(bufB), - reExitCodesDiffer) - return - - if bufB != expectedOut and expected.action != actionRunNoSpec: - if not (expected.substr and expectedOut in bufB): - given.err = reOutputsDiffer - r.addResult(test, expected.outp, bufB, reOutputsDiffer) - return - - compilerOutputTests(test, given, expected, r) - return - - of actionReject: - var given = callCompiler(expected.cmd, test.name, test.options, - test.target) - cmpMsgs(r, expected, given, test) - return - -proc testNoSpec(r: var TResults, test: TTest) = + if expected.targets == {}: + expected.targets.incl(target) + + for target in expected.targets: + if target notin targets: + r.addResult(test, target, "", "", reIgnored) + inc(r.skipped) + continue + + case expected.action + of actionCompile: + var given = callCompiler(expected.cmd, test.name, test.options, target, + extraOptions=" --stdout --hint[Path]:off --hint[Processing]:off") + compilerOutputTests(test, target, given, expected, r) + of actionRun, actionRunNoSpec: + # In this branch of code "early return" pattern is clearer than deep + # nested conditionals - the empty rows in between to clarify the "danger" + var given = callCompiler(expected.cmd, test.name, test.options, + target) + + if given.err != reSuccess: + r.addResult(test, target, "", given.msg, given.err) + continue + + let isJsTarget = target == targetJS + var exeFile: string + if isJsTarget: + let (_, file, _) = splitFile(tname) + exeFile = nimcacheDir(test.name, test.options) / file & ".js" + else: + exeFile = changeFileExt(tname, ExeExt) + + if not existsFile(exeFile): + r.addResult(test, target, expected.outp, "executable not found", reExeNotFound) + continue + + let nodejs = if isJsTarget: findNodeJs() else: "" + if isJsTarget and nodejs == "": + r.addResult(test, target, expected.outp, "nodejs binary not in PATH", + reExeNotFound) + continue + + let exeCmd = (if isJsTarget: nodejs & " " else: "") & exeFile + var (buf, exitCode) = execCmdEx(exeCmd, options = {poStdErrToStdOut}) + + # Treat all failure codes from nodejs as 1. Older versions of nodejs used + # to return other codes, but for us it is sufficient to know that it's not 0. + if exitCode != 0: exitCode = 1 + + let bufB = if expected.sortoutput: makeDeterministic(strip(buf.string)) + else: strip(buf.string) + let expectedOut = strip(expected.outp) + + if exitCode != expected.exitCode: + r.addResult(test, target, "exitcode: " & $expected.exitCode, + "exitcode: " & $exitCode & "\n\nOutput:\n" & + bufB, reExitCodesDiffer) + continue + + if bufB != expectedOut and expected.action != actionRunNoSpec: + if not (expected.substr and expectedOut in bufB): + given.err = reOutputsDiffer + r.addResult(test, target, expected.outp, bufB, reOutputsDiffer) + continue + + compilerOutputTests(test, target, given, expected, r) + continue + + of actionReject: + var given = callCompiler(expected.cmd, test.name, test.options, + target) + cmpMsgs(r, expected, given, test, target) + continue + +proc testNoSpec(r: var TResults, test: TTest, target = targetC) = # does not extract the spec because the file is not supposed to have any #let tname = test.name.addFileExt(".nim") inc(r.total) - let given = callCompiler(cmdTemplate(), test.name, test.options, test.target) - r.addResult(test, "", given.msg, given.err) + let given = callCompiler(cmdTemplate(), test.name, test.options, target) + r.addResult(test, target, "", given.msg, given.err) if given.err == reSuccess: inc(r.passed) proc testC(r: var TResults, test: TTest) = @@ -398,9 +393,9 @@ proc testC(r: var TResults, test: TTest) = let tname = test.name.addFileExt(".c") inc(r.total) styledEcho "Processing ", fgCyan, extractFilename(tname) - var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, test.target) + var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, targetC) if given.err != reSuccess: - r.addResult(test, "", given.msg, given.err) + r.addResult(test, targetC, "", given.msg, given.err) elif test.action == actionRun: let exeFile = changeFileExt(test.name, ExeExt) var (_, exitCode) = execCmdEx(exeFile, options = {poStdErrToStdOut, poUsePath}) @@ -408,10 +403,10 @@ proc testC(r: var TResults, test: TTest) = if given.err == reSuccess: inc(r.passed) proc makeTest(test, options: string, cat: Category, action = actionCompile, - target = targetC, env: string = ""): TTest = + env: string = ""): TTest = # start with 'actionCompile', will be overwritten in the spec: result = TTest(cat: cat, name: test, options: options, - target: target, action: action, startTime: epochTime()) + action: action, startTime: epochTime()) when defined(windows): const @@ -436,7 +431,8 @@ proc main() = backend.open() var optPrintResults = false var optFailing = false - var optPedantic = false + + var targetsStr = "" var p = initOptParser() p.next() @@ -444,8 +440,10 @@ proc main() = case p.key.string.normalize of "print", "verbose": optPrintResults = true of "failing": optFailing = true - of "pedantic": optPedantic = true - of "targets": targets = parseTargets(p.val.string) + of "pedantic": discard "now always enabled" + of "targets": + targetsStr = p.val.string + targets = parseTargets(targetsStr) of "nim": compilerPrefix = p.val.string else: quit Usage p.next() @@ -456,13 +454,22 @@ proc main() = case action of "all": let testsDir = "tests" & DirSep + var myself = quoteShell(findExe("tests" / "testament" / "tester")) + if targetsStr.len > 0: + myself &= " " & quoteShell("--targets:" & targetsStr) + + myself &= " " & quoteShell("--nim:" & compilerPrefix) + + var cmds: seq[string] = @[] + let rest = if p.cmdLineRest.string.len > 0: " " & p.cmdLineRest.string else: "" for kind, dir in walkDir(testsDir): assert testsDir.startsWith(testsDir) let cat = dir[testsDir.len .. ^1] if kind == pcDir and cat notin ["testament", "testdata", "nimcache"]: - processCategory(r, Category(cat), p.cmdLineRest.string) - for a in AdditionalCategories: - processCategory(r, Category(a), p.cmdLineRest.string) + cmds.add(myself & " cat " & cat & rest) + for cat in AdditionalCategories: + cmds.add(myself & " cat " & cat & rest) + quit osproc.execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath, poParentStreams}) of "c", "cat", "category": var cat = Category(p.key) p.next @@ -473,10 +480,7 @@ proc main() = var cat = Category(subdir) processSingleTest(r, cat, p.cmdLineRest.string, file) of "html": - var commit = 0 - discard parseInt(p.cmdLineRest.string, commit) - generateHtml(resultsFile, commit, optFailing) - generateJson(jsonFile, commit) + generateHtml(resultsFile, optFailing) else: quit Usage @@ -484,11 +488,10 @@ proc main() = if action == "html": openDefaultBrowser(resultsFile) else: echo r, r.data backend.close() - if optPedantic: - var failed = r.total - r.passed - r.skipped - if failed > 0: - echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped - quit(QuitFailure) + var failed = r.total - r.passed - r.skipped + if failed > 0: + echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped + quit(QuitFailure) if paramCount() == 0: quit Usage diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index 7f5a359f5..eb265f420 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -485,7 +485,7 @@ proc writeformat(o: var Writer; b: bool; fmt: Format) = else: raise newException(FormatError, "Boolean values must of one of the following types: s,b,o,x,X,d,n") -proc writeformat(o: var Writer; ary: openarray[any]; fmt: Format) = +proc writeformat(o: var Writer; ary: openarray[system.any]; fmt: Format) = ## Write array `ary` according to format `fmt` using output object ## `o` and output function `add`. if ary.len == 0: return diff --git a/tests/typerel/typeof_in_template.nim b/tests/typerel/typeof_in_template.nim index 9ec06f2e3..3724cc994 100644 --- a/tests/typerel/typeof_in_template.nim +++ b/tests/typerel/typeof_in_template.nim @@ -1,5 +1,5 @@ discard """ - output: '''@[a, c]''' + output: '''@["a", "c"]''' """ # bug #3230 diff --git a/tests/types/tillegaltyperecursion2.nim b/tests/types/tillegaltyperecursion2.nim new file mode 100644 index 000000000..b5ffdda72 --- /dev/null +++ b/tests/types/tillegaltyperecursion2.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "invalid recursion in type 'Executor'" + line: 8 +""" +# bug reported by PR #5637 +type + Executor[N] = Executor[N] +var e: Executor[int] diff --git a/tests/types/tinheritpartialgeneric.nim b/tests/types/tinheritpartialgeneric.nim index a00df26fa..1845778bf 100644 --- a/tests/types/tinheritpartialgeneric.nim +++ b/tests/types/tinheritpartialgeneric.nim @@ -1,6 +1,6 @@ discard """ - output: '''(c: hello, a: 10, b: 12.0) -(a: 15.5, b: hello) + output: '''(c: "hello", a: 10, b: 12.0) +(a: 15.5, b: "hello") (a: 11.75, b: 123)''' """ diff --git a/tests/types/tinheritref.nim b/tests/types/tinheritref.nim index ecd62a06f..00af0538d 100644 --- a/tests/types/tinheritref.nim +++ b/tests/types/tinheritref.nim @@ -1,5 +1,7 @@ discard """ - output: "23" + output: '''23 +1.5 +''' """ # bug #554, #179 @@ -25,3 +27,24 @@ type var it: TKeysIterator[int, string] = nil +#bug #5521 +type + Texture = enum + Smooth + Coarse + + FruitBase = object of RootObj + color: int + case kind: Texture + of Smooth: + skin: float64 + of Coarse: + grain: int + + Apple = object of FruitBase + width: int + taste: float64 + +var x = Apple(kind: Smooth, skin: 1.5) +var u = x.skin +echo u diff --git a/tests/types/tparameterizedparent2.nim b/tests/types/tparameterizedparent2.nim index 999db2ac5..e96b9edbe 100644 --- a/tests/types/tparameterizedparent2.nim +++ b/tests/types/tparameterizedparent2.nim @@ -2,7 +2,7 @@ discard """ output: '''(width: 11, color: 13) (width: 15, weight: 13, taste: 11, color: 14) (width: 17, color: 16) -(width: 12.0, taste: yummy, color: 13) +(width: 12.0, taste: "yummy", color: 13) (width: 0, tast_e: 0.0, kind: Smooth, skin: 1.5, color: 12)''' """ # bug #5264 diff --git a/tests/types/tyet_another_generic_regression.nim b/tests/types/tyet_another_generic_regression.nim new file mode 100644 index 000000000..914166e06 --- /dev/null +++ b/tests/types/tyet_another_generic_regression.nim @@ -0,0 +1,13 @@ +import system + +type Bar[T] = ref object + value: T + +type types = int32|int64 # if I change this to just int32 or int64 it works (compiles) + +# if I replace Bar everywhere with seq it also compiles fine +proc Foo[T: Bar[types]](): T = + when T is Bar: nil + +discard Foo[Bar[int32]]() +#bug #6073 diff --git a/tests/untestable/readme.markdown b/tests/untestable/readme.markdown index fcb7f4f28..de1ba9459 100644 --- a/tests/untestable/readme.markdown +++ b/tests/untestable/readme.markdown @@ -1,2 +1,9 @@ -This directory contains tests which are not automatically executed -for various reasons. Mainly due to dependencies on external services. \ No newline at end of file +This directory contains integration tests which are not automatically executed +for various reasons: +- dependency on external services +- dependency on files / configuration / state of the local host +- tests that are extremely slow or require large amounts of memory or storage +- tests that spawn local daemons + +Integration tests can become stale very quickly. Automated ./koch tests are +strongly recommended. diff --git a/tests/untestable/tpostgres.nim b/tests/untestable/tpostgres.nim index 486d0d703..d3397e53a 100644 --- a/tests/untestable/tpostgres.nim +++ b/tests/untestable/tpostgres.nim @@ -304,7 +304,24 @@ doAssert parseInt(dbCols[40].typ.name) > 0 doAssert dbCols[41].name == "range_col" doAssert dbCols[41].typ.kind == DbTypeKind.dbComposite doAssert dbCols[41].typ.name == "int4range" - + +# issue 6571 +db.exec(sql"DROP TABLE IF EXISTS DICTIONARY") +db.exec(sql("""CREATE TABLE DICTIONARY( + id SERIAL PRIMARY KEY, + entry VARCHAR(1000) NOT NULL, + definition VARCHAR(4000) NOT NULL + );""")) +var entry = "あっそ" +var definition = "(int) (See ああそうそう) oh, really (uninterested)/oh yeah?/hmmmmm" +discard db.getRow( + SqlQuery("INSERT INTO DICTIONARY(entry, definition) VALUES(\'$1\', \'$2\') RETURNING id" % [entry, definition])) +doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition +entry = "Format string entry" +definition = "Format string definition" +db.exec(sql"INSERT INTO DICTIONARY(entry, definition) VALUES (?, ?)", entry, definition) +doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition + echo("All tests succeeded!") db.close() diff --git a/tests/vm/tableinstatic.nim b/tests/vm/tableinstatic.nim index 54e7c11f0..b0d24b477 100644 --- a/tests/vm/tableinstatic.nim +++ b/tests/vm/tableinstatic.nim @@ -2,7 +2,7 @@ discard """ nimout: '''0 0 0 -{hallo: 123, welt: 456}''' +{"hallo": "123", "welt": "456"}''' """ import tables diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim new file mode 100644 index 000000000..7b9ddd7d9 --- /dev/null +++ b/tests/vm/tcastint.nim @@ -0,0 +1,120 @@ +discard """ + file: "tcastint.nim" + output: "OK" +""" + +type + Dollar = distinct int + XCoord = distinct int32 + Digit = range[-9..0] + +# those are necessary for comparisons below. +proc `==`(x, y: Dollar): bool {.borrow.} +proc `==`(x, y: XCoord): bool {.borrow.} + +proc dummy[T](x: T): T = x + +proc test() = + let U8 = 0b1011_0010'u8 + let I8 = 0b1011_0010'i8 + let C8 = 0b1011_0010'u8.char + let C8_1 = 0b1011_0011'u8.char + let U16 = 0b10100111_00101000'u16 + let I16 = 0b10100111_00101000'i16 + let U32 = 0b11010101_10011100_11011010_01010000'u32 + let I32 = 0b11010101_10011100_11011010_01010000'i32 + let U64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'u64 + let I64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'i64 + let U64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'u64 + let I64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'i64 + when sizeof(int) == 8: + let UX = U64A.uint + let IX = I64A.int + elif sizeof(int) == 4: + let UX = U32.uint + let IX = I32.int + elif sizeof(int) == 2: + let UX = U16.uint + let IX = I16.int + else: + let UX = U8.uint + let IX = I8.int + + doAssert(cast[char](I8) == C8) + doAssert(cast[uint8](I8) == U8) + doAssert(cast[uint16](I16) == U16) + doAssert(cast[uint32](I32) == U32) + doAssert(cast[uint64](I64A) == U64A) + doAssert(cast[uint64](I64B) == U64B) + doAssert(cast[int8](U8) == I8) + doAssert(cast[int16](U16) == I16) + doAssert(cast[int32](U32) == I32) + doAssert(cast[int64](U64A) == I64A) + doAssert(cast[int64](U64B) == I64B) + doAssert(cast[uint](IX) == UX) + doAssert(cast[int](UX) == IX) + + doAssert(cast[char](I8 + 1) == C8_1) + doAssert(cast[uint8](I8 + 1) == U8 + 1) + doAssert(cast[uint16](I16 + 1) == U16 + 1) + doAssert(cast[uint32](I32 + 1) == U32 + 1) + doAssert(cast[uint64](I64A + 1) == U64A + 1) + doAssert(cast[uint64](I64B + 1) == U64B + 1) + doAssert(cast[int8](U8 + 1) == I8 + 1) + doAssert(cast[int16](U16 + 1) == I16 + 1) + doAssert(cast[int32](U32 + 1) == I32 + 1) + doAssert(cast[int64](U64A + 1) == I64A + 1) + doAssert(cast[int64](U64B + 1) == I64B + 1) + doAssert(cast[uint](IX + 1) == UX + 1) + doAssert(cast[int](UX + 1) == IX + 1) + + doAssert(cast[char](I8.dummy) == C8.dummy) + doAssert(cast[uint8](I8.dummy) == U8.dummy) + doAssert(cast[uint16](I16.dummy) == U16.dummy) + doAssert(cast[uint32](I32.dummy) == U32.dummy) + doAssert(cast[uint64](I64A.dummy) == U64A.dummy) + doAssert(cast[uint64](I64B.dummy) == U64B.dummy) + doAssert(cast[int8](U8.dummy) == I8.dummy) + doAssert(cast[int16](U16.dummy) == I16.dummy) + doAssert(cast[int32](U32.dummy) == I32.dummy) + doAssert(cast[int64](U64A.dummy) == I64A.dummy) + doAssert(cast[int64](U64B.dummy) == I64B.dummy) + doAssert(cast[uint](IX.dummy) == UX.dummy) + doAssert(cast[int](UX.dummy) == IX.dummy) + + + doAssert(cast[int64](if false: U64B else: 0'u64) == (if false: I64B else: 0'i64)) + + block: + let raw = 3 + let money = Dollar(raw) # this must be a variable, is otherwise constant folded. + doAssert(cast[int](money) == raw) + doAssert(cast[Dollar](raw) == money) + block: + let raw = 150'i32 + let position = XCoord(raw) # this must be a variable, is otherwise constant folded. + doAssert(cast[int32](position) == raw) + doAssert(cast[XCoord](raw) == position) + block: + let raw = -2 + let digit = Digit(raw) + doAssert(cast[int](digit) == raw) + doAssert(cast[Digit](raw) == digit) + + when defined nimvm: + doAssert(not compiles(cast[float](I64A))) + doAssert(not compiles(cast[float32](I64A))) + + doAssert(not compiles(cast[char](I64A))) + doAssert(not compiles(cast[uint16](I64A))) + doAssert(not compiles(cast[uint32](I64A))) + + doAssert(not compiles(cast[uint16](I8))) + doAssert(not compiles(cast[uint32](I8))) + doAssert(not compiles(cast[uint64](I8))) + +test() +static: + test() + +echo "OK" diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim index 51f30fb78..38fcdd844 100644 --- a/tests/vm/tconstobj.nim +++ b/tests/vm/tconstobj.nim @@ -1,5 +1,5 @@ discard """ - output: '''(name: hello) + output: '''(name: "hello") (-1, 0)''' """ diff --git a/tests/vm/tnimnode.nim b/tests/vm/tnimnode.nim index 60e3189b0..0614b9807 100644 --- a/tests/vm/tnimnode.nim +++ b/tests/vm/tnimnode.nim @@ -26,12 +26,12 @@ proc checkNode(arg: NimNode; name: string): void {. compileTime .} = seqAppend.add(arg) # bit this creates a copy arg.add newCall(ident"echo", newLit("Hello World")) - assertEq arg.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq node.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq nodeSeq[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq seqAppend[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq seqAppend[1].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" + assertEq arg.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq node.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq nodeSeq[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq seqAppend[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq seqAppend[1].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" echo "OK" diff --git a/tests/vm/trgba.nim b/tests/vm/trgba.nim index da1a2d0c5..923ea1b2e 100644 --- a/tests/vm/trgba.nim +++ b/tests/vm/trgba.nim @@ -22,14 +22,14 @@ template `B=`*(self: TAggRgba8, val: byte) = template `A=`*(self: TAggRgba8, val: byte) = self[3] = val -proc ABGR* (val: int| int64): TAggRgba8 = +proc ABGR*(val: int| int64): TAggRgba8 = var V = val - result.R = V and 0xFF + result.R = byte(V and 0xFF) V = V shr 8 - result.G = V and 0xFF + result.G = byte(V and 0xFF) V = V shr 8 - result.B = V and 0xFF - result.A = (V shr 8) and 0xFF + result.B = byte(V and 0xFF) + result.A = byte((V shr 8) and 0xFF) const c1 = ABGR(0xFF007F7F) |