diff options
Diffstat (limited to 'tests')
68 files changed, 2521 insertions, 125 deletions
diff --git a/tests/arithm/tshr.nim b/tests/arithm/tshr.nim new file mode 100644 index 000000000..e9b72f1df --- /dev/null +++ b/tests/arithm/tshr.nim @@ -0,0 +1,20 @@ +discard """ + output: '''''' +""" + +proc T() = + let VI = -8 + let VI64 = -8'i64 + let VI32 = -8'i32 + let VI16 = -8'i16 + let VI8 = -8'i8 + doAssert( (VI shr 1) == 9223372036854775804) + doAssert( (VI64 shr 1) == 9223372036854775804) + doAssert( (VI32 shr 1) == 2147483644) + doAssert( (VI16 shr 1) == 32764) + doAssert( (VI8 shr 1) == 124) + + +T() +static: + T() diff --git a/tests/async/tasyncRecvLine.nim b/tests/async/tasyncRecvLine.nim new file mode 100644 index 000000000..679831b27 --- /dev/null +++ b/tests/async/tasyncRecvLine.nim @@ -0,0 +1,54 @@ +discard """ + file: "tasyncRecvLine.nim" + output: ''' +Hello World +Hello World +''' +""" + +import asyncdispatch, asyncnet + +const recvLinePort = Port(6047) + +proc setupTestServer(): AsyncSocket = + result = newAsyncSocket() + result.setSockOpt(OptReuseAddr, true) + result.bindAddr(recvLinePort) + result.listen() + +proc testUnbuffered(): Future[void] {.async.} = + let serverSock = setupTestServer() + let serverAcceptClientFut = serverSock.accept() + + let clientSock = newAsyncSocket(buffered = false) + let clientConnectFut = clientSock.connect("localhost", recvLinePort) + + let serverAcceptedClient = await serverAcceptClientFut + await clientConnectFut + + await serverAcceptedClient.send("Hello World\c\L") + + echo await clientSock.recvLine() + + clientSock.close() + serverSock.close() + +proc testBuffered(): Future[void] {.async.} = + let serverSock = setupTestServer() + let serverAcceptClientFut = serverSock.accept() + + let clientSock = newAsyncSocket(buffered = true) + let clientConnectFut = clientSock.connect("localhost", recvLinePort) + + let serverAcceptedClient = await serverAcceptClientFut + await clientConnectFut + + await serverAcceptedClient.send("Hello World\c\L") + + echo await clientSock.recvLine() + + clientSock.close() + serverSock.close() + +waitFor testUnbuffered() +waitFor testBuffered() diff --git a/tests/async/tasync_forward.nim b/tests/async/tasync_forward.nim index ffb7acafd..99527032f 100644 --- a/tests/async/tasync_forward.nim +++ b/tests/async/tasync_forward.nim @@ -7,3 +7,12 @@ proc foo {.async.} proc foo {.async.} = discard + +# With additional pragmas: +proc bar {.async, cdecl.} + +proc bar {.async.} = + discard + +proc verifyCdeclPresent(p: proc : Future[void] {.cdecl.}) = discard +verifyCdeclPresent(bar) diff --git a/tests/async/tasyncall.nim b/tests/async/tasyncall.nim index 63b2945a6..7daecd9ef 100644 --- a/tests/async/tasyncall.nim +++ b/tests/async/tasyncall.nim @@ -2,19 +2,19 @@ discard """ file: "tasyncall.nim" exitcode: 0 """ -import times, sequtils +import times, sequtils, unittest import asyncdispatch const taskCount = 10 - sleepDuration = 500 + sleepDuration = 50 proc futureWithValue(x: int): Future[int] {.async.} = await sleepAsync(sleepDuration) return x proc futureWithoutValue() {.async.} = - await sleepAsync(1000) + await sleepAsync(sleepDuration) proc testFuturesWithValue(x: int): seq[int] = var tasks = newSeq[Future[int]](taskCount) @@ -40,38 +40,39 @@ proc testVarargs(x, y, z: int): seq[int] = result = waitFor all(a, b, c) -block: - let - startTime = cpuTime() - results = testFuturesWithValue(42) - expected = repeat(42, taskCount) - execTime = cpuTime() - startTime - - doAssert execTime * 1000 < taskCount * sleepDuration - doAssert results == expected - -block: - let startTime = cpuTime() - testFuturesWithoutValues() - let execTime = cpuTime() - startTime - - doAssert execTime * 1000 < taskCount * sleepDuration - -block: - let - startTime = cpuTime() - results = testVarargs(1, 2, 3) - expected = @[1, 2, 3] - execTime = cpuTime() - startTime - - doAssert execTime * 100 < taskCount * sleepDuration - doAssert results == expected - -block: - let - noIntFuturesFut = all(newSeq[Future[int]]()) - noVoidFuturesFut = all(newSeq[Future[void]]()) - - doAssert noIntFuturesFut.finished and not noIntFuturesFut.failed - doAssert noVoidFuturesFut.finished and not noVoidFuturesFut.failed - doAssert noIntFuturesFut.read() == @[] +suite "tasyncall": + test "testFuturesWithValue": + let + startTime = cpuTime() + results = testFuturesWithValue(42) + expected = repeat(42, taskCount) + execTime = cpuTime() - startTime + + doAssert execTime * 1000 < taskCount * sleepDuration + doAssert results == expected + + test "testFuturesWithoutValues": + let startTime = cpuTime() + testFuturesWithoutValues() + let execTime = cpuTime() - startTime + + doAssert execTime * 1000 < taskCount * sleepDuration + + test "testVarargs": + let + startTime = cpuTime() + results = testVarargs(1, 2, 3) + expected = @[1, 2, 3] + execTime = cpuTime() - startTime + + doAssert execTime * 100 < taskCount * sleepDuration + doAssert results == expected + + test "all on seq[Future]": + let + noIntFuturesFut = all(newSeq[Future[int]]()) + noVoidFuturesFut = all(newSeq[Future[void]]()) + + doAssert noIntFuturesFut.finished and not noIntFuturesFut.failed + doAssert noVoidFuturesFut.finished and not noVoidFuturesFut.failed + doAssert noIntFuturesFut.read() == @[] diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index e2b9b94d5..034c2185c 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -508,10 +508,14 @@ else: freeAddrInfo(aiList) # for some reason Windows select doesn't return both # descriptors from first call, so we need to make 2 calls - var rcm1 = selector.select(1000) - var rcm2 = selector.select(1000) - let rcm = len(rcm1) + len(rcm2) - assert(rcm >= 2 and rcm <= 4) + var n = 0 + var rcm = selector.select(1000) + while n < 10 and len(rcm) < 2: + sleep(1000) + rcm = selector.select(1000) + inc(n) + + assert(len(rcm) == 2) var sockAddress = SockAddr() var addrLen = sizeof(sockAddress).Socklen diff --git a/tests/async/tlambda.nim b/tests/async/tlambda.nim index e0ff1f483..d187c0d50 100644 --- a/tests/async/tlambda.nim +++ b/tests/async/tlambda.nim @@ -51,5 +51,8 @@ proc main() = var builder = newBuilder() + # Test {.async.} pragma with do notation: #5995 + builder.client = newClient("builder") do(client: Client, msg: JsonNode) {.async.}: + await onMessage(builder, msg) main() diff --git a/tests/bind/tinvalidbindtypedesc.nim b/tests/bind/tinvalidbindtypedesc.nim index 5b2f51110..7704d2cb7 100644 --- a/tests/bind/tinvalidbindtypedesc.nim +++ b/tests/bind/tinvalidbindtypedesc.nim @@ -1,6 +1,6 @@ discard """ line: 10 - errormsg: "type mismatch: got (typedesc[float], string)" + errormsg: "type mismatch: got (type float, string)" """ proc foo(T: typedesc; some: T) = diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index bd00188fa..1431720e0 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -1,6 +1,6 @@ discard """ line: 18 - errormsg: "type mismatch: got (proc (s: TScgi) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe, locks: 0.}" + errormsg: "type mismatch: got (proc (s: TScgi: ScgiState or AsyncScgiState) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe, locks: 0.}" """ #bug #442 diff --git a/tests/concepts/t3414.nim b/tests/concepts/t3414.nim new file mode 100644 index 000000000..d45973034 --- /dev/null +++ b/tests/concepts/t3414.nim @@ -0,0 +1,22 @@ +type + View[T] = concept v + v.empty is bool + v.front is T + popFront v + +proc find(view: View; target: View.T): View = + result = view + + while not result.empty: + if view.front == target: + return + + mixin popFront + popFront result + +proc popFront[T](s: var seq[T]) = discard +proc empty[T](s: seq[T]): bool = false + +var s1 = @[1, 2, 3] +let s2 = s1.find(10) + diff --git a/tests/concepts/t4982.nim b/tests/concepts/t4982.nim new file mode 100644 index 000000000..9d82c83c9 --- /dev/null +++ b/tests/concepts/t4982.nim @@ -0,0 +1,18 @@ +discard """ +errormsg: "undeclared identifier: 'x'" +line: 10 +""" + +import typetraits # without this import the program compiles (and echos false) + +type + SomeTestConcept = concept t + x.name is string # typo: t.name was intended (which would result in echo true) + +type + TestClass = ref object of RootObj + name: string + +var test = TestClass(name: "mytest") +echo $(test is SomeTestConcept) + diff --git a/tests/concepts/t5888.nim b/tests/concepts/t5888.nim new file mode 100644 index 000000000..dbbab8c4c --- /dev/null +++ b/tests/concepts/t5888.nim @@ -0,0 +1,26 @@ +discard """ +output: ''' +true +true +true +f +0 +''' +""" + +import t5888lib/ca, t5888lib/opt + +type LocalCA = ca.CA + +proc f(c: CA) = + echo "f" + echo c.x + +var o = new(Opt) + +echo o is CA +echo o is LocalCA +echo o is ca.CA + +o.f() + diff --git a/tests/concepts/t5888lib/ca.nim b/tests/concepts/t5888lib/ca.nim new file mode 100644 index 000000000..4a811f797 --- /dev/null +++ b/tests/concepts/t5888lib/ca.nim @@ -0,0 +1,4 @@ +type + CA* = concept c + c.x is int + diff --git a/tests/concepts/t5888lib/opt.nim b/tests/concepts/t5888lib/opt.nim new file mode 100644 index 000000000..65d16addc --- /dev/null +++ b/tests/concepts/t5888lib/opt.nim @@ -0,0 +1,6 @@ +import ca + +type + Opt* = object + x*: int + diff --git a/tests/concepts/t5968.nim b/tests/concepts/t5968.nim new file mode 100644 index 000000000..adb374c65 --- /dev/null +++ b/tests/concepts/t5968.nim @@ -0,0 +1,20 @@ +discard """ + exitcode: 0 +""" + +type + Enumerable[T] = concept e + for it in e: + it is T + +proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] = + result = @[] + for it in e: result.add(fn(it)) + +import json + +var x = %["hello", "world"] + +var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!") +assert z == @["hello!", "world!"] + diff --git a/tests/concepts/t5983.nim b/tests/concepts/t5983.nim new file mode 100644 index 000000000..e69647448 --- /dev/null +++ b/tests/concepts/t5983.nim @@ -0,0 +1,22 @@ +discard """ + output: "20.0 USD" +""" + +import typetraits + +const currencies = ["USD", "EUR"] # in real code 120 currencies + +type USD* = distinct float # in real code 120 types generates using macro +type EUR* = distinct float + +type CurrencyAmount = concept c + type t = c.type + const name = c.type.name + name in currencies + +proc `$`(x: CurrencyAmount): string = + $float(x) & " " & x.name + +let amount = 20.USD +echo amount + diff --git a/tests/concepts/templatesinconcepts.nim b/tests/concepts/templatesinconcepts.nim new file mode 100644 index 000000000..292b97ea6 --- /dev/null +++ b/tests/concepts/templatesinconcepts.nim @@ -0,0 +1,56 @@ +import typetraits + +template typeLen(x): int = x.type.name.len + +template bunchOfChecks(x) = + x.typeLen > 3 + x != 10 is bool + +template stmtListExprTmpl(x: untyped): untyped = + x is int + x + +type + Obj = object + x: int + + Gen[T] = object + x: T + + Eq = concept x, y + (x == y) is bool + + NotEq = concept x, y + (x != y) is bool + + ConceptUsingTemplate1 = concept x + echo x + sizeof(x) is int + bunchOfChecks x + + ConceptUsingTemplate2 = concept x + stmtListExprTmpl x + +template ok(x) = + static: assert(x) + +template no(x) = + static: assert(not(x)) + +ok int is Eq +ok int is NotEq +ok string is Eq +ok string is NotEq +ok Obj is Eq +ok Obj is NotEq +ok Gen[string] is Eq +ok Gen[int] is NotEq + +no int is ConceptUsingTemplate1 +ok float is ConceptUsingTemplate1 +no string is ConceptUsingTemplate1 + +ok int is ConceptUsingTemplate2 +no float is ConceptUsingTemplate2 +no string is ConceptUsingTemplate2 + diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 25a075fd1..417d1e502 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -9,33 +9,33 @@ 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: type class predicate failed +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: type class predicate failed +texplain.nim(65, 5) ExplainedConcept: concept predicate failed texplain.nim(105, 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: type class predicate failed +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: type class predicate failed +texplain.nim(65, 5) ExplainedConcept: concept predicate failed texplain.nim(109, 20) Error: type mismatch: got (NonMatchingType) but expected one of: proc e(o: ExplainedConcept): int -texplain.nim(65, 5) ExplainedConcept: type class predicate failed +texplain.nim(65, 5) ExplainedConcept: concept predicate failed proc e(i: int): int texplain.nim(110, 20) Error: type mismatch: got (NonMatchingType) but expected one of: proc r(o: RegularConcept): int -texplain.nim(69, 5) RegularConcept: type class predicate failed +texplain.nim(69, 5) RegularConcept: concept predicate failed proc r[T](a: SomeNumber; b: T; c: auto) proc r(i: string): int @@ -49,12 +49,12 @@ 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: type class predicate failed +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: type class predicate failed -texplain.nim(73, 5) NestedConcept: type class predicate failed +texplain.nim(69, 5) RegularConcept: concept predicate failed +texplain.nim(73, 5) NestedConcept: concept predicate failed ''' line: 119 errormsg: "type mismatch: got (MatchingType)" diff --git a/tests/concepts/tgraph.nim b/tests/concepts/tgraph.nim index a0177a043..985f04a61 100644 --- a/tests/concepts/tgraph.nim +++ b/tests/concepts/tgraph.nim @@ -1,29 +1,34 @@ -discard """ - output: '''XY is Node -MyGraph is Graph''' -""" # bug #3452 import math type - Node* = concept n - `==`(n, n) is bool + Node* = concept n + `==`(n, n) is bool - Graph* = concept g - var x: Node - distance(g, x, x) is float + Graph1* = concept g + type N = Node + distance(g, N, N) is float - XY* = tuple[x, y: int] + Graph2 = concept g + distance(g, Node, Node) is float - MyGraph* = object - points: seq[XY] + Graph3 = concept g + var x: Node + distance(g, x, x) is float -if XY is Node: - echo "XY is Node" + XY* = tuple[x, y: int] + + MyGraph* = object + points: seq[XY] + +static: + assert XY is Node proc distance*( g: MyGraph, a, b: XY): float = - sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) ) + sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) ) -if MyGraph is Graph: - echo "MyGraph is Graph" +static: + assert MyGraph is Graph1 + assert MyGraph is Graph2 + assert MyGraph is Graph3 diff --git a/tests/concepts/trandomvars.nim b/tests/concepts/trandomvars.nim new file mode 100644 index 000000000..db41aa901 --- /dev/null +++ b/tests/concepts/trandomvars.nim @@ -0,0 +1,61 @@ +discard """ +output: ''' +true +true +true +3 +18.0 +324.0 +''' +""" + +type RNG = object + +proc random(rng: var RNG): float = 1.0 + +type + RandomVar[A] = concept x + var rng: RNG + rng.sample(x) is A + + Constant[A] = object + value: A + + Uniform = object + a, b: float + + ClosureVar[A] = proc(rng: var RNG): A + +proc sample[A](rng: var RNG, c: Constant[A]): A = c.value + +proc sample(rng: var RNG, u: Uniform): float = u.a + (u.b - u.a) * rng.random() + +proc sample[A](rng: var RNG, c: ClosureVar[A]): A = c(rng) + +proc constant[A](a: A): Constant[A] = Constant[A](value: a) + +proc uniform(a, b: float): Uniform = Uniform(a: a, b: b) + +proc lift1[A, B](f: proc(a: A): B, r: RandomVar[A]): ClosureVar[B] = + proc inner(rng: var RNG): B = f(rng.sample(r)) + + return inner + +when isMainModule: + proc sq(x: float): float = x * x + + let + c = constant(3) + u = uniform(2, 18) + t = lift1(sq, u) + + var rng: RNG + + echo(c is RandomVar[int]) + echo(u is RandomVar[float]) + echo(t is RandomVar[float]) + + echo rng.sample(c) + echo rng.sample(u) + echo rng.sample(t) + diff --git a/tests/concepts/twrapconcept.nim b/tests/concepts/twrapconcept.nim new file mode 100644 index 000000000..25a855e34 --- /dev/null +++ b/tests/concepts/twrapconcept.nim @@ -0,0 +1,22 @@ +discard """ + errormsg: "type mismatch: got (string)" + line: 21 + nimout: "twrapconcept.nim(11, 5) Foo: concept predicate failed" +""" + +# https://github.com/nim-lang/Nim/issues/5127 + +type + Foo = concept foo + foo.get is int + + FooWrap[F: Foo] = object + foo: F + +proc get(x: int): int = x + +proc wrap[F: Foo](foo: F): FooWrap[F] = FooWrap[F](foo: foo) + +let x = wrap(12) +let y = wrap "string" + diff --git a/tests/cpp/tcovariancerules.nim b/tests/cpp/tcovariancerules.nim new file mode 100644 index 000000000..dfe4cb941 --- /dev/null +++ b/tests/cpp/tcovariancerules.nim @@ -0,0 +1,424 @@ +discard """ +cmd: "nim cpp $file" +output: ''' +cat +cat +dog +dog +cat +cat +dog +dog X +cat +cat +dog +dog +dog value +cat value +dog value +cat value +dog +dog +dog value +cat value +dog 1 +dog 2 +''' +""" + +template accept(x) = + static: assert(compiles(x)) + +template reject(x) = + static: assert(not compiles(x)) + +import macros + +macro skipElse(n: untyped): typed = n[0] + +template acceptWithCovariance(x, otherwise): typed = + when nimEnableCovariance: + x + else: + reject(x) + skipElse(otherwise) + +type + Animal = object of RootObj + x: string + + Dog = object of Animal + y: int + + Cat = object of Animal + z: int + + AnimalRef = ref Animal + AnimalPtr = ptr Animal + + RefAlias[T] = ref T + +var dog = new(Dog) +dog.x = "dog" + +var cat = new(Cat) +cat.x = "cat" + +proc makeDerivedRef(x: string): ref Dog = + new(result) + result.x = x + +proc makeDerived(x: string): Dog = + result.x = x + +var covariantSeq = @[makeDerivedRef("dog 1"), makeDerivedRef("dog 2")] +var nonCovariantSeq = @[makeDerived("dog 1"), makeDerived("dog 2")] +var covariantArr = [makeDerivedRef("dog 1"), makeDerivedRef("dog 2")] +var nonCovariantArr = [makeDerived("dog 1"), makeDerived("dog 2")] + +proc wantsCovariantSeq1(s: seq[ref Animal]) = + for a in s: echo a.x + +proc wantsCovariantSeq2(s: seq[AnimalRef]) = + for a in s: echo a.x + +proc wantsCovariantSeq3(s: seq[RefAlias[Animal]]) = + for a in s: echo a.x + +proc wantsCovariantOperArray(s: openarray[ref Animal]) = + for a in s: echo a.x + +proc modifiesCovariantOperArray(s: var openarray[ref Animal]) = + for a in s: echo a.x + +proc modifiesDerivedOperArray(s: var openarray[ref Dog]) = + for a in s: echo a.x + +proc wantsNonCovariantOperArray(s: openarray[Animal]) = + for a in s: echo a.x + +proc wantsCovariantArray(s: array[2, ref Animal]) = + for a in s: echo a.x + +proc wantsNonCovariantSeq(s: seq[Animal]) = + for a in s: echo a.x + +proc wantsNonCovariantArray(s: array[2, Animal]) = + for a in s: echo a.x + +proc modifiesCovariantSeq(s: var seq[ref Animal]) = + for a in s: echo a.x + +proc modifiesCovariantArray(s: var array[2, ref Animal]) = + for a in s: echo a.x + +proc modifiesCovariantSeq(s: ptr seq[ref Animal]) = + for a in s[]: echo a.x + +proc modifiesCovariantArray(s: ptr array[2, ref Animal]) = + for a in s[]: echo a.x + +proc modifiesDerivedSeq(s: var seq[ref Dog]) = + for a in s: echo a.x + +proc modifiesDerivedArray(s: var array[2, ref Dog]) = + for a in s: echo a.x + +proc modifiesDerivedSeq(s: ptr seq[ref Dog]) = + for a in s[]: echo a.x + +proc modifiesDerivedArray(s: ptr array[2, ref Dog]) = + for a in s[]: echo a.x + +accept: + wantsCovariantArray([AnimalRef(dog), AnimalRef(dog)]) + wantsCovariantArray([AnimalRef(cat), AnimalRef(dog)]) + wantsCovariantArray([AnimalRef(cat), dog]) + + # there is a special rule that detects the base + # type of polymorphic arrays + wantsCovariantArray([cat, dog]) + +acceptWithCovariance: + wantsCovariantArray([cat, cat]) +else: + echo "cat" + echo "cat" + +var animalRefArray: array[2, ref Animal] + +accept: + animalRefArray = [AnimalRef(dog), AnimalRef(dog)] + animalRefArray = [AnimalRef(cat), dog] + +acceptWithCovariance: + animalRefArray = [dog, dog] + wantsCovariantArray animalRefArray +else: + echo "dog" + echo "dog" + +accept: + var animal: AnimalRef = dog + animal = cat + +var vdog: Dog +vdog.x = "dog value" +var vcat: Cat +vcat.x = "cat value" + +reject: + vcat = vdog + +# XXX: The next two cases seem incosistent, perhaps we should change the rules +accept: + # truncating copies are allowed + var vanimal: Animal = vdog + vanimal = vdog + +reject: + # truncating copies are not allowed with arrays + var vanimalArray: array[2, Animal] + var vdogArray = [vdog, vdog] + vanimalArray = vdogArray + +accept: + # a more explicit version of a truncating copy that + # should probably always remain allowed + var vnextnimal: Animal = Animal(vdog) + +proc wantsRefSeq(x: seq[AnimalRef]) = discard + +accept: + wantsCovariantSeq1(@[AnimalRef(dog), AnimalRef(dog)]) + wantsCovariantSeq1(@[AnimalRef(cat), AnimalRef(dog)]) + wantsCovariantSeq1(@[AnimalRef(cat), dog]) + wantsCovariantSeq1(@[cat, dog]) + + wantsCovariantSeq2(@[AnimalRef(dog), AnimalRef(dog)]) + wantsCovariantSeq2(@[AnimalRef(cat), AnimalRef(dog)]) + wantsCovariantSeq2(@[AnimalRef(cat), dog]) + wantsCovariantSeq2(@[cat, dog]) + + wantsCovariantSeq3(@[AnimalRef(dog), AnimalRef(dog)]) + wantsCovariantSeq3(@[AnimalRef(cat), AnimalRef(dog)]) + wantsCovariantSeq3(@[AnimalRef(cat), dog]) + wantsCovariantSeq3(@[cat, dog]) + + wantsCovariantOperArray([cat, dog]) + +acceptWithCovariance: + wantsCovariantSeq1(@[cat, cat]) + wantsCovariantSeq2(@[dog, makeDerivedRef("dog X")]) + # XXX: wantsCovariantSeq3(@[cat, cat]) + + wantsCovariantOperArray(@[cat, cat]) + wantsCovariantOperArray([dog, dog]) +else: + echo "cat" + echo "cat" + echo "dog" + echo "dog X" + echo "cat" + echo "cat" + echo "dog" + echo "dog" + +var dogRefs = @[dog, dog] +var dogRefsArray = [dog, dog] +var animalRefs = @[dog, cat] + +accept: + modifiesDerivedArray(dogRefsArray) + modifiesDerivedSeq(dogRefs) + +reject modifiesCovariantSeq(dogRefs) +reject modifiesCovariantSeq(addr(dogRefs)) +reject modifiesCovariantSeq(dogRefs.addr) + +reject modifiesCovariantArray([dog, dog]) +reject modifiesCovariantArray(dogRefsArray) +reject modifiesCovariantArray(addr(dogRefsArray)) +reject modifiesCovariantArray(dogRefsArray.addr) + +var dogValues = @[vdog, vdog] +var dogValuesArray = [vdog, vdog] +var animalValues = @[Animal(vdog), Animal(vcat)] +var animalValuesArray = [Animal(vdog), Animal(vcat)] + +wantsNonCovariantSeq animalValues +wantsNonCovariantArray animalValuesArray + +reject wantsNonCovariantSeq(dogRefs) +reject modifiesCovariantOperArray(dogRefs) +reject wantsNonCovariantArray(dogRefsArray) +reject wantsNonCovariantSeq(dogValues) +reject wantsNonCovariantArray(dogValuesArray) +reject modifiesValueArray() + +modifiesDerivedOperArray dogRefs +reject modifiesDerivedOperArray(dogValues) +reject modifiesDerivedOperArray(animalRefs) + +wantsNonCovariantOperArray animalValues +reject wantsNonCovariantOperArray(animalRefs) +reject wantsNonCovariantOperArray(dogRefs) +reject wantsNonCovariantOperArray(dogValues) + +var animalRefSeq: seq[ref Animal] + +accept: + animalRefSeq = @[AnimalRef(dog), AnimalRef(dog)] + animalRefSeq = @[AnimalRef(cat), dog] + +acceptWithCovariance: + animalRefSeq = @[makeDerivedRef("dog 1"), makeDerivedRef("dog 2")] + wantsCovariantSeq1(animalRefSeq) +else: + echo "dog 1" + echo "dog 2" + +var pdog: ptr Dog +var pcat: ptr Cat + +proc wantsPointer(x: ptr Animal) = + discard + +accept: + wantsPointer pdog + wantsPointer pcat + +# covariance should be disabled when var is involved +proc wantsVarPointer1(x: var ptr Animal) = + discard + +proc wantsVarPointer2(x: var AnimalPtr) = + discard + +reject wantsVarPointer1(pdog) +reject wantsVarPointer2(pcat) + +# covariance may be allowed for certain extern types + +{.emit: """ +template <class T> struct FN { typedef void (*type)(T); }; +template <class T> struct ARR { typedef T DataType[2]; DataType data; }; +""".} + +type + MyPtr {.importcpp: "'0 *"} [out T] = object + + MySeq {.importcpp: "ARR<'0>", nodecl} [out T] = object + data: array[2, T] + + MyAction {.importcpp: "FN<'0>::type"} [in T] = object + +var + cAnimal: MyPtr[Animal] + cDog: MyPtr[Dog] + cCat: MyPtr[Cat] + + cAnimalFn: MyAction[Animal] + cCatFn: MyAction[Cat] + cDogFn: MyAction[Dog] + + cRefAnimalFn: MyAction[ref Animal] + cRefCatFn: MyAction[ref Cat] + cRefDogFn: MyAction[ref Dog] + +accept: + cAnimal = cDog + cAnimal = cCat + + cDogFn = cAnimalFn + cCatFn = cAnimalFn + + cRefDogFn = cRefAnimalFn + cRefCatFn = cRefAnimalFn + +reject: cDogFn = cRefAnimalFn +reject: cCatFn = cRefAnimalFn + +reject: cCat = cDog +reject: cAnimalFn = cDogFn +reject: cAnimalFn = cCatFn +reject: cRefAnimalFn = cRefDogFn +reject: cRefAnimalFn = cRefCatFn +reject: cRefAnimalFn = cDogFn + +var + ptrPtrDog: ptr ptr Dog + ptrPtrAnimal: ptr ptr Animal + +reject: ptrPtrDog = ptrPtrAnimal + +# Try to break the rules by introducing some tricky +# double indirection types: +var + cPtrRefAnimal: MyPtr[ref Animal] + cPtrRefDog: MyPtr[ref Dog] + + cPtrAliasRefAnimal: MyPtr[RefAlias[Animal]] + cPtrAliasRefDog: MyPtr[RefAlias[Dog]] + + cDoublePtrAnimal: MyPtr[MyPtr[Animal]] + cDoublePtrDog: MyPtr[MyPtr[Dog]] + +reject: cPtrRefAnimal = cPtrRefDog +reject: cDoublePtrAnimal = cDoublePtrDog +reject: cRefAliasPtrAnimal = cRefAliasPtrDog +reject: cPtrRefAnimal = cRefAliasPtrDog +reject: cPtrAliasRefAnimal = cPtrRefDog + +var + # Array and Sequence types are covariant only + # when instantiated with ref or ptr types: + cAnimals: MySeq[ref Animal] + cDogs: MySeq[ref Dog] + + # "User-defined" pointer types should be OK too: + cAnimalPtrSeq: MySeq[MyPtr[Animal]] + cDogPtrSeq: MySeq[MyPtr[Dog]] + + # Value types shouldn't work: + cAnimalValues: MySeq[Animal] + cDogValues: MySeq[Dog] + + # Double pointer types should not work either: + cAnimalRefPtrSeq: MySeq[ref MyPtr[Animal]] + cDogRefPtrSeq: MySeq[ref MyPtr[Dog]] + cAnimalPtrPtrSeq: MySeq[ptr ptr Animal] + cDogPtrPtrSeq: MySeq[ptr ptr Dog] + +accept: + cAnimals = cDogs + cAnimalPtrSeq = cDogPtrSeq + +reject: cAnimalValues = cDogValues +reject: cAnimalRefPtrSeq = cDogRefPtrSeq +reject: cAnimalPtrPtrSeq = cDogPtrPtrSeq + +proc wantsAnimalSeq(x: MySeq[Animal]) = discard +proc wantsAnimalRefSeq(x: MySeq[ref Animal]) = discard +proc modifiesAnimalRefSeq(x: var MySeq[ref Animal]) = discard +proc usesAddressOfAnimalRefSeq(x: ptr MySeq[ref Animal]) = discard + +accept wantsAnimalSeq(cAnimalValues) +reject wantsAnimalSeq(cDogValues) +reject wantsAnimalSeq(cAnimals) + +reject wantsAnimalRefSeq(cAnimalValues) +reject wantsAnimalRefSeq(cDogValues) +accept wantsAnimalRefSeq(cAnimals) +accept wantsAnimalRefSeq(cDogs) + +reject modifiesAnimalRefSeq(cAnimalValues) +reject modifiesAnimalRefSeq(cDogValues) +accept modifiesAnimalRefSeq(cAnimals) +reject modifiesAnimalRefSeq(cDogs) + +reject usesAddressOfAnimalRefSeq(addr cAnimalValues) +reject usesAddressOfAnimalRefSeq(addr cDogValues) +accept usesAddressOfAnimalRefSeq(addr cAnimals) +reject usesAddressOfAnimalRefSeq(addr cDogs) + diff --git a/tests/errmsgs/tconceptconstraint.nim b/tests/errmsgs/tconceptconstraint.nim new file mode 100644 index 000000000..c1f0b94eb --- /dev/null +++ b/tests/errmsgs/tconceptconstraint.nim @@ -0,0 +1,21 @@ +discard """ + errormsg: "cannot instantiate B" + line: 20 + nimout: ''' +got: (type string) +but expected: (T: A) +''' +""" + +type + A = concept c + advance(c) + + B[T: A] = object + child: ref B[T] + +proc advance(x: int): int = x + 1 + +var a: B[int] +var b: B[string] + diff --git a/tests/errmsgs/tgenericconstraint.nim b/tests/errmsgs/tgenericconstraint.nim new file mode 100644 index 000000000..9129d257b --- /dev/null +++ b/tests/errmsgs/tgenericconstraint.nim @@ -0,0 +1,15 @@ +discard """ + errormsg: "cannot instantiate B" + line: 14 + nimout: ''' +got: (type int) +but expected: (T: string or float) +''' +""" + +type + B[T: string|float] = object + child: ref B[T] + +var b: B[int] + diff --git a/tests/errmsgs/tinvalidinout.nim b/tests/errmsgs/tinvalidinout.nim new file mode 100644 index 000000000..ce7eb6022 --- /dev/null +++ b/tests/errmsgs/tinvalidinout.nim @@ -0,0 +1,26 @@ +discard """ +cmd: "nim check $file" +errormsg: "The `in` modifier can be used only with imported types" +nimout: ''' +tinvalidinout.nim(14, 7) Error: The `out` modifier can be used only with imported types +tinvalidinout.nim(17, 9) Error: The `in` modifier can be used only with imported types +tinvalidinout.nim(18, 9) Error: The `in` modifier can be used only with imported types +''' +""" + +type + Foo {.header: "foo.h", importcpp.} [in T] = object + + Bar[out X] = object + x: int + +proc f1[in T](x: T) = discard +proc f2[in T](x: T) {.importc: "f", header: "foo.h"} + +var + f: Foo[int] + b: Bar[string] + +f1 f +f2 b + diff --git a/tests/exception/tfinally3.nim b/tests/exception/tfinally3.nim index 8bccd1a7f..037ca9553 100644 --- a/tests/exception/tfinally3.nim +++ b/tests/exception/tfinally3.nim @@ -1,6 +1,11 @@ discard """ file: "tfinally3.nim" - output: "false" + output: '''false +Within finally->try +Traceback (most recent call last) +tfinally3.nim(24) tfinally3 +Error: unhandled exception: First [Exception]''' + exitCode: 1 """ # Test break in try statement: @@ -14,5 +19,11 @@ proc main: bool = echo main() #OUT false - - +# bug #5871 +try: + raise newException(Exception, "First") +finally: + try: + raise newException(Exception, "Within finally->try") + except: + echo getCurrentExceptionMsg() diff --git a/tests/fields/timplicitfieldswithpartial.nim b/tests/fields/timplicitfieldswithpartial.nim new file mode 100644 index 000000000..996912a1a --- /dev/null +++ b/tests/fields/timplicitfieldswithpartial.nim @@ -0,0 +1,19 @@ +discard """ + output: '''(foo: 38, other: string here) +43''' +""" + +type + Base = ref object of RootObj + Foo {.partial.} = ref object of Base + +proc my(f: Foo) = + #var f.next = f + let f.foo = 38 + let f.other = "string here" + echo f[] + echo f.foo + 5 + +var g: Foo +new(g) +my(g) diff --git a/tests/float/tissue5821.nim b/tests/float/tissue5821.nim new file mode 100644 index 000000000..e8aa4a1d9 --- /dev/null +++ b/tests/float/tissue5821.nim @@ -0,0 +1,13 @@ +discard """ + file: "tissue5821.nim" + output: '''''' +""" +proc main(): void = + let a: float32 = 47.11'f32 + doAssert a == 47.11'f32 + + let b: float64 = 10.234402823e+38'f64 + doAssert b != 10.123402823e+38'f64 + doAssert b == 10.234402823e+38'f64 + +main() \ No newline at end of file diff --git a/tests/generics/tfakecovariance.nim b/tests/generics/tfakecovariance.nim new file mode 100644 index 000000000..0920cb504 --- /dev/null +++ b/tests/generics/tfakecovariance.nim @@ -0,0 +1,78 @@ +template accept(x) = + static: assert(compiles(x)) + +template reject(x) = + static: assert(not compiles(x)) + +type + BaseObj = object of RootObj + DerivedObj = object of BaseObj + NonDerivedObj = object + + Container[T] = object + +var base: BaseObj +var derived: DerivedObj +var nonDerived: NonDerivedObj + +var baseContainer: Container[BaseObj] +var derivedContainer: Container[DerivedObj] +var nonDerivedContainer: Container[NonDerivedObj] + +# We can fake covariance by listing some specific derived types that +# will be allowed with our overload. This is not a real covariance, +# because there will be multiple instantiations of the proc, but for +# many purposes, it will suffice: + +proc wantsSpecificContainers(c: Container[BaseObj or DerivedObj]) = discard + +accept wantsSpecificContainers(baseContainer) +accept wantsSpecificContainers(derivedContainer) + +reject wantsSpecificContainers(nonDerivedContainer) +reject wantsSpecificContainers(derived) + +# Now, let's make a more general solution able to catch all derived types: + +type + DerivedFrom[T] = concept type D + var derived: ref D + var base: ref T = derived + +proc wantsDerived(x: DerivedFrom[BaseObj]) = discard + +accept wantsDerived(base) +accept wantsDerived(derived) + +reject wantsDerived(nonDerived) +reject wantsDerived(baseContainer) + +proc wantsDerivedContainer(c: Container[DerivedFrom[BaseObj]]) = discard + +accept wantsDerivedContainer(baseContainer) +accept wantsDerivedContainer(derivedContainer) + +reject wantsDerivedContainer(nonDerivedContainer) + +# The previous solutions were solving the problem for a single overload. +# Let's solve it for multiple overloads by introducing a converter: + +type + OtherContainer[T] = object + +proc wantsBaseContainer1(c: OtherContainer[BaseObj]) = discard +proc wantsBaseContainer2(c: OtherContainer[BaseObj]) = discard + +converter derivedToBase(c: OtherContainer[DerivedFrom[BaseObj]]): OtherContainer[BaseObj] = discard + +block: + var baseContainer: OtherContainer[BaseObj] + var derivedContainer: OtherContainer[DerivedObj] + var nonDerivedContainer: OtherContainer[NonDerivedObj] + + accept wantsBaseContainer1(derivedContainer) + reject wantsBaseContainer1(nonDerivedContainer) + + accept wantsBaseContainer2(derivedContainer) + reject wantsBaseContainer2(nonDerivedContainer) + diff --git a/tests/generics/tfakedependenttypes.nim b/tests/generics/tfakedependenttypes.nim new file mode 100644 index 000000000..cd4be806c --- /dev/null +++ b/tests/generics/tfakedependenttypes.nim @@ -0,0 +1,61 @@ +discard """ +output: ''' +U[3] +U[(f: 3)] +U[[3]] +''' +""" + +# https://github.com/nim-lang/Nim/issues/5106 + +import typetraits + +block: + type T = distinct int + + proc `+`(a, b: T): T = + T(int(a) + int(b)) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T(1)](1) + var b = U[T(2)](2) + var c = a + b + echo c.type.name + +block: + type T = object + f: int + + proc `+`(a, b: T): T = + T(f: a.f + b.f) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T(f: 1)](1) + var b = U[T(f: 2)](2) + var c = a + b + echo c.type.name + +block: + type T = distinct array[0..0, int] + + proc `+`(a, b: T): T = + T([array[0..0, int](a)[0] + array[0..0, int](b)[0]]) + + type U[F: static[T]] = distinct int + + proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] = + U[P1 + P2](int(a) + int(b)) + + var a = U[T([1])](1) + var b = U[T([2])](2) + var c = a + b + echo c.type.name + diff --git a/tests/generics/tgenericconst.nim b/tests/generics/tgenericconst.nim new file mode 100644 index 000000000..3c86888df --- /dev/null +++ b/tests/generics/tgenericconst.nim @@ -0,0 +1,39 @@ +discard """ +output: ''' +@[1, 2] +@[3, 4] +1 +''' +""" + +# https://github.com/nim-lang/Nim/issues/5756 + +type + Vec*[N : static[int]] = object + x: int + arr*: array[N, int32] + + Mat*[M,N: static[int]] = object + x: int + arr*: array[M, Vec[N]] + +proc vec2*(x,y:int32) : Vec[2] = + result.arr = [x,y] + result.x = 10 + +proc mat2*(a,b: Vec[2]): Mat[2,2] = + result.arr = [a,b] + result.x = 20 + +const M = mat2(vec2(1, 2), vec2(3, 4)) + +let m1 = M +echo @(m1.arr[0].arr) +echo @(m1.arr[1].arr) + +proc foo = + let m2 = M + echo m1.arr[0].arr[0] + +foo() + diff --git a/tests/generics/tgenericsdefaultvalues.nim b/tests/generics/tgenericsdefaultvalues.nim new file mode 100644 index 000000000..2604c1031 --- /dev/null +++ b/tests/generics/tgenericsdefaultvalues.nim @@ -0,0 +1,14 @@ +discard """ +output: "12" +""" + +# https://github.com/nim-lang/Nim/issues/5864 + +proc defaultStatic(s: openarray, N: static[int] = 1): int = N +proc defaultGeneric[T](a: T = 2): int = a + +let a = [1, 2, 3, 4].defaultStatic() +let b = defaultGeneric() + +echo a, b + diff --git a/tests/generics/tproctypecache_falsepositive.nim b/tests/generics/tproctypecache_falsepositive.nim new file mode 100644 index 000000000..4f24a1fc8 --- /dev/null +++ b/tests/generics/tproctypecache_falsepositive.nim @@ -0,0 +1,17 @@ + +import asyncdispatch + +type + Callback = proc() {.closure, gcsafe.} + GameState = ref object + playerChangeHandlers: seq[Callback] + +#proc dummy() = +# var x = newSeq[proc() {.cdecl, gcsafe.}]() + +proc newGameState(): GameState = + result = GameState( + playerChangeHandlers: newSeq[Callback]() # this fails + ) + +#dummy() diff --git a/tests/generics/tptrinheritance.nim b/tests/generics/tptrinheritance.nim index 1e1115fa5..221b8777b 100644 --- a/tests/generics/tptrinheritance.nim +++ b/tests/generics/tptrinheritance.nim @@ -10,7 +10,7 @@ proc newMutableArrayAbstract*(): NSMutableArrayAbstract = discard template newMutableArray*(T: typedesc): NSMutableArray[T] = cast[NSMutableArray[T]](newMutableArrayAbstract()) -proc writeObjects*(p: NSPasteboard, o: ptr NSArray[NSPasteboardItem]) = discard +proc writeObjects*(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard let a = newMutableArray NSPasteboardItem var x: NSMutableArray[NSPasteboardItem] diff --git a/tests/generics/treentranttypes.nim b/tests/generics/treentranttypes.nim new file mode 100644 index 000000000..9b4774e9b --- /dev/null +++ b/tests/generics/treentranttypes.nim @@ -0,0 +1,111 @@ +discard """ +output: ''' +(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]] + +2x3 Literal [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0]] + +2x3 Matrix [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + +2x2 ArrayArray[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + +2x3 ArrayVector[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + +2x3 VectorVector [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + +2x3 VectorArray [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + +@[1, 2] +@[1, 2] +@[1, 2]@[3, 4] +@[1, 2]@[3, 4] +''' +""" + +# https://github.com/nim-lang/Nim/issues/5962 + +type + ArrayLike[A, B] = (A, B) + VectorLike*[SIZE, T] = ArrayLike[SIZE, T] + MatrixLike*[M, N, T] = VectorLike[M, VectorLike[N, T]] + +proc tupleTest = + let m: MatrixLike[int, string, float] = (10, ("test", 1.2)) + echo m + +tupleTest() + +type + Vector*[K: static[int], T] = + array[K, T] + + 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], + [2.0, 0.0, 5.0], + [2.0, 0.0, 5.0]] + echo "3x3 Matrix ", repr(mat_good) + + # this does not work with explicit type signature (the matrix seems to always think it is NxN instead) + let mat_fail: Matrix[2, 3, float] = [[0.0, 2.0, 3.0], + [2.0, 0.0, 5.0]] + echo "2x3 Matrix ", repr(mat_fail) + + # this literal seems to work just fine + let mat_also_good = [[0.0, 2.0, 3.0], + [2.0, 0.0, 5.0]] + + echo "2x3 Literal ", repr(mat_also_good) + + # but making a named type out of this leads to pretty nasty runtime behavior + var mat_fail_runtime: Matrix[2, 3, float] + echo "2x3 Matrix ", repr(mat_fail_runtime) + + # cutting out the matrix type middle man seems to solve our problem + var mat_ok_runtime: array[2, array[3, float]] + echo "2x2 ArrayArray", repr(mat_ok_runtime) + + # this is fine too + var mat_ok_runtime_2: array[2, Vector[3, float]] + echo "2x3 ArrayVector", repr(mat_ok_runtime_2) + + # here we are in trouble again + var mat_fail_runtime_2: Vector[2, Vector[3, float]] + echo "2x3 VectorVector ", repr(mat_fail_runtime_2) + + # and here we are fine again + var mat_ok_runtime_3: Vector[2, array[3, float]] + echo "2x3 VectorArray ", repr(mat_ok_runtime_3) + +arrayTest() + +# https://github.com/nim-lang/Nim/issues/5756 + +type + Vec*[N : static[int]] = object + arr*: array[N, int32] + + Mat*[M,N: static[int]] = object + arr*: array[M, Vec[N]] + +proc vec2*(x,y:int32) : Vec[2] = + result.arr = [x,y] + +proc mat2*(a,b: Vec[2]): Mat[2,2] = + result.arr = [a,b] + +const a = vec2(1,2) +echo @(a.arr) +let x = a +echo @(x.arr) + +const b = mat2(vec2(1, 2), vec2(3, 4)) +echo @(b.arr[0].arr), @(b.arr[1].arr) +let y = b +echo @(y.arr[0].arr), @(y.arr[1].arr) + diff --git a/tests/js/tbyvar.nim b/tests/js/tbyvar.nim index f974049b9..705d62574 100644 --- a/tests/js/tbyvar.nim +++ b/tests/js/tbyvar.nim @@ -5,6 +5,12 @@ bar 12 foo 12 bar 12 2 +12.5 +(nums: @[5, 5, 10, 5, 5, 5, 5, 5, 5, 5]) +(nums: @[5, 5, 50, 5, 5, 5, 5, 5, 5, 5]) +(nums: @[5, 5, 45, 5, 5, 5, 5, 5, 5, 5]) +(nums: @[5, 5, 9, 5, 5, 5, 5, 5, 5, 5]) +asd ''' """ @@ -59,3 +65,58 @@ block: # Test var arg inside case expression. #5244 var a = "ok" foo(a) doAssert(a == "ok") + + +proc mainowar = + var x = 9.0 + x += 3.5 + echo x + +mainowar() + + +# bug #5608 + +type Foo = object + nums : seq[float] + +proc newFoo(len : int, default = 0.0) : Foo = + result = Foo() + result.nums = newSeq[float](len) + for i in 0..(len - 1): + result.nums[i] = default + +proc `[]=`(f : var Foo, i : int, v : float) = + f.nums[i] = v + +proc `[]`(f : Foo, i : int) : float = f.nums[i] + +proc `[]`(f : var Foo, i : int) : var float = f.nums[i] + +var f = newFoo(10,5) + +f[2] += 5 +echo f +f[2] *= 5 +echo f +f[2] -= 5 +echo f +f[2] /= 5 +echo f + +# regression for #5608 +import tables + +type + SomeObj = ref object + s: cstring + +var a = initTable[cstring, Table[cstring, SomeObj]]() + +var b = initTable[cstring, SomeObj]() + +b.add(cstring"b", SomeObj(s: cstring"asd")) + +a.add(cstring"a", b) + +echo a[cstring"a"][cstring"b"].s diff --git a/tests/js/tcopying.nim b/tests/js/tcopying.nim index 4f72d6ada..387df9cd3 100644 --- a/tests/js/tcopying.nim +++ b/tests/js/tcopying.nim @@ -1,5 +1,7 @@ discard """ output: '''123 +2 9 +2 9 ''' """ @@ -11,3 +13,25 @@ proc changeArray(a: var MyArray) = var a : MyArray changeArray(a) echo a[0] + +# bug #4703 +# Test 1 +block: + let ary1 = [1, 2, 3] + var ary2 = ary1 + + ary2[1] = 9 + + echo ary1[1], " ", ary2[1] + +# Test 2 +block: + type TestObj = ref object of RootObj + ary2: array[3, int] + + let ary1 = [1, 2, 3] + var obj = TestObj(ary2:ary1) + + obj.ary2[1] = 9 + + echo ary1[1], " ", obj.ary2[1] diff --git a/tests/js/testobjs.nim b/tests/js/testobjs.nim index 0166c0f38..dd66825ec 100644 --- a/tests/js/testobjs.nim +++ b/tests/js/testobjs.nim @@ -1,5 +1,7 @@ discard """ - action: run + output: '''{"columns":[{"t":null},{"t":null}]} +{"columns":[{"t":null},{"t":null}]} +''' """ ## Tests javascript object generation @@ -36,3 +38,19 @@ doAssert test.name == "Jorden" doAssert knight.age == 19 doAssert knight.item.price == 50 doAssert recurse1.next.next.data == 3 + +# bug #6035 +proc toJson*[T](data: T): cstring {.importc: "JSON.stringify".} + +type + Column = object + t: ref Column + + Test2 = object + columns: seq[Column] + +var test1 = Test2(columns: @[Column(t: nil), Column(t: nil)]) +let test2 = test1 + +echo toJSON(test1) +echo toJSON(test2) diff --git a/tests/js/tjshello.nim b/tests/js/tjshello.nim new file mode 100644 index 000000000..19e0b90ae --- /dev/null +++ b/tests/js/tjshello.nim @@ -0,0 +1,10 @@ +discard """ + output: "Hello World" + maxcodesize: 1000 + ccodecheck: "!@'function'" +""" + +import jsconsole + +console.log "Hello World" + diff --git a/tests/js/trefbyvar.nim b/tests/js/trefbyvar.nim index 68dd36543..d440fcc64 100644 --- a/tests/js/trefbyvar.nim +++ b/tests/js/trefbyvar.nim @@ -2,7 +2,9 @@ discard """ output: '''0 5 0 -5''' +5 +@[1, 2] +~''' """ # bug #2476 @@ -33,3 +35,35 @@ proc main = echo t.m main() + +# bug #5974 +type + View* = object + data: ref seq[int] + +let a = View(data: new(seq[int])) +a.data[] = @[1, 2] + +echo a.data[] + +# bug #5379 +var input = newSeq[ref string]() +input.add(nil) +input.add(new string) +input[1][] = "~" +echo input[1][] + +# bug #5517 +type + TypeA1 = object of RootObj + a_impl: int + b_impl: string + c_impl: pointer + +proc initTypeA1(a: int; b: string; c: pointer = nil): TypeA1 = + result.a_impl = a + result.b_impl = b + result.c_impl = c + +let x = initTypeA1(1, "a") +doAssert($x == "(a_impl: 1, b_impl: a, c_impl: ...)") diff --git a/tests/js/tseqops.nim b/tests/js/tseqops.nim new file mode 100644 index 000000000..d10e1ca6a --- /dev/null +++ b/tests/js/tseqops.nim @@ -0,0 +1,51 @@ +discard """ + output: '''(x: 0, y: 0) +(x: 5, y: 0) +@[(x: 2, y: 4), (x: 4, y: 5), (x: 4, y: 5)] +@[(a: 3, b: 3), (a: 1, b: 1), (a: 2, b: 2)] +''' +""" + +# bug #4139 + +type + TestO = object + x, y: int + +proc onLoad() = + var test: seq[TestO] = @[] + var foo = TestO(x: 0, y: 0) + test.add(foo) + foo.x = 5 + echo(test[0]) + echo foo + +onLoad() + +# 'setLen' bug (part of bug #5933) +type MyObj = object + x: cstring + y: int + +proc foo(x: var seq[MyObj]) = + let L = x.len + x.setLen L + 1 + x[L] = x[1] + +var s = @[MyObj(x: "2", y: 4), MyObj(x: "4", y: 5)] +foo(s) +echo s + +# bug #5933 +import sequtils + +type + Test = object + a: cstring + b: int + +var test = @[Test(a: "1", b: 1), Test(a: "2", b: 2)] + +test.insert(@[Test(a: "3", b: 3)], 0) + +echo test diff --git a/tests/js/ttimes.nim b/tests/js/ttimes.nim index 20ba14245..2868c6d0f 100644 --- a/tests/js/ttimes.nim +++ b/tests/js/ttimes.nim @@ -21,6 +21,9 @@ block timestampPersistenceTest: 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: - doAssert $timeString.parse(fmt).toTime().getGMTime() == timeStringGmt + let x = $timeString.parse(fmt).toTime().getGMTime() + doAssert x == timeStringGmt or x == timeStringGmt2 diff --git a/tests/macros/tclosuremacro.nim b/tests/macros/tclosuremacro.nim index c29fbe1c8..9f2137dec 100644 --- a/tests/macros/tclosuremacro.nim +++ b/tests/macros/tclosuremacro.nim @@ -6,10 +6,14 @@ discard """ 3 noReturn 6 +calling mystuff +yes +calling mystuff +yes ''' """ -import future +import future, macros proc twoParams(x: (int, int) -> int): int = result = x(5, 5) @@ -41,3 +45,30 @@ proc pass2(f: (int, int) -> int): (int) -> int = ((x: int) -> int) => f(2, x) echo pass2((x, y) => x + y)(4) + + + +proc register(name: string; x: proc()) = + echo "calling ", name + x() + +register("mystuff", proc () = + echo "yes" +) + +proc helper(x: NimNode): NimNode = + if x.kind == nnkProcDef: + result = copyNimTree(x) + result[0] = newEmptyNode() + result = newCall("register", newLit($x[0]), result) + else: + result = copyNimNode(x) + for i in 0..<x.len: + result.add helper(x[i]) + +macro m(x: untyped): untyped = + result = helper(x) + +m: + proc mystuff() = + echo "yes" diff --git a/tests/macros/tnewlit.nim b/tests/macros/tnewlit.nim new file mode 100644 index 000000000..69245d076 --- /dev/null +++ b/tests/macros/tnewlit.nim @@ -0,0 +1,140 @@ +import macros + +type + MyType = object + a : int + b : string + +macro test_newLit_MyType: untyped = + let mt = MyType(a: 123, b:"foobar") + result = newLit(mt) + +doAssert test_newLit_MyType == MyType(a: 123, b:"foobar") + +macro test_newLit_array: untyped = + let arr = [1,2,3,4,5] + result = newLit(arr) + +doAssert test_newLit_array == [1,2,3,4,5] + +macro test_newLit_seq_int: untyped = + let s: seq[int] = @[1,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[int] = test_newLit_seq_int + doAssert tmp == @[1,2,3,4,5] + +macro test_newLit_seq_int8: untyped = + let s: seq[int8] = @[1'i8,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[int8] = test_newLit_seq_int8 + doAssert tmp == @[1'i8,2,3,4,5] + +macro test_newLit_seq_int16: untyped = + let s: seq[int16] = @[1'i16,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[int16] = test_newLit_seq_int16 + doAssert tmp == @[1'i16,2,3,4,5] + +macro test_newLit_seq_int32: untyped = + let s: seq[int32] = @[1'i32,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[int32] = test_newLit_seq_int32 + doAssert tmp == @[1'i32,2,3,4,5] + +macro test_newLit_seq_int64: untyped = + let s: seq[int64] = @[1'i64,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[int64] = test_newLit_seq_int64 + doAssert tmp == @[1'i64,2,3,4,5] + +macro test_newLit_seq_uint: untyped = + let s: seq[uint] = @[1u,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[uint] = test_newLit_seq_uint + doAssert tmp == @[1u,2,3,4,5] + +macro test_newLit_seq_uint8: untyped = + let s: seq[uint8] = @[1'u8,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[uint8] = test_newLit_seq_uint8 + doAssert tmp == @[1'u8,2,3,4,5] + +macro test_newLit_seq_uint16: untyped = + let s: seq[uint16] = @[1'u16,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[uint16] = test_newLit_seq_uint16 + doAssert tmp == @[1'u16,2,3,4,5] + +macro test_newLit_seq_uint32: untyped = + let s: seq[uint32] = @[1'u32,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[uint32] = test_newLit_seq_uint32 + doAssert tmp == @[1'u32,2,3,4,5] + +macro test_newLit_seq_uint64: untyped = + let s: seq[uint64] = @[1'u64,2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[uint64] = test_newLit_seq_uint64 + doAssert tmp == @[1'u64,2,3,4,5] + +macro test_newLit_seq_float: untyped = + let s: seq[float] = @[1.0, 2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[float] = test_newLit_seq_float + doAssert tmp == @[1.0, 2,3,4,5] + +macro test_newLit_seq_float32: untyped = + let s: seq[float32] = @[1.0'f32, 2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[float32] = test_newLit_seq_float32 + doAssert tmp == @[1.0'f32, 2,3,4,5] + +macro test_newLit_seq_float64: untyped = + let s: seq[float64] = @[1.0'f64, 2,3,4,5] + result = newLit(s) + +block: + let tmp: seq[float64] = test_newLit_seq_float64 + doAssert tmp == @[1.0'f64, 2,3,4,5] + +macro test_newLit_tuple: untyped = + let tup: tuple[a:int,b:string] = (a: 123, b: "223") + result = newLit(tup) + +doAssert test_newLit_tuple == (a: 123, b: "223") + +type + ComposedType = object + mt: MyType + arr: array[4,int] + data: seq[byte] + +macro test_newLit_ComposedType: untyped = + let ct = ComposedType(mt: MyType(a: 123, b:"abc"), arr: [1,2,3,4], data: @[1.byte, 3, 7, 127]) + result = newLit(ct) + +doAssert test_newLit_ComposedType == ComposedType(mt: MyType(a: 123, b:"abc"), arr: [1,2,3,4], data: @[1.byte, 3, 7, 127]) diff --git a/tests/macros/tnodecompare.nim b/tests/macros/tnodecompare.nim index 3870c7559..b9cf7df48 100644 --- a/tests/macros/tnodecompare.nim +++ b/tests/macros/tnodecompare.nim @@ -1,33 +1,33 @@ -discard """ -output: '''true -false -true -false -true -false -true -false''' -""" - import macros +static: + let nodeA = newCommentStmtNode("this is a comment") + doAssert nodeA.repr == "## this is a comment" + doAssert nodeA.strVal == "this is a comment" + doAssert $nodeA == "this is a comment" + + let nodeB = newCommentStmtNode("this is a comment") + doAssert nodeA == nodeB + nodeB.strVal = "this is a different comment" + doAssert nodeA != nodeB + macro test(a: typed, b: typed): expr = newLit(a == b) -echo test(1, 1) -echo test(1, 2) +doAssert test(1, 1) == true +doAssert test(1, 2) == false type Obj = object of RootObj Other = object of RootObj -echo test(Obj, Obj) -echo test(Obj, Other) +doAssert test(Obj, Obj) == true +doAssert test(Obj, Other) == false var a, b: int -echo test(a, a) -echo test(a, b) +doAssert test(a, a) == true +doAssert test(a, b) == false macro test2: expr = newLit(bindSym"Obj" == bindSym"Obj") @@ -35,5 +35,5 @@ macro test2: expr = macro test3: expr = newLit(bindSym"Obj" == bindSym"Other") -echo test2() -echo test3() +doAssert test2() == true +doAssert test3() == false diff --git a/tests/metatype/tmatrix4.nim b/tests/metatype/tmatrix4.nim new file mode 100644 index 000000000..207d76fed --- /dev/null +++ b/tests/metatype/tmatrix4.nim @@ -0,0 +1,39 @@ +import math + +type + TMatrix*[T; R, C: static[int]] = array[R, array[C, T]] ## Row major matrix type. + TMat4* = TMatrix[float32, 4, 4] + TVector*[T; C: static[int]] = array[C, T] + TVec4* = TVector[float32, 4] + +template row*[T; R, C: static[int]](m: TMatrix[T, R, C], rowidx: range[0..R-1]): TVector[T, R] = + m[rowidx] + +proc col*[T; R, C: static[int]](m: TMatrix[T, R, C], colidx: range[0..C-1]): TVector[T, C] {.noSideEffect.} = + for i in low(m)..high(m): + result[i] = m[i][colidx] + +proc dot(lhs, rhs: TVector): float32 = + for i in low(rhs)..high(rhs): + result += lhs[i] * rhs[i] + +proc `*`*[T; R, N, C: static[int]](a: TMatrix[T, R, N], b: TMatrix[T, N, C]): TMatrix[T, R, C] {.noSideEffect.} = + for i in low(a)..high(a): + for j in low(a[i])..high(a[i]): + result[i][j] = dot(a.row(i), b.col(j)) + +proc translate*(v: TVec4): TMat4 {.noSideEffect.} = + result = [[1f32, 0f32, 0f32, 0f32], + [0f32, 1f32, 0f32, 0f32], + [0f32, 0f32, 1f32, 0f32], + [v[0], v[1], v[2], 1f32]] + +proc rotatex*(angle: float): TMat4 = + result = [[1f32, 0f32, 0f32, 0f32], + [0f32, cos(angle).float32, sin(angle).float32, 0f32], + [0f32, -sin(angle).float32, cos(angle).float32, 0f32], + [0f32, 0f32, 0f32, 1f32]] + +proc orbitxAround(point: TVec4, angle: float): TMat4 = + result = translate(point)*rotatex(angle)*translate(point) + diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index 11653e563..69b62e4a6 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -1,6 +1,6 @@ discard """ file: "tstaticparams.nim" - output: "abracadabra\ntest\n3\n15\n4\n2\nfloat\n3\nfloat\nyin\nyang" + output: "abracadabra\ntest\n3\n15\n4\n2\nfloat\n3\nfloat\nyin\nyang\n2\n4\n4\n2\n3" """ type @@ -140,3 +140,36 @@ dontBind1 bb_2 dontBind2 bb_1 dontBind2 bb_2 +# https://github.com/nim-lang/Nim/issues/4524 +const + size* = 2 + +proc arraySize[N: static[int]](A: array[N, int]): int = + result = A.high - A.low + 1 + +var A: array[size, int] = [1, 2] +echo arraySize(A) + +# https://github.com/nim-lang/Nim/issues/3153 + +proc outSize1[M: static[int], A](xs: array[M, A]): int = M +echo outSize1([1, 2, 3, 4]) + +type + Arr[N: static[int], A] = array[N, A] + +proc outSize2[M: static[int], A](xs: Arr[M, A]): int = M +echo outSize2([1, 2, 3, 4]) # 4 + +echo outSize2([ + [1, 2, 3], + [4, 5, 6] +]) # 2 + +proc inSize[M, N: static[int]](xs: Arr[M, Arr[N, int]]): int = N + +echo inSize([ + [1, 2, 3], + [4, 5, 6] +]) + diff --git a/tests/metatype/tstaticvector.nim b/tests/metatype/tstaticvector.nim index 69ee0e935..1a7bdeafe 100644 --- a/tests/metatype/tstaticvector.nim +++ b/tests/metatype/tstaticvector.nim @@ -2,7 +2,9 @@ discard """ output: '''0 0 2 -100''' +100 +30.0 [data = [2.0]] +''' """ type @@ -16,13 +18,12 @@ type proc foo*[N, T](a: StaticVector[N, T]): T = 0.T proc foobar*[N, T](a, b: StaticVector[N, T]): T = 0.T - var a: StaticVector[3, int] echo foo(a) # OK echo foobar(a, a) # <--- hangs compiler -# bug #3112 +# https://github.com/nim-lang/Nim/issues/3112 type Vector[N: static[int]] = array[N, float64] @@ -30,10 +31,45 @@ type a: Vector[Na] b: Vector[Nb] -when isMainModule: - var v: TwoVectors[2, 100] - echo v[0].len - echo v[1].len - #let xx = 50 - v[1][50] = 0.0 +var v: TwoVectors[2, 100] +echo v[0].len +echo v[1].len +#let xx = 50 +v[1][50] = 0.0 + +# https://github.com/nim-lang/Nim/issues/1051 + +type + TMatrix[N,M: static[int], T] = object + data: array[0..M*N-1, T] + + TMat4f = TMatrix[4,4,float32] + TVec3f = TMatrix[1,3,float32] + TVec4f = TMatrix[1,4,float32] + + TVec[N: static[int]; T] = TMatrix[1,N,T] + +proc dot*(a, b: TVec): TVec.T = + #assert(a.data.len == b.data.len) + for i in 1..a.data.len: + result += a.data[i-1] * b.data[i-1] + +proc row*(a: TMatrix; i: int): auto = + result = TVec[TMatrix.M, TMatrix.T]() + for idx in 1 .. TMatrix.M: + result.data[idx-1] = a.data[(TMatrix.N * (idx-1)) + (i-1)] + +proc col*(a: TMatrix; j: int): auto = + result = TVec[TMatrix.N, TMatrix.T]() + for idx in 0 .. <TMatrix.N: + result.data[idx] = a.data[(TMatrix.N * (idx)) + (j-1)] + +proc mul*(a: TMat4f; b: TMat4f): TMat4f = + for i in 1..4: + for j in 1..4: + result.data[(4 * (j-1)) + (i-1)] = dot(row(a,i), col(b,j)) + +var test = TVec4f(data: [1.0'f32, 2.0'f32, 3.0'f32, 4.0'f32]) + +echo dot(test,test), " ", repr(col(test, 2)) diff --git a/tests/misc/tcast.nim b/tests/misc/tcast.nim new file mode 100644 index 000000000..4e27040fb --- /dev/null +++ b/tests/misc/tcast.nim @@ -0,0 +1,23 @@ +discard """ + output: ''' +Hello World +Hello World''' +""" +type MyProc = proc() {.cdecl.} +type MyProc2 = proc() {.nimcall.} +type MyProc3 = proc() #{.closure.} is implicit + +proc testProc() = echo "Hello World" + +proc callPointer(p: pointer) = + # can cast to proc(){.cdecl.} + let ffunc0 = cast[MyProc](p) + # can cast to proc(){.nimcall.} + let ffunc1 = cast[MyProc2](p) + # cannot cast to proc(){.closure.} + doAssert(not compiles(cast[MyProc3](p))) + + ffunc0() + ffunc1() + +callPointer(cast[pointer](testProc)) diff --git a/tests/misc/tparseopt.nim b/tests/misc/tparseopt.nim new file mode 100644 index 000000000..1f8375dfd --- /dev/null +++ b/tests/misc/tparseopt.nim @@ -0,0 +1,57 @@ +discard """ + file: "tparseopt.nim" + output: ''' +parseopt +first round +kind: cmdLongOption key:val -- left: +second round +kind: cmdLongOption key:val -- left: +kind: cmdLongOption key:val -- debug:3 +kind: cmdShortOption key:val -- l:4 +kind: cmdShortOption key:val -- r:2 +parseopt2 +first round +kind: cmdLongOption key:val -- left: +second round +kind: cmdLongOption key:val -- left: +kind: cmdLongOption key:val -- debug:3 +kind: cmdShortOption key:val -- l:4 +kind: cmdShortOption key:val -- r:2''' +""" +from parseopt import nil +from parseopt2 import nil + + +block: + echo "parseopt" + for kind, key, val in parseopt.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + + # pass custom cmdline arguments + echo "first round" + var argv = "--left --debug:3 -l=4 -r:2" + var p = parseopt.initOptParser(argv) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + +block: + echo "parseopt2" + for kind, key, val in parseopt2.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + + # pass custom cmdline arguments + echo "first round" + var argv: seq[string] = @["--left", "--debug:3", "-l=4", "-r:2"] + var p = parseopt2.initOptParser(argv) + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val diff --git a/tests/modules/tmismatchedvisibility.nim b/tests/modules/tmismatchedvisibility.nim index 325c729c0..91b639a27 100644 --- a/tests/modules/tmismatchedvisibility.nim +++ b/tests/modules/tmismatchedvisibility.nim @@ -1,6 +1,6 @@ discard """ line: 8 - errormsg: "public implementation 'tmismatchedvisibility.foo(a: int)' has non-public forward declaration in " + errormsg: "public implementation 'tmismatchedvisibility.foo(a: int)[declared in tmismatchedvisibility.nim(6,5)]' has non-public forward declaration in " """ proc foo(a: int): int diff --git a/tests/overload/tstaticoverload.nim b/tests/overload/tstaticoverload.nim new file mode 100644 index 000000000..33ca49e56 --- /dev/null +++ b/tests/overload/tstaticoverload.nim @@ -0,0 +1,30 @@ +discard """ +output: ''' +dynamic: let +dynamic: var +static: const +static: literal +static: constant folding +static: static string +''' +""" + +proc foo(s: string) = + echo "dynamic: ", s + +proc foo(s: static[string]) = + echo "static: ", s + +let l = "let" +var v = "var" +const c = "const" + +type staticString = static[string] + +foo(l) +foo(v) +foo(c) +foo("literal") +foo("constant" & " " & "folding") +foo(staticString("static string")) + diff --git a/tests/pragmas/tused.nim b/tests/pragmas/tused.nim index 4a317f874..389863aef 100644 --- a/tests/pragmas/tused.nim +++ b/tests/pragmas/tused.nim @@ -1,7 +1,7 @@ discard """ nimout: ''' compile start -tused.nim(15, 8) Hint: 'tused.echoSub(a: int, b: int)' is declared but not used [XDeclaredButNotUsed] +tused.nim(15, 8) Hint: 'tused.echoSub(a: int, b: int)[declared in tused.nim(15,7)]' is declared but not used [XDeclaredButNotUsed] compile end''' output: "8\n8" """ diff --git a/tests/statictypes/t3784.nim b/tests/statictypes/t3784.nim new file mode 100644 index 000000000..3414d9802 --- /dev/null +++ b/tests/statictypes/t3784.nim @@ -0,0 +1,20 @@ +discard """ +output: "T[1, 1]" +""" + +# https://github.com/nim-lang/Nim/issues/3784 + +import typetraits + +type + S[N: static[int]] = object + T[A,B: static[int]] = object + + C = S[1] + +var + x: T[1,1] + y: T[C.N, C.N] + +echo y.type.name + diff --git a/tests/statictypes/texplicitprocparams.nim b/tests/statictypes/texplicitprocparams.nim new file mode 100644 index 000000000..d1e717dbf --- /dev/null +++ b/tests/statictypes/texplicitprocparams.nim @@ -0,0 +1,19 @@ +discard """ +output: ''' +(x: 100) +5 +''' +""" + +type + OdArray*[As: static[int], T] = object + x: int + +proc initOdArray*[As: static[int], T](len: int): OdArray[As, T] = + result.x = len + +echo initOdArray[10, int](100) + +proc doStatic[N: static[int]](): int = N +echo doStatic[5]() + diff --git a/tests/statictypes/tpassthruarith.nim b/tests/statictypes/tpassthruarith.nim new file mode 100644 index 000000000..90fc7824c --- /dev/null +++ b/tests/statictypes/tpassthruarith.nim @@ -0,0 +1,54 @@ +discard """ +output: ''' +[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] + +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + +[1, 2, 3, 4] +''' +""" + +# https://github.com/nim-lang/Nim/issues/4880 + +proc `^^`(x: int): int = x * 2 + +type + Foo[x: static[int]] = array[x, int] + Bar[a, b: static[int]] = array[b, Foo[^^a]] + +var x: Bar[2, 3] +echo repr(x) + +# https://github.com/nim-lang/Nim/issues/2730 + +type + Matrix[M,N: static[int]] = distinct array[0..(M*N - 1), int] + +proc bigger[M,N](m: Matrix[M,N]): Matrix[(M * N) div 8, (M * N)] = + discard + +proc bigger2[M,N](m: Matrix[M,N]): Matrix[M * 2, N * 2] = + discard + +var m : Matrix[4, 4] +var n = bigger(m) +var o = bigger2(m) + +echo repr(m) +echo repr(n) +echo repr(o) + +type + Vect[N: static[int], A] = array[N, A] + +proc push[N: static[int], A](a: Vect[N, A], x: A): Vect[N + 1, A] = + for n in 0 .. < N: + result[n] = a[n] + result[N] = x + +echo repr(push([1, 2, 3], 4)) + diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 323b3e1ee..32d848e06 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -226,4 +226,24 @@ when isMainModule: let x = parseJson("""{ "field": 5}""") let data = to(x, FooBar) - doAssert data.field == 5.0 \ No newline at end of file + doAssert data.field == 5.0 + + block: + type + BirdColor = object + name: string + rgb: array[3, float] + + type + Bird = object + age: int + height: float + name: string + colors: array[2, BirdColor] + + var red = BirdColor(name: "red", rgb: [1.0, 0.0, 0.0]) + var blue = Birdcolor(name: "blue", rgb: [0.0, 0.0, 1.0]) + 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 diff --git a/tests/stdlib/tjsontestsuite.nim b/tests/stdlib/tjsontestsuite.nim new file mode 100644 index 000000000..06f783a73 --- /dev/null +++ b/tests/stdlib/tjsontestsuite.nim @@ -0,0 +1,384 @@ +## JSON tests based on https://github.com/nst/JSONTestSuite + +import unittest, + json, + strutils + +let parsing_testdata = { + "i_number_neg_int_huge_exp": """[-1e+9999]""", + "i_number_pos_double_huge_exp": """[1.5e+9999]""", + "i_object_key_lone_2nd_surrogate": """{"\uDFAA":0}""", + "i_string_1st_surrogate_but_2nd_missing": """["\uDADA"]""", + "i_string_1st_valid_surrogate_2nd_invalid": """["\uD888\u1234"]""", + "i_string_incomplete_surrogate_and_escape_valid": """["\uD800\n"]""", + "i_string_incomplete_surrogate_pair": """["\uDd1ea"]""", + "i_string_incomplete_surrogates_escape_valid": """["\uD800\uD800\n"]""", + "i_string_inverted_surrogates_U+1D11E": """["\uDd1e\uD834"]""", + "i_string_lone_second_surrogate": """["\uDFAA"]""", + "i_string_not_in_unicode_range": """[""]""", + "i_string_truncated-utf-8": """[""]""", + "i_string_unicode_U+10FFFE_nonchar": """["\uDBFF\uDFFE"]""", + "i_string_unicode_U+1FFFE_nonchar": """["\uD83F\uDFFE"]""", + "i_string_unicode_U+FDD0_nonchar": """["\uFDD0"]""", + "i_string_unicode_U+FFFE_nonchar": """["\uFFFE"]""", + "i_string_UTF-16_invalid_lonely_surrogate": """["\ud800"]""", + "i_string_UTF-16_invalid_surrogate": """["\ud800abc"]""", + "i_string_UTF-8_invalid_sequence": """["日ш"]""", + "i_structure_500_nested_arrays": """[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]""", + "i_structure_UTF-8_BOM_empty_object": """{}""", + "n_array_1_true_without_comma": """[1 true]""", + "n_array_a_invalid_utf8": """[a]""", + "n_array_colon_instead_of_comma": """["": 1]""", + "n_array_comma_after_close": """[""],""", + "n_array_comma_and_number": """[,1]""", + "n_array_double_comma": """[1,,2]""", + "n_array_double_extra_comma": """["x",,]""", + "n_array_extra_close": """["x"]]""", + "n_array_extra_comma": """["",]""", + "n_array_incomplete_invalid_value": """[x""", + "n_array_incomplete": """["x"""", + "n_array_inner_array_no_comma": """[3[4]]""", + "n_array_invalid_utf8": """[]""", + "n_array_items_separated_by_semicolon": """[1:2]""", + "n_array_just_comma": """[,]""", + "n_array_just_minus": """[-]""", + "n_array_missing_value": """[ , ""]""", + "n_array_newlines_unclosed": """["a",""", + "n_array_newlines_unclosed": """4""", + "n_array_newlines_unclosed": """,1,""", + "n_array_number_and_comma": """[1,]""", + "n_array_number_and_several_commas": """[1,,]""", + "n_array_spaces_vertical_tab_formfeed": """["a"\f]""", + "n_array_star_inside": """[*]""", + "n_array_unclosed": """[""""", + "n_array_unclosed_trailing_comma": """[1,""", + "n_array_unclosed_with_new_lines": """[1,""", + "n_array_unclosed_with_new_lines": """1""", + "n_array_unclosed_with_new_lines": """,1""", + "n_array_unclosed_with_object_inside": """[{}""", + "n_incomplete_false": """[fals]""", + "n_incomplete_null": """[nul]""", + "n_incomplete_true": """[tru]""", + "n_number_0.1.2": """[0.1.2]""", + "n_number_-01": """[-01]""", + "n_number_0.3e": """[0.3e]""", + "n_number_0.3e+": """[0.3e+]""", + "n_number_0_capital_E": """[0E]""", + "n_number_0_capital_E+": """[0E+]""", + "n_number_0.e1": """[0.e1]""", + "n_number_0e": """[0e]""", + "n_number_0e+": """[0e+]""", + "n_number_1_000": """[1 000.0]""", + "n_number_1.0e-": """[1.0e-]""", + "n_number_1.0e": """[1.0e]""", + "n_number_1.0e+": """[1.0e+]""", + "n_number_-1.0.": """[-1.0.]""", + "n_number_1eE2": """[1eE2]""", + "n_number_.-1": """[.-1]""", + "n_number_+1": """[+1]""", + "n_number_.2e-3": """[.2e-3]""", + "n_number_2.e-3": """[2.e-3]""", + "n_number_2.e+3": """[2.e+3]""", + "n_number_2.e3": """[2.e3]""", + "n_number_-2.": """[-2.]""", + "n_number_9.e+": """[9.e+]""", + "n_number_expression": """[1+2]""", + "n_number_hex_1_digit": """[0x1]""", + "n_number_hex_2_digits": """[0x42]""", + "n_number_infinity": """[Infinity]""", + "n_number_+Inf": """[+Inf]""", + "n_number_Inf": """[Inf]""", + "n_number_invalid+-": """[0e+-1]""", + "n_number_invalid-negative-real": """[-123.123foo]""", + "n_number_invalid-utf-8-in-bigger-int": """[123]""", + "n_number_invalid-utf-8-in-exponent": """[1e1]""", + "n_number_invalid-utf-8-in-int": """[0]""", + "n_number_++": """[++1234]""", + "n_number_minus_infinity": """[-Infinity]""", + "n_number_minus_sign_with_trailing_garbage": """[-foo]""", + "n_number_minus_space_1": """[- 1]""", + "n_number_-NaN": """[-NaN]""", + "n_number_NaN": """[NaN]""", + "n_number_neg_int_starting_with_zero": """[-012]""", + "n_number_neg_real_without_int_part": """[-.123]""", + "n_number_neg_with_garbage_at_end": """[-1x]""", + "n_number_real_garbage_after_e": """[1ea]""", + "n_number_real_with_invalid_utf8_after_e": """[1e]""", + "n_number_real_without_fractional_part": """[1.]""", + "n_number_starting_with_dot": """[.123]""", + "n_number_then_00": """1\x00""", + "n_number_U+FF11_fullwidth_digit_one": """[1]""", + "n_number_with_alpha_char": """[1.8011670033376514H-308]""", + "n_number_with_alpha": """[1.2a-3]""", + "n_number_with_leading_zero": """[012]""", + "n_object_bad_value": """["x", truth]""", + "n_object_bracket_key": """{[: "x"}""", + "n_object_comma_instead_of_colon": """{"x", null}""", + "n_object_double_colon": """{"x"::"b"}""", + "n_object_emoji": """{🇨🇭}""", + "n_object_garbage_at_end": """{"a":"a" 123}""", + "n_object_key_with_single_quotes": """{key: 'value'}""", + "n_object_missing_colon": """{"a" b}""", + "n_object_missing_key": """{:"b"}""", + "n_object_missing_semicolon": """{"a" "b"}""", + "n_object_missing_value": """{"a":""", + "n_object_no-colon": """{"a"""", + "n_object_non_string_key_but_huge_number_instead": """{9999E9999:1}""", + "n_object_non_string_key": """{1:1}""", + "n_object_pi_in_key_and_trailing_comma": """{"":"0",}""", + "n_object_repeated_null_null": """{null:null,null:null}""", + "n_object_several_trailing_commas": """{"id":0,,,,,}""", + "n_object_single_quote": """{'a':0}""", + "n_object_trailing_comma": """{"id":0,}""", + "n_object_trailing_comment": """{"a":"b"}/**/""", + "n_object_trailing_comment_open": """{"a":"b"}/**//""", + "n_object_trailing_comment_slash_open_incomplete": """{"a":"b"}/""", + "n_object_trailing_comment_slash_open": """{"a":"b"}//""", + "n_object_two_commas_in_a_row": """{"a":"b",,"c":"d"}""", + "n_object_unquoted_key": """{a: "b"}""", + "n_object_unterminated-value": """{"a":"a""", + "n_object_with_single_string": """{ "foo" : "bar", "a" }""", + "n_object_with_trailing_garbage": """{"a":"b"}#""", + "n_single_space": """ """, + "n_string_1_surrogate_then_escape": """["\uD800\"]""", + "n_string_1_surrogate_then_escape u1": """["\uD800\u1"]""", + "n_string_1_surrogate_then_escape u1x": """["\uD800\u1x"]""", + "n_string_1_surrogate_then_escape u": """["\uD800\u"]""", + "n_string_accentuated_char_no_quotes": """[é]""", + "n_string_backslash_00": """["\\x00"]""", + "n_string_escaped_backslash_bad": """["\\\"]""", + "n_string_escaped_ctrl_char_tab": """["\ "]""", + "n_string_escaped_emoji": """["\🌀"]""", + "n_string_escape_x": """["\x00"]""", + "n_string_incomplete_escaped_character": """["\u00A"]""", + "n_string_incomplete_escape": """["\"]""", + "n_string_incomplete_surrogate_escape_invalid": """["\uD800\uD800\x"]""", + "n_string_invalid_backslash_esc": """["\a"]""", + "n_string_invalid_unicode_escape": """["\uqqqq"]""", + "n_string_invalid_utf8_after_escape": """["\"]""", + "n_string_invalid-utf-8-in-escape": """["\u"]""", + "n_string_invalid_utf-8": """[""]""", + "n_string_iso_latin_1": """[""]""", + "n_string_leading_uescaped_thinspace": """[\u0020"asd"]""", + "n_string_lone_utf8_continuation_byte": """[""]""", + "n_string_no_quotes_with_bad_escape": """[\n]""", + "n_string_overlong_sequence_2_bytes": """[""]""", + "n_string_overlong_sequence_6_bytes": """[""]""", + "n_string_overlong_sequence_6_bytes_null": """[""]""", + "n_string_single_doublequote": """"""", + "n_string_single_quote": """['single quote']""", + "n_string_single_string_no_double_quotes": """abc""", + "n_string_start_escape_unclosed": """["\""", + "n_string_unescaped_ctrl_char": """["a\x00a"]""", + "n_string_unescaped_newline": """["new +line"]""", + "n_string_unescaped_tab": """[" "]""", + "n_string_unicode_CapitalU": """"\UA66D"""", + "n_string_UTF-16_incomplete_surrogate": """["\uD834\uDd"]""", + "n_string_UTF8_surrogate_U+D800": """[""]""", + "n_string_with_trailing_garbage": """""x""", + "n_structure_array_trailing_garbage": """[1]x""", + "n_structure_array_with_extra_array_close": """[1]]""", + "n_structure_array_with_unclosed_string": """["asd]""", + "n_structure_ascii-unicode-identifier": """aå""", + "n_structure_capitalized_True": """[True]""", + "n_structure_close_unopened_array": """1]""", + "n_structure_comma_instead_of_closing_brace": """{"x": true,""", + "n_structure_double_array": """[][]""", + "n_structure_end_array": """]""", + "n_structure_incomplete_UTF8_BOM": """{}""", + "n_structure_<.>": """<.>""", + "n_structure_lone-invalid-utf-8": """""", + "n_structure_lone-open-bracket": """[""", + "n_structure_null-byte-outside-string": """[\00]""", + "n_structure_<null>": """[<null>]""", + "n_structure_number_with_trailing_garbage": """2@""", + "n_structure_object_followed_by_closing_object": """{}}""", + "n_structure_object_unclosed_no_value": """{"":""", + "n_structure_object_with_comment": """{"a":/*comment*/"b"}""", + "n_structure_object_with_trailing_garbage": """{"a": true} "x"""", + "n_structure_open_array_apostrophe": """['""", + "n_structure_open_array_comma": """[,""", + "n_structure_open_array_open_object": """[{""", + "n_structure_open_array_open_string": """["a""", + "n_structure_open_array_string": """["a"""", + "n_structure_open_object_close_array": """{]""", + "n_structure_open_object_comma": """{,""", + "n_structure_open_object": """{""", + "n_structure_open_object_open_array": """{[""", + "n_structure_open_object_open_string": """{"a""", + "n_structure_open_object_string_with_apostrophes": """{'a'""", + "n_structure_open_open": """["\{["\{["\{["\{""", + "n_structure_single_point": """""", + "n_structure_single_star": """*""", + "n_structure_trailing_#": """{"a":"b"}#{}""", + "n_structure_U+2060_word_joined": """[]""", + "n_structure_uescaped_LF_before_string": """[\u000A""]""", + "n_structure_unclosed_array": """[1""", + "n_structure_unclosed_array_partial_null": """[ false, nul""", + "n_structure_unclosed_array_unfinished_false": """[ true, fals""", + "n_structure_unclosed_array_unfinished_true": """[ false, tru""", + "n_structure_unclosed_object": """{"asd":"asd"""", + "n_structure_unicode-identifier": """å""", + "n_structure_UTF8_BOM_no_data": """""", + "n_structure_whitespace_formfeed": """[]""", + "n_structure_whitespace_U+2060_word_joiner": """[]""", + "y_array_arraysWithSpaces": """[[] ]""", + "y_array_empty": """[]""", + "y_array_empty-string": """[""]""", + "y_array_ending_with_newline": """["a"]""", + "y_array_false": """[false]""", + "y_array_heterogeneous": """[null, 1, "1", {}]""", + "y_array_null": """[null]""", + "y_array_with_1_and_newline": """[1 +]""", + "y_array_with_leading_space": """ [1]""", + "y_array_with_several_null": """[1,null,null,null,2]""", + "y_array_with_trailing_space": """[2] """, + "y_number_0e+1": """[0e+1]""", + "y_number_0e1": """[0e1]""", + "y_number_after_space": """[ 4]""", + "y_number_double_close_to_zero": """[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]""", + "y_number_double_huge_neg_exp": """[123.456e-789]""", + "y_number_huge_exp": """[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]""", + "y_number_int_with_exp": """[20e1]""", + "y_number": """[123e65]""", + "y_number_minus_zero": """[-0]""", + "y_number_negative_int": """[-123]""", + "y_number_negative_one": """[-1]""", + "y_number_negative_zero": """[-0]""", + "y_number_real_capital_e": """[1E22]""", + "y_number_real_capital_e_neg_exp": """[1E-2]""", + "y_number_real_capital_e_pos_exp": """[1E+2]""", + "y_number_real_exponent": """[123e45]""", + "y_number_real_fraction_exponent": """[123.456e78]""", + "y_number_real_neg_exp": """[1e-2]""", + "y_number_real_neg_overflow": """[-123123e100000]""", + "y_number_real_pos_exponent": """[1e+2]""", + "y_number_real_pos_overflow": """[123123e100000]""", + "y_number_real_underflow": """[123e-10000000]""", + "y_number_simple_int": """[123]""", + "y_number_simple_real": """[123.456789]""", + "y_number_too_big_neg_int": """[-123123123123123123123123123123]""", + "y_number_too_big_pos_int": """[100000000000000000000]""", + "y_number_very_big_negative_int": """[-237462374673276894279832749832423479823246327846]""", + "y_object_basic": """{"asd":"sdf"}""", + "y_object_duplicated_key_and_value": """{"a":"b","a":"b"}""", + "y_object_duplicated_key": """{"a":"b","a":"c"}""", + "y_object_empty": """{}""", + "y_object_empty_key": """{"":0}""", + "y_object_escaped_null_in_key": """{"foo\u0000bar": 42}""", + "y_object_extreme_numbers": """{ "min": -1.0e+28, "max": 1.0e+28 }""", + "y_object": """{"asd":"sdf", "dfg":"fgh"}""", + "y_object_long_strings": """{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}""", + "y_object_simple": """{"a":[]}""", + "y_object_string_unicode": """{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }""", + "y_object_with_newlines": """{ +"a": "b" +}""", + "y_string_1_2_3_bytes_UTF-8_sequences": """["\u0060\u012a\u12AB"]""", + "y_string_accepted_surrogate_pair": """["\uD801\udc37"]""", + "y_string_accepted_surrogate_pairs": """["\ud83d\ude39\ud83d\udc8d"]""", + "y_string_allowed_escapes": """["\"\\\/\b\f\n\r\t"]""", + "y_string_backslash_and_u_escaped_zero": """["\\u0000"]""", + "y_string_backslash_doublequotes": """["\""]""", + "y_string_comments": """["a/*b*/c/*d//e"]""", + "y_string_double_escape_a": """["\\a"]""", + "y_string_double_escape_n": """["\\n"]""", + "y_string_escaped_control_character": """["\u0012"]""", + "y_string_escaped_noncharacter": """["\uFFFF"]""", + "y_string_in_array": """["asd"]""", + "y_string_in_array_with_leading_space": """[ "asd"]""", + "y_string_last_surrogates_1_and_2": """["\uDBFF\uDFFF"]""", + "y_string_newline_uescaped": """["new\u00A0line"]""", + "y_string_nonCharacterInUTF-8_U+10FFFF": """[""]""", + "y_string_nonCharacterInUTF-8_U+1FFFF": """[""]""", + "y_string_nonCharacterInUTF-8_U+FFFF": """[""]""", + "y_string_null_escape": """["\u0000"]""", + "y_string_one-byte-utf-8": """["\u002c"]""", + "y_string_pi": """["π"]""", + "y_string_simple_ascii": """["asd "]""", + "y_string_space": """" """", + "y_string_three-byte-utf-8": """["\u0821"]""", + "y_string_two-byte-utf-8": """["\u0123"]""", + "y_string_u+2028_line_sep": """[" "]""", + "y_string_u+2029_par_sep": """[" "]""", + "y_string_uEscape": """["\u0061\u30af\u30EA\u30b9"]""", + "y_string_unescaped_char_delete": """[""]""", + "y_string_unicode_2": """["⍂㈴⍂"]""", + "y_string_unicodeEscapedBackslash": """["\u005C"]""", + "y_string_unicode_escaped_double_quote": """["\u0022"]""", + "y_string_unicode": """["\uA66D"]""", + "y_string_unicode_U+200B_ZERO_WIDTH_SPACE": """["\u200B"]""", + "y_string_unicode_U+2064_invisible_plus": """["\u2064"]""", + "y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF": """["\uD834\uDd1e"]""", + "y_string_utf8": """["€𝄞"]""", + "y_string_with_del_character": """["aa"]""", + "y_structure_lonely_false": """false""", + "y_structure_lonely_int": """42""", + "y_structure_lonely_negative_real": """-0.1""", + "y_structure_lonely_null": """null""", + "y_structure_lonely_string": """"asd"""", + "y_structure_lonely_true": """true""", + "y_structure_string_empty": """""""", + "y_structure_trailing_newline": """["a"]""", + "y_structure_true_in_array": """[true]""", + "y_structure_whitespace_array": """ [] """, +} + + +suite "JSON": + + test "Multiple parsing tests": + var test_is_failed = false + for test_item in parsing_testdata: + + let name = test_item[0] + let data = test_item[1] + var + parsed_successfully = false + parsed: JsonNode + exception_while_parsing = "" + exception_while_rendering = "" + + try: + parsed = parseJson(data) + parsed_successfully = true + except: + exception_while_parsing = getCurrentExceptionMsg() + + + proc echo_summary(msg: string) = + var rendered = "" + var render_successfully = false + if parsed_successfully: + try: + rendered = $parsed + render_successfully = true + except: + rendered = "[Fail to render:<$#>]" % getCurrentExceptionMsg() + else: + rendered = "<$#>" % exception_while_parsing + + echo name, repeat(' ', 60 - name.len), "[$#]" % msg, " ", rendered + + case name[0] + of 'y': + # Tests starting with y_ must parse + if not parsed_successfully: + echo_summary "Failed to parse" + test_is_failed = true + of 'n': + # Tests starting with n_ should not parse + if parsed_successfully: + echo_summary "Failed to raise exception" + of 'i': + if parsed_successfully: + echo_summary "OK" + else: + echo_summary "Not parsed" + + else: discard + + # FIXME: temporarily disabled until "y_" tests will succeed + # if test_is_failed: fail() diff --git a/tests/stdlib/tmarshal.nim b/tests/stdlib/tmarshal.nim index b05cb5a10..6a53a2964 100644 --- a/tests/stdlib/tmarshal.nim +++ b/tests/stdlib/tmarshal.nim @@ -1,7 +1,10 @@ discard """ output: '''{"age": 12, "bio": "\u042F Cletus", "blob": [65, 66, 67, 128], "name": "Cletus"} true -true''' +true +alpha 100 +omega 200 +''' """ import marshal @@ -83,3 +86,22 @@ var instance1 = Person(name: "Cletus", age: 12, echo($$instance1) echo(to[Person]($$instance1).bio == instance1.bio) echo(to[Person]($$instance1).blob == instance1.blob) + +# bug 5757 + +type + Something = object + x: string + y: int + +var data1 = """{"x": "alpha", "y": 100}""" +var data2 = """{"x": "omega", "y": 200}""" + +var r = to[Something](data1) + +echo r.x, " ", r.y + +r = to[Something](data2) + +echo r.x, " ", r.y + diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim index 538582ba8..581308a7e 100644 --- a/tests/stdlib/tmath.nim +++ b/tests/stdlib/tmath.nim @@ -1,4 +1,15 @@ -import math, random +discard """ + action: run + output: '''[Suite] random int + +[Suite] random float + +[Suite] ^ + +''' +""" + +import math, random, os import unittest import sets @@ -26,6 +37,7 @@ suite "random int": test "randomize() again gives new numbers": randomize() var rand1 = random(1000000) + os.sleep(200) randomize() var rand2 = random(1000000) check rand1 != rand2 @@ -55,7 +67,16 @@ suite "random float": test "randomize() again gives new numbers": randomize() var rand1:float = random(1000000.0) + os.sleep(200) randomize() var rand2:float = random(1000000.0) check rand1 != rand2 +suite "^": + test "compiles for valid types": + check: compiles(5 ^ 2) + check: compiles(5.5 ^ 2) + check: compiles(5.5 ^ 2.int8) + check: compiles(5.5 ^ 2.uint) + check: compiles(5.5 ^ 2.uint8) + check: not compiles(5.5 ^ 2.2) \ No newline at end of file diff --git a/tests/stdlib/torderedtable.nim b/tests/stdlib/torderedtable.nim new file mode 100644 index 000000000..91a916930 --- /dev/null +++ b/tests/stdlib/torderedtable.nim @@ -0,0 +1,18 @@ +import tables, random +var t = initOrderedTable[int,string]() + +# this tests issue #5917 +var data = newSeq[int]() +for i in 0..<1000: + var x = random(1000) + if x notin t: data.add(x) + t[x] = "meh" + +# this checks that keys are re-inserted +# in order when table is enlarged. +var i = 0 +for k, v in t: + doAssert(k == data[i]) + doAssert(v == "meh") + inc(i) + diff --git a/tests/template/tgenerictemplates.nim b/tests/template/tgenerictemplates.nim new file mode 100644 index 000000000..2c83bc0ec --- /dev/null +++ b/tests/template/tgenerictemplates.nim @@ -0,0 +1,13 @@ +type + SomeObj = object of RootObj + + Foo[T, U] = object + x: T + y: U + +template someTemplate[T](): tuple[id: int32, obj: T] = + var result: tuple[id: int32, obj: T] = (0'i32, T()) + result + +let ret = someTemplate[SomeObj]() + diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index ab24acc70..ed435465a 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -52,6 +52,7 @@ type exitCode*: int msg*: string ccodeCheck*: string + maxCodeSize*: int err*: TResultEnum substr*, sortoutput*: bool targets*: set[TTarget] @@ -109,6 +110,7 @@ proc specDefaults*(result: var TSpec) = result.tfile = "" result.tline = 0 result.tcolumn = 0 + result.maxCodeSize = 0 proc parseTargets*(value: string): set[TTarget] = for v in value.normalize.split: @@ -180,6 +182,7 @@ proc parseSpec*(filename: string): TSpec = else: result.cmd = e.value of "ccodecheck": result.ccodeCheck = e.value + of "maxcodesize": discard parseInt(e.value, result.maxCodeSize) of "target", "targets": for v in e.value.normalize.split: case v diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index 0f74de013..b83eb668a 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -212,20 +212,31 @@ proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) = proc generatedFile(path, name: string, target: TTarget): string = let ext = targetToExt[target] result = path / "nimcache" / - (if target == targetJS: path.splitPath.tail & "_" else: "compiler_") & + (if target == targetJS: "" else: "compiler_") & name.changeFileExt(ext) -proc codegenCheck(test: TTest, check: string, given: var TSpec) = +proc needsCodegenCheck(spec: TSpec): bool = + result = spec.maxCodeSize > 0 or spec.ccodeCheck.len > 0 + +proc codegenCheck(test: TTest, spec: TSpec, expectedMsg: var string, + given: var TSpec) = try: let (path, name, _) = test.name.splitFile let genFile = generatedFile(path, name, test.target) let contents = readFile(genFile).string - if check[0] == '\\': - # little hack to get 'match' support: - if not contents.match(check.peg): + let check = spec.ccodeCheck + if check.len > 0: + if check[0] == '\\': + # little hack to get 'match' support: + if not contents.match(check.peg): + given.err = reCodegenFailure + elif contents.find(check.peg) < 0: given.err = reCodegenFailure - elif contents.find(check.peg) < 0: + expectedMsg = check + if spec.maxCodeSize > 0 and contents.len > spec.maxCodeSize: given.err = reCodegenFailure + given.msg = "generated code size: " & $contents.len + expectedMsg = "max allowed size: " & $spec.maxCodeSize except ValueError: given.err = reInvalidPeg echo getCurrentExceptionMsg() @@ -248,9 +259,8 @@ proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; var expectedmsg: string = "" var givenmsg: string = "" if given.err == reSuccess: - if expected.ccodeCheck.len > 0: - codegenCheck(test, expected.ccodeCheck, given) - expectedmsg = expected.ccodeCheck + if expected.needsCodegenCheck: + codegenCheck(test, expected, expectedmsg, given) givenmsg = given.msg if expected.nimout.len > 0: expectedmsg = expected.nimout diff --git a/tests/typerel/ttypedesc_as_genericparam1.nim b/tests/typerel/ttypedesc_as_genericparam1.nim index 677bf6fc8..88c0509b2 100644 --- a/tests/typerel/ttypedesc_as_genericparam1.nim +++ b/tests/typerel/ttypedesc_as_genericparam1.nim @@ -1,6 +1,6 @@ discard """ line: 6 - errormsg: "type mismatch: got (typedesc[int])" + errormsg: "type mismatch: got (type int)" """ # bug #3079, #1146 echo repr(int) diff --git a/tests/typerel/ttypenoval.nim b/tests/typerel/ttypenoval.nim index d5b91fbca..eabca48f6 100644 --- a/tests/typerel/ttypenoval.nim +++ b/tests/typerel/ttypenoval.nim @@ -1,7 +1,7 @@ discard """ file: "ttypenoval.nim" line: 38 - errormsg: "type mismatch: got (typedesc[int]) but expected 'int'" + errormsg: "type mismatch: got (type int) but expected 'int'" """ # A min-heap. diff --git a/tests/types/t1252.nim b/tests/types/t1252.nim new file mode 100644 index 000000000..c6a12e9f7 --- /dev/null +++ b/tests/types/t1252.nim @@ -0,0 +1,12 @@ +discard """ + output: '''true +true +true +true +''' +""" + +echo float32 isnot float64 +echo float32 isnot float +echo int32 isnot int64 +echo int32 isnot int diff --git a/tests/types/thard_tyforward.nim b/tests/types/thard_tyforward.nim index 7131cd64b..8f606a0f9 100755..100644 --- a/tests/types/thard_tyforward.nim +++ b/tests/types/thard_tyforward.nim @@ -2,8 +2,8 @@ type Bar[T] = Foo[T, T] Baz[T] = proc (x: Foo[T, T]) - GenericAlias[T] = Foo[T] - GenericAlias2[T] = Foo[Baz[T]] + GenericAlias[T] = Foo[T, T] + GenericAlias2[T] = Foo[Baz[T], T] Concrete1 = Foo[int, float] Concrete2 = proc(x: proc(a: Foo[int, float])) diff --git a/tests/vm/tnimnode.nim b/tests/vm/tnimnode.nim index cca03cd62..e5a41e3c2 100644 --- a/tests/vm/tnimnode.nim +++ b/tests/vm/tnimnode.nim @@ -72,3 +72,11 @@ static: echo "OK" +static: + echo "testing creation of comment node" + var docComment: NimNode = newNimNode(nnkCommentStmt) + docComment.strVal = "This is a doc comment" + + assertEq repr(docComment), "## This is a doc comment" + + echo "OK" |