From 1b17c9f693754b69b249ca604533dccb2a421fab Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 29 Oct 2018 17:07:27 +0100 Subject: More descriptive names of test files (#9531) * change generic `tissues` name to more specific * change `tvarious` to more specific names --- tests/closure/tclosure_issues.nim | 54 +++ tests/closure/tissues.nim | 55 --- tests/concepts/tconcepts_issues.nim | 467 +++++++++++++++++++++ tests/concepts/tissues.nim | 467 --------------------- tests/distinct/tdistinct_issues.nim | 67 +++ tests/distinct/tissues.nim | 67 --- tests/generics/t5707.nim | 6 - tests/generics/tgenerics_issues.nim | 773 +++++++++++++++++++++++++++++++++++ tests/generics/tgenerics_various.nim | 245 +++++++++++ tests/generics/tissues.nim | 765 ---------------------------------- tests/generics/tvarious.nim | 245 ----------- tests/iter/tissues.nim | 215 ---------- tests/iter/titer_issues.nim | 215 ++++++++++ tests/macros/tissues.nim | 241 ----------- tests/macros/tmacros_issues.nim | 241 +++++++++++ tests/macros/tmacros_various.nim | 111 +++++ tests/macros/tvarious.nim | 111 ----- tests/metatype/tissues.nim | 150 ------- tests/metatype/tmetatype_issues.nim | 150 +++++++ tests/metatype/tmetatype_various.nim | 49 +++ tests/metatype/tvarious.nim | 49 --- tests/method/tissues.nim | 128 ------ tests/method/tmethod_issues.nim | 128 ++++++ tests/method/tmethod_various.nim | 83 ++++ tests/method/tvarious.nim | 83 ---- tests/objects/tissues.nim | 117 ------ tests/objects/tobjects_issues.nim | 117 ++++++ tests/objects/tobjects_various.nim | 87 ++++ tests/objects/tvarious.nim | 87 ---- tests/overload/tissues.nim | 185 --------- tests/overload/toverload_issues.nim | 185 +++++++++ tests/overload/toverload_various.nim | 176 ++++++++ tests/overload/tvarious.nim | 176 -------- tests/sets/tsets_various.nim | 200 +++++++++ tests/sets/tvarious.nim | 200 --------- tests/stdlib/tissues.nim | 109 ----- tests/stdlib/tstdlib_issues.nim | 109 +++++ tests/stdlib/tstdlib_various.nim | 247 +++++++++++ tests/stdlib/tvarious.nim | 247 ----------- 39 files changed, 3704 insertions(+), 3703 deletions(-) create mode 100644 tests/closure/tclosure_issues.nim delete mode 100644 tests/closure/tissues.nim create mode 100644 tests/concepts/tconcepts_issues.nim delete mode 100644 tests/concepts/tissues.nim create mode 100644 tests/distinct/tdistinct_issues.nim delete mode 100644 tests/distinct/tissues.nim delete mode 100644 tests/generics/t5707.nim create mode 100644 tests/generics/tgenerics_issues.nim create mode 100644 tests/generics/tgenerics_various.nim delete mode 100644 tests/generics/tissues.nim delete mode 100644 tests/generics/tvarious.nim delete mode 100644 tests/iter/tissues.nim create mode 100644 tests/iter/titer_issues.nim delete mode 100644 tests/macros/tissues.nim create mode 100644 tests/macros/tmacros_issues.nim create mode 100644 tests/macros/tmacros_various.nim delete mode 100644 tests/macros/tvarious.nim delete mode 100644 tests/metatype/tissues.nim create mode 100644 tests/metatype/tmetatype_issues.nim create mode 100644 tests/metatype/tmetatype_various.nim delete mode 100644 tests/metatype/tvarious.nim delete mode 100644 tests/method/tissues.nim create mode 100644 tests/method/tmethod_issues.nim create mode 100644 tests/method/tmethod_various.nim delete mode 100644 tests/method/tvarious.nim delete mode 100644 tests/objects/tissues.nim create mode 100644 tests/objects/tobjects_issues.nim create mode 100644 tests/objects/tobjects_various.nim delete mode 100644 tests/objects/tvarious.nim delete mode 100644 tests/overload/tissues.nim create mode 100644 tests/overload/toverload_issues.nim create mode 100644 tests/overload/toverload_various.nim delete mode 100644 tests/overload/tvarious.nim create mode 100644 tests/sets/tsets_various.nim delete mode 100644 tests/sets/tvarious.nim delete mode 100644 tests/stdlib/tissues.nim create mode 100644 tests/stdlib/tstdlib_issues.nim create mode 100644 tests/stdlib/tstdlib_various.nim delete mode 100644 tests/stdlib/tvarious.nim diff --git a/tests/closure/tclosure_issues.nim b/tests/closure/tclosure_issues.nim new file mode 100644 index 000000000..b2d77c571 --- /dev/null +++ b/tests/closure/tclosure_issues.nim @@ -0,0 +1,54 @@ +discard """ + output: '''true''' +""" + + +block tissue600: + for i in 1..1: + var reported = false + proc report() = + reported = true + + + +import sequtils +block tissue1502def: + let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] + + let maps = xs.map( + proc(x: auto): tuple[typ: string, maps: seq[string]] = + (x.key, x.val.map(proc(x: string): string = x))) + + + +block tissue1642: + var i = 0 + proc p() = inc(i) + + + +block tissue1846: + type + TBinOp[T] = proc (x,y: T): bool + THeap[T] = object + cmp: TBinOp[T] + + proc less[T](x,y: T): bool = + x < y + + proc initHeap[T](cmp: TBinOp[T]): THeap[T] = + result.cmp = cmp + + var h = initHeap[int](less[int]) + echo h.cmp(2,3) + + + +block tissue1911: + proc foo(x: int) : auto = + + proc helper() : int = x + proc bar() : int = helper() + proc baz() : int = helper() + + return (bar, baz) diff --git a/tests/closure/tissues.nim b/tests/closure/tissues.nim deleted file mode 100644 index d33e3b403..000000000 --- a/tests/closure/tissues.nim +++ /dev/null @@ -1,55 +0,0 @@ -discard """ - file: "tissues.nim" - output: '''true''' -""" - - -block tissue600: - for i in 1..1: - var reported = false - proc report() = - reported = true - - - -import sequtils -block tissue1502def: - let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] - - let maps = xs.map( - proc(x: auto): tuple[typ: string, maps: seq[string]] = - (x.key, x.val.map(proc(x: string): string = x))) - - - -block tissue1642: - var i = 0 - proc p() = inc(i) - - - -block tissue1846: - type - TBinOp[T] = proc (x,y: T): bool - THeap[T] = object - cmp: TBinOp[T] - - proc less[T](x,y: T): bool = - x < y - - proc initHeap[T](cmp: TBinOp[T]): THeap[T] = - result.cmp = cmp - - var h = initHeap[int](less[int]) - echo h.cmp(2,3) - - - -block tissue1911: - proc foo(x: int) : auto = - - proc helper() : int = x - proc bar() : int = helper() - proc baz() : int = helper() - - return (bar, baz) diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim new file mode 100644 index 000000000..e145b9f37 --- /dev/null +++ b/tests/concepts/tconcepts_issues.nim @@ -0,0 +1,467 @@ +discard """ + file: "tissues.nim" + output: ''' +20.0 USD +Printable +true +true +true +true +true +f +0 +10 +10 +5 +() +false +10 +true +true +true +true +p has been called. +p has been called. +implicit generic +generic +false +true +-1 +Meow +''' +""" + +import macros, typetraits, os, posix + + +block t5983: + 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 + + +block t3414: + 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) + + + +type + Obj1[T] = object + v: T +converter toObj1[T](t: T): Obj1[T] = + return Obj1[T](v: t) +block t976: + type + int1 = distinct int + int2 = distinct int + int1g = concept x + x is int1 + int2g = concept x + x is int2 + + proc take[T: int1g](value: int1) = + when T is int2: + static: error("killed in take(int1)") + + proc take[T: int2g](vale: int2) = + when T is int1: + static: error("killed in take(int2)") + + var i1: int1 = 1.int1 + var i2: int2 = 2.int2 + + take[int1](i1) + take[int2](i2) + + template reject(e) = + static: assert(not compiles(e)) + + reject take[string](i2) + reject take[int1](i2) + + # bug #6249 + type + Obj2 = ref object + PrintAble = concept x + $x is string + + proc `$`[T](nt: Obj1[T]): string = + when T is PrintAble: result = "Printable" + else: result = "Non Printable" + + echo Obj2() + + + +block t1128: + type + TFooContainer[T] = object + + TContainer[T] = concept var c + foo(c, T) + + proc foo[T](c: var TFooContainer[T], val: T) = + discard + + proc bar(c: var TContainer) = + discard + + var fooContainer: TFooContainer[int] + echo fooContainer is TFooContainer # true. + echo fooContainer is TFooContainer[int] # true. + fooContainer.bar() + + + +block t5642: + type DataTable = concept x + x is object + for f in fields(x): + f is seq + + type Students = object + id : seq[int] + name : seq[string] + age: seq[int] + + proc nrow(dt: DataTable) : Natural = + var totalLen = 0 + for f in fields(dt): + totalLen += f.len + return totalLen + + let + stud = Students(id: @[1,2,3], name: @["Vas", "Pas", "NafNaf"], age: @[10,16,32]) + + doAssert nrow(stud) == 9 + + + +import t5888lib/ca, t5888lib/opt +block t5888: + 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() + + + +import json +block t5968: + 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)) + + var x = %["hello", "world"] + + var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!") + assert z == @["hello!", "world!"] + + + +import sugar +block t6462: + 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)) + doAssert s.test() == nil + + + +block t6770: + type GA = concept c + c.a is int + + type A = object + a: int + + type AA = object + case exists: bool + of true: + a: int + else: + discard + + proc print(inp: GA) = + echo inp.a + + let failing = AA(exists: true, a: 10) + let working = A(a:10) + print(working) + print(failing) + + + +block t7952: + type + HasLen = concept iter + len(iter) is int + + proc echoLen(x: HasLen) = + echo len(x) + + echoLen([1, 2, 3, 4, 5]) + + + +block t8280: + type + Iterable[T] = concept x + for elem in x: + elem is T + + proc max[A](iter: Iterable[A]): A = + discard + + type + MyType = object + + echo max(@[MyType()]) + + + +import math +block t3452: + type + Node = concept n + `==`(n, n) is bool + Graph1 = concept g + type N = Node + distance(g, N, N) is float + Graph2 = concept g + distance(g, Node, Node) is float + Graph3 = concept g + var x: Node + distance(g, x, x) is float + 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) ) + + static: + assert MyGraph is Graph1 + assert MyGraph is Graph2 + assert MyGraph is Graph3 + + + +block t6691: + type + ConceptA = concept c + ConceptB = concept c + c.myProc(ConceptA) + Obj = object + + proc myProc(obj: Obj, x: ConceptA) = discard + + echo Obj is ConceptB + + + +block t6782: + type + Reader = concept c + c.read(openarray[byte], int, int) is int + Rdr = concept c + c.rd(openarray[byte], int, int) is int + + type TestFile = object + + proc read(r: TestFile, dest: openarray[byte], offset: int, limit: int): int = + result = 0 + proc rd(r: TestFile, dest: openarray[byte], offset: int, limit: int): int = + result = 0 + + doAssert TestFile is Reader + doAssert TestFile is Rdr + + + +block t7114: + type + MyConcept = concept x + x.close() # error, doesn't work + MyConceptImplementer = object + + proc close(self: MyConceptImplementer) = discard + proc takeConcept(window: MyConcept) = + discard + + takeConcept(MyConceptImplementer()) + + + +block t7510: + type + A[T] = concept a + a.x is T + B[T] = object + x: T + proc getx(v: A): v.T = v.x + var v = B[int32](x: 10) + echo v.getx + + + +block misc_issues: + # https://github.com/nim-lang/Nim/issues/1147 + type TTest = object + vals: seq[int] + + proc add(self: var TTest, val: int) = + self.vals.add(val) + + type CAddable = concept x + x[].add(int) + + echo((ref TTest) is CAddable) # true + + # https://github.com/nim-lang/Nim/issues/1570 + type ConcretePointOfFloat = object + x, y: float + + type ConcretePoint[Value] = object + x, y: Value + + type AbstractPointOfFloat = concept p + p.x is float and p.y is float + + let p1 = ConcretePointOfFloat(x: 0, y: 0) + let p2 = ConcretePoint[float](x: 0, y: 0) + + echo p1 is AbstractPointOfFloat # true + echo p2 is AbstractPointOfFloat # true + echo p2.x is float and p2.y is float # true + + # https://github.com/nim-lang/Nim/issues/2018 + type ProtocolFollower = concept + true # not a particularly involved protocol + + type ImplementorA = object + type ImplementorB = object + + proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) = + echo "p has been called." + + p(ImplementorA(), ImplementorA()) + p(ImplementorA(), ImplementorB()) + + # https://github.com/nim-lang/Nim/issues/2423 + proc put[T](c: seq[T], x: T) = echo "generic" + proc put(c: seq) = echo "implicit generic" + + type + Container[T] = concept c + put(c) + put(c, T) + + proc c1(x: Container) = echo "implicit generic" + c1(@[1]) + + proc c2[T](x: Container[T]) = echo "generic" + c2(@[1]) + + # https://github.com/nim-lang/Nim/issues/2882 + type + Paper = object + name: string + + Bendable = concept x + bend(x is Bendable) + + proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name) + + var paper = Paper(name: "red") + echo paper is Bendable + + type + A = concept self + size(self) is int + + B = object + + proc size(self: B): int = + return -1 + + proc size(self: A): int = + return 0 + + let b = B() + echo b is A + echo b.size() + + # https://github.com/nim-lang/Nim/issues/7125 + type + Thing = concept x + x.hello is string + Cat = object + + proc hello(d: Cat): string = "Meow" + + proc sayHello(c: Thing) = echo(c.hello) + + var a: Thing = Cat() + a.sayHello() diff --git a/tests/concepts/tissues.nim b/tests/concepts/tissues.nim deleted file mode 100644 index e145b9f37..000000000 --- a/tests/concepts/tissues.nim +++ /dev/null @@ -1,467 +0,0 @@ -discard """ - file: "tissues.nim" - output: ''' -20.0 USD -Printable -true -true -true -true -true -f -0 -10 -10 -5 -() -false -10 -true -true -true -true -p has been called. -p has been called. -implicit generic -generic -false -true --1 -Meow -''' -""" - -import macros, typetraits, os, posix - - -block t5983: - 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 - - -block t3414: - 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) - - - -type - Obj1[T] = object - v: T -converter toObj1[T](t: T): Obj1[T] = - return Obj1[T](v: t) -block t976: - type - int1 = distinct int - int2 = distinct int - int1g = concept x - x is int1 - int2g = concept x - x is int2 - - proc take[T: int1g](value: int1) = - when T is int2: - static: error("killed in take(int1)") - - proc take[T: int2g](vale: int2) = - when T is int1: - static: error("killed in take(int2)") - - var i1: int1 = 1.int1 - var i2: int2 = 2.int2 - - take[int1](i1) - take[int2](i2) - - template reject(e) = - static: assert(not compiles(e)) - - reject take[string](i2) - reject take[int1](i2) - - # bug #6249 - type - Obj2 = ref object - PrintAble = concept x - $x is string - - proc `$`[T](nt: Obj1[T]): string = - when T is PrintAble: result = "Printable" - else: result = "Non Printable" - - echo Obj2() - - - -block t1128: - type - TFooContainer[T] = object - - TContainer[T] = concept var c - foo(c, T) - - proc foo[T](c: var TFooContainer[T], val: T) = - discard - - proc bar(c: var TContainer) = - discard - - var fooContainer: TFooContainer[int] - echo fooContainer is TFooContainer # true. - echo fooContainer is TFooContainer[int] # true. - fooContainer.bar() - - - -block t5642: - type DataTable = concept x - x is object - for f in fields(x): - f is seq - - type Students = object - id : seq[int] - name : seq[string] - age: seq[int] - - proc nrow(dt: DataTable) : Natural = - var totalLen = 0 - for f in fields(dt): - totalLen += f.len - return totalLen - - let - stud = Students(id: @[1,2,3], name: @["Vas", "Pas", "NafNaf"], age: @[10,16,32]) - - doAssert nrow(stud) == 9 - - - -import t5888lib/ca, t5888lib/opt -block t5888: - 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() - - - -import json -block t5968: - 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)) - - var x = %["hello", "world"] - - var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!") - assert z == @["hello!", "world!"] - - - -import sugar -block t6462: - 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)) - doAssert s.test() == nil - - - -block t6770: - type GA = concept c - c.a is int - - type A = object - a: int - - type AA = object - case exists: bool - of true: - a: int - else: - discard - - proc print(inp: GA) = - echo inp.a - - let failing = AA(exists: true, a: 10) - let working = A(a:10) - print(working) - print(failing) - - - -block t7952: - type - HasLen = concept iter - len(iter) is int - - proc echoLen(x: HasLen) = - echo len(x) - - echoLen([1, 2, 3, 4, 5]) - - - -block t8280: - type - Iterable[T] = concept x - for elem in x: - elem is T - - proc max[A](iter: Iterable[A]): A = - discard - - type - MyType = object - - echo max(@[MyType()]) - - - -import math -block t3452: - type - Node = concept n - `==`(n, n) is bool - Graph1 = concept g - type N = Node - distance(g, N, N) is float - Graph2 = concept g - distance(g, Node, Node) is float - Graph3 = concept g - var x: Node - distance(g, x, x) is float - 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) ) - - static: - assert MyGraph is Graph1 - assert MyGraph is Graph2 - assert MyGraph is Graph3 - - - -block t6691: - type - ConceptA = concept c - ConceptB = concept c - c.myProc(ConceptA) - Obj = object - - proc myProc(obj: Obj, x: ConceptA) = discard - - echo Obj is ConceptB - - - -block t6782: - type - Reader = concept c - c.read(openarray[byte], int, int) is int - Rdr = concept c - c.rd(openarray[byte], int, int) is int - - type TestFile = object - - proc read(r: TestFile, dest: openarray[byte], offset: int, limit: int): int = - result = 0 - proc rd(r: TestFile, dest: openarray[byte], offset: int, limit: int): int = - result = 0 - - doAssert TestFile is Reader - doAssert TestFile is Rdr - - - -block t7114: - type - MyConcept = concept x - x.close() # error, doesn't work - MyConceptImplementer = object - - proc close(self: MyConceptImplementer) = discard - proc takeConcept(window: MyConcept) = - discard - - takeConcept(MyConceptImplementer()) - - - -block t7510: - type - A[T] = concept a - a.x is T - B[T] = object - x: T - proc getx(v: A): v.T = v.x - var v = B[int32](x: 10) - echo v.getx - - - -block misc_issues: - # https://github.com/nim-lang/Nim/issues/1147 - type TTest = object - vals: seq[int] - - proc add(self: var TTest, val: int) = - self.vals.add(val) - - type CAddable = concept x - x[].add(int) - - echo((ref TTest) is CAddable) # true - - # https://github.com/nim-lang/Nim/issues/1570 - type ConcretePointOfFloat = object - x, y: float - - type ConcretePoint[Value] = object - x, y: Value - - type AbstractPointOfFloat = concept p - p.x is float and p.y is float - - let p1 = ConcretePointOfFloat(x: 0, y: 0) - let p2 = ConcretePoint[float](x: 0, y: 0) - - echo p1 is AbstractPointOfFloat # true - echo p2 is AbstractPointOfFloat # true - echo p2.x is float and p2.y is float # true - - # https://github.com/nim-lang/Nim/issues/2018 - type ProtocolFollower = concept - true # not a particularly involved protocol - - type ImplementorA = object - type ImplementorB = object - - proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) = - echo "p has been called." - - p(ImplementorA(), ImplementorA()) - p(ImplementorA(), ImplementorB()) - - # https://github.com/nim-lang/Nim/issues/2423 - proc put[T](c: seq[T], x: T) = echo "generic" - proc put(c: seq) = echo "implicit generic" - - type - Container[T] = concept c - put(c) - put(c, T) - - proc c1(x: Container) = echo "implicit generic" - c1(@[1]) - - proc c2[T](x: Container[T]) = echo "generic" - c2(@[1]) - - # https://github.com/nim-lang/Nim/issues/2882 - type - Paper = object - name: string - - Bendable = concept x - bend(x is Bendable) - - proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name) - - var paper = Paper(name: "red") - echo paper is Bendable - - type - A = concept self - size(self) is int - - B = object - - proc size(self: B): int = - return -1 - - proc size(self: A): int = - return 0 - - let b = B() - echo b is A - echo b.size() - - # https://github.com/nim-lang/Nim/issues/7125 - type - Thing = concept x - x.hello is string - Cat = object - - proc hello(d: Cat): string = "Meow" - - proc sayHello(c: Thing) = echo(c.hello) - - var a: Thing = Cat() - a.sayHello() diff --git a/tests/distinct/tdistinct_issues.nim b/tests/distinct/tdistinct_issues.nim new file mode 100644 index 000000000..ce71344d0 --- /dev/null +++ b/tests/distinct/tdistinct_issues.nim @@ -0,0 +1,67 @@ +discard """ + output: ''' +A +A +25.0 +210.0 +apr +''' +""" + + +block t4435: + type + A[T] = distinct T + B[T] = distinct T + + proc foo[T](x:A[T]) = echo "A" + proc foo[T](x:B[T]) = echo "B" + proc bar(x:A) = echo "A" + proc bar(x:B) = echo "B" + + var + a:A[int] + + foo(a) # fine + bar(a) # testdistinct.nim(14, 4) Error: ambiguous call; both testdistinct.bar(x: A) and testdistinct.bar(x: B) match for: (A[system.int]) + + + +block t7010: + type MyInt = distinct int + + proc `+`(x: MyInt, y: MyInt): MyInt {.borrow.} + proc `+=`(x: var MyInt, y: MyInt) {.borrow.} + proc `=`(x: var MyInt, y: MyInt) {.borrow.} + + var next: MyInt + + proc getNext() : MyInt = + result = next + next += 1.MyInt + next = next + 1.MyInt + + + +block t9079: + type + Dollars = distinct float + + proc `$`(d: Dollars): string {.borrow.} + proc `*`(a, b: Dollars): Dollars {.borrow.} + proc `+`(a, b: Dollars): Dollars {.borrow.} + + var a = Dollars(20) + a = Dollars(25.0) + echo a + a = 10.Dollars * (20.Dollars + 1.Dollars) + echo a + + + +block t9322: + type Fix = distinct string + proc `$`(f: Fix): string {.borrow.} + proc mystr(s: string) = + echo s + mystr($Fix("apr")) diff --git a/tests/distinct/tissues.nim b/tests/distinct/tissues.nim deleted file mode 100644 index ce71344d0..000000000 --- a/tests/distinct/tissues.nim +++ /dev/null @@ -1,67 +0,0 @@ -discard """ - output: ''' -A -A -25.0 -210.0 -apr -''' -""" - - -block t4435: - type - A[T] = distinct T - B[T] = distinct T - - proc foo[T](x:A[T]) = echo "A" - proc foo[T](x:B[T]) = echo "B" - proc bar(x:A) = echo "A" - proc bar(x:B) = echo "B" - - var - a:A[int] - - foo(a) # fine - bar(a) # testdistinct.nim(14, 4) Error: ambiguous call; both testdistinct.bar(x: A) and testdistinct.bar(x: B) match for: (A[system.int]) - - - -block t7010: - type MyInt = distinct int - - proc `+`(x: MyInt, y: MyInt): MyInt {.borrow.} - proc `+=`(x: var MyInt, y: MyInt) {.borrow.} - proc `=`(x: var MyInt, y: MyInt) {.borrow.} - - var next: MyInt - - proc getNext() : MyInt = - result = next - next += 1.MyInt - next = next + 1.MyInt - - - -block t9079: - type - Dollars = distinct float - - proc `$`(d: Dollars): string {.borrow.} - proc `*`(a, b: Dollars): Dollars {.borrow.} - proc `+`(a, b: Dollars): Dollars {.borrow.} - - var a = Dollars(20) - a = Dollars(25.0) - echo a - a = 10.Dollars * (20.Dollars + 1.Dollars) - echo a - - - -block t9322: - type Fix = distinct string - proc `$`(f: Fix): string {.borrow.} - proc mystr(s: string) = - echo s - mystr($Fix("apr")) diff --git a/tests/generics/t5707.nim b/tests/generics/t5707.nim deleted file mode 100644 index a155e1597..000000000 --- a/tests/generics/t5707.nim +++ /dev/null @@ -1,6 +0,0 @@ -import sugar - -proc foo[T]: seq[int] = - return lc[x | (x <- 1..10, x mod 2 == 0), int] - -doAssert foo[float32]() == @[2, 4, 6, 8, 10] diff --git a/tests/generics/tgenerics_issues.nim b/tests/generics/tgenerics_issues.nim new file mode 100644 index 000000000..c215ea2c2 --- /dev/null +++ b/tests/generics/tgenerics_issues.nim @@ -0,0 +1,773 @@ +discard """ + output: ''' +4 +3 +(weight: 17.0, color: 100) +perm: 22 det: 22 +TMatrix[3, 3, system.int] +3 +@[0.9, 0.1] +U[3] +U[(f: 3)] +U[[3]] +b() +@[1, 2] +@[3, 4] +1 +concrete 88 +123 +1 +2 +3 +!!Hi!! +G:0,1:0.1 +G:0,1:0.1 +H:1:0.1 +''' +""" + + +import macros, sequtils, sets, sugar, tables, typetraits + + +block t88: + type + BaseClass[V] = object of RootObj + b: V + + proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] = + BaseClass[V](b: v) + + proc baseMethod[V](v: BaseClass[V]): V = v.b + proc overriddenMethod[V](v: BaseClass[V]): V = v.baseMethod + + type + ChildClass[V] = object of BaseClass[V] + c: V + + proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] = + ChildClass[V](b: v1, c: v2) + + proc overriddenMethod[V](v: ChildClass[V]): V = v.c + + let c = ChildClass[string].new("Base", "Child") + + assert c.baseMethod == "Base" + assert c.overriddenMethod == "Child" + + + +block t4528: + type GenericBase[T] = ref object of RootObj + type GenericSubclass[T] = ref object of GenericBase[T] + proc foo[T](g: GenericBase[T]) = discard + var bar: GenericSubclass[int] + foo(bar) + + + +block t1050_5597: + type ArrayType[T] = distinct T + + proc arrayItem(a: ArrayType): auto = + static: echo(name(type(a).T)) + result = (type(a).T)(4) + + var arr: ArrayType[int] + echo arrayItem(arr) + + # bug #5597 + + template fail() = "what" + + proc g[T](x: var T) = + x.fail = 3 + + type + Obj = object + fail: int + + var y: Obj + g y + + + +block t1789: + type + Foo[N: static[int]] = object + + proc bindStaticN[N](foo: Foo[N]) = + var ar0: array[3, int] + var ar1: array[N, int] + var ar2: array[1..N, int] + var ar3: array[0..(N+10), float] + echo N + + var f: Foo[3] + f.bindStaticN + + # case 2 + + type + ObjectWithStatic[X, Y: static[int], T] = object + bar: array[X * Y, T] # this one works + + AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] + + var + x: ObjectWithStatic[1, 2, int] + y: AliasWithStatic[2, 3, int] + + # case 3 + + type + Bar[N: static[int], T] = object + bar: array[N, T] + + proc `[]`[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = + assert high(n) == N-1 + result = f.bar[n] + + var b: Bar[3, int] + doAssert b[2] == 0 + + + +block t3977: + type Foo[N: static[int]] = object + + proc foo[N](x: Foo[N]) = + let n = N + doAssert N == n + + var f1: Foo[42] + f1.foo + + + +block t5570: + type + BaseFruit[T] = object of RootObj + color: T + + Banana[T] = object of BaseFruit[uint32] + weight: T + + macro printTypeName(typ: typed): untyped = + echo "type ", getType(typ).repr + + proc setColor[K](self: var BaseFruit[K], c: int) = + printTypeName(self.color) + self.color = uint32(c) + + var x: Banana[float64] + x.weight = 17 + printTypeName(x.color) + x.setColor(100) + echo x + + + +block t5643: + type + Matrix[M, N: static[int], T: SomeFloat] = object + data: ref array[N * M, T] + Matrix64[M, N: static[int]] = Matrix[M, N, float64] + + proc zeros64(M,N: static[int]): Matrix64[M,N] = + new result.data + for i in 0 ..< (M * N): + result.data[i] = 0'f64 + + proc bar[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) = + discard + + let a = zeros64(2,2) + bar(a,a) + # https://github.com/nim-lang/Nim/issues/5643 + # + # The test case was failing here, because the compiler failed to + # detect the two matrix instantiations as the same type. + # + # The root cause was that the `T` type variable is a different + # type after the first Matrix type has been matched. + # + # Sigmatch was failing to match the second version of `T`, but + # due to some complex interplay between tyOr, tyTypeDesc and + # tyGenericParam this was allowed to went through. The generic + # instantiation of the second matrix was incomplete and the + # generic cache lookup failed, producing two separate types. + + + +block t5683: + type Matrix[M,N: static[int]] = array[M, array[N, float]] + + proc det[M,N](a: Matrix[M,N]): int = N*10 + M + proc perm[M,N](a: Matrix[M,N]): int = M*10 + N + + const + a = [ [1.0, 2.0] + , [3.0, 4.0] + ] + + echo "perm: ", a.perm, " det: ", a.det + + # This tests multiple instantiations of a generic + # proc involving static params: + type + Vector64[N: static[int]] = ref array[N, float64] + Array64[N: static[int]] = array[N, float64] + + proc vector[N: static[int]](xs: Array64[N]): Vector64[N] = + new result + for i in 0 ..< N: + result[i] = xs[i] + + let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) + let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) + let v3 = vector([1.0, 2.0, 3.0, 4.0]) + + + +block t7794: + type + Data[T:SomeNumber, U:SomeFloat] = ref object + x: T + value*: U + + var d = Data[int, float64](x:10.int, value:2'f64) + doAssert d.x == 10 + doAssert d.value == 2.0 + + + +block t8403: + proc sum[T](s: seq[T], R: typedesc): R = + var sum: R = 0 + for x in s: + sum += R(x) + return sum + + doAssert @[1, 2, 3].sum(float) == 6.0 + + + +block t8439: + type + Cardinal = enum + north, east, south, west + + proc foo[cardinal: static[Cardinal]](): int = 1 + doAssert foo[north]() == 1 + + + +block t8694: + when true: + # Error: undeclared identifier: '|' + proc bar[T](t:T): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(0) + + when true: + # ok + proc bar(t:int): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(0) + + when true: + # Error: undeclared identifier: '|' + proc bar(t:typedesc): bool = + runnableExamples: + type Foo = int | float + true + doAssert bar(int) + + + +block t9130: + when true: + # stack overflow + template baz1(iter: untyped): untyped = + runnableExamples: + import sugar + proc fun(a: proc(x:int): int) = discard + baz1(fun(x:int => x)) + discard + + proc foo1[A](ts: A) = + baz1(ts) + + when true: + # ok + template baz2(iter: untyped): untyped = + runnableExamples: + import sugar + proc fun(a: proc(x:int): int) = discard + baz2(fun(x:int => x)) + discard + + proc foo2(ts: int) = + baz2(ts) + + when true: + # stack overflow + template baz3(iter: untyped): untyped = + runnableExamples: + baz3(fun(x:int => x)) + discard + + proc foo3[A](ts: A) = + baz3(ts) + + + +block t1056: + type + TMatrix[N,M: static[int], T] = object + data: array[0..N*M-1, T] + + TMat2[T] = TMatrix[2,2,T] + + proc echoMatrix(a: TMatrix) = + echo a.type.name + echo TMatrix.N + + proc echoMat2(a: TMat2) = + echo TMat2.M + + var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) + + echoMatrix m + + + +block t4884: + type + Vec[N: static[int], T] = object + arr*: array[N, T] + + Mat[N,M: static[int], T] = object + arr: array[N, Vec[M,T]] + + var m : Mat[3,3,float] + var strMat : Mat[m.N, m.M, string] + var lenMat : Mat[m.N, m.M, int] + + + +block t2221: + var tblo: TableRef[string, int] + doAssert tblo == nil + + + +block t2304: + type TV2[T:SomeNumber] = array[0..1, T] + proc newV2T[T](x, y: T=0): TV2[T] = [x, y] + + let x = newV2T[float](0.9, 0.1) + echo(@x) + + + +block t2752: + proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) = + iterator aNameWhichWillConflict(): T {.closure.}= + for x in it(): + if f(x): + yield x + result = aNameWhichWillConflict + + iterator testIt():int {.closure.}= + yield -1 + yield 2 + + #let unusedVariable = myFilter(testIt, (x: int) => x > 0) + + proc onlyPos(it: (iterator(): int)): (iterator(): int)= + iterator aNameWhichWillConflict(): int {.closure.}= + var filtered = onlyPos(myFilter(it, (x:int) => x > 0)) + for x in filtered(): + yield x + result = aNameWhichWillConflict + + let x = onlyPos(testIt) + + + +block t5106: + 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 + + + +block t3055: + proc b(t: int | string) + proc a(t: int) = b(t) + proc b(t: int | string) = echo "b()" + a(1) + + # test recursive generics still work: + proc fac[T](x: T): T = + if x == 0: return 1 + else: return fac(x-1)*x + + doAssert fac(6) == 720 + doAssert fac(5.0) == 120.0 + + + # test recursive generic with forwarding: + proc fac2[T](x: T): T + + doAssert fac2(6) == 720 + doAssert fac2(5.0) == 120.0 + + proc fac2[T](x: T): T = + if x == 0: return 1 + else: return fac2(x-1)*x + + + +block t1187: + type + TEventArgs = object + skip: bool + TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.} + TEvent[T] = object + #handlers: seq[TEventHandler[T]] # Does not work + handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works + + TData = object + x: int + + TSomething = object + s: TEvent[TData] + + proc init[T](e: var TEvent[T]) = + e.handlers.newSeq(0) + + #proc add*[T](e: var TEvent[T], h: proc (e: var TEventArgs, data: T) {.closure.}) = + # this line works + proc add[T](e: var TEvent[T], h: TEventHandler[T]) = + # this line does not work + e.handlers.add(h) + + proc main () = + var something: TSomething + something.s.init() + var fromOutside = 4711 + + something.s.add() do (e: var TEventArgs, data: TData): + var x = data.x + x = fromOutside + + main() + + + +block t1919: + type + Base[M] = object of RootObj + a : M + Sub1[M] = object of Base[M] + b : int + Sub2[M] = object of Sub1[M] + c : int + + var x: Sub2[float] + doAssert x.a == 0.0 + + + +block t5756: + 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() + + + +block t7854: + type + Stream = ref StreamObj + StreamObj = object of RootObj + + InhStream = ref InhStreamObj + InhStreamObj = object of Stream + f: string + + proc newInhStream(f: string): InhStream = + new(result) + result.f = f + + var val: int + let str = newInhStream("input_file.json") + + block: + # works: + proc load[T](data: var T, s: Stream) = + discard + load(val, str) + + block: + # works + proc load[T](s: Stream, data: T) = + discard + load(str, val) + + block: + # broken + proc load[T](s: Stream, data: var T) = + discard + load(str, val) + + + +block t5864: + 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() + + doAssert a == 1 + doAssert b == 2 + + + +block t3498: + template defaultOf[T](t: T): untyped = (var d: T; d) + + doAssert defaultOf(1) == 0 + + # assignment using template + + template tassign[T](x: var seq[T]) = + x = @[1, 2, 3] + + var y: seq[int] + tassign(y) #<- x is expected = @[1, 2, 3] + tassign(y) + + doAssert y[0] == 1 + doAssert y[1] == 2 + doAssert y[2] == 3 + + + +block t3499: + proc foo[T](x: proc(): T) = + echo "generic ", x() + + proc foo(x: proc(): int) = + echo "concrete ", x() + + # note the following 'proc' is not .closure! + foo(proc (): auto {.nimcall.} = 88) + + # bug #3499 last snippet fixed + # bug 705 last snippet fixed + + + + +block t797: + proc foo[T](s:T):string = $s + + type IntStringProc = proc(x: int): string + + var f1 = IntStringProc(foo) + var f2: proc(x: int): string = foo + var f3: IntStringProc = foo + + echo f1(1), f2(2), f3(3) + + for x in map([1,2,3], foo): echo x + + + +block t4658: + var x = 123 + proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x)) + proc quote(s: string): string = "!" & s & "!" + echo twice(quote)("Hi") + + + +block t4589: + type SimpleTable[TKey, TVal] = TableRef[TKey, TVal] + template newSimpleTable(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]() + var fontCache : SimpleTable[string, SimpleTable[int32, int]] + fontCache = newSimpleTable(string, SimpleTable[int32, int]) + + + +block t4600: + template foo(x: untyped): untyped = echo 1 + template foo(x,y: untyped): untyped = echo 2 + + proc bar1[T](x: T) = foo(x) + proc bar2(x: float) = foo(x,x) + proc bar3[T](x: T) = foo(x,x) + + + +block t4672: + type + EnumContainer[T: enum] = object + v: T + SomeEnum {.pure.} = enum + A,B,C + + proc value[T: enum](this: EnumContainer[T]): T = + this.v + + var enumContainer: EnumContainer[SomeEnum] + discard enumContainer.value() + + + +block t4863: + type + G[i,j: static[int]] = object + v:float + H[j: static[int]] = G[0,j] + proc p[i,j: static[int]](x:G[i,j]) = echo "G:", i, ",", j, ":", x.v + proc q[j: static[int]](x:H[j]) = echo "H:", j, ":", x.v + + var + g0 = G[0,1](v: 0.1) + h0:H[1] = g0 + p(g0) + p(h0) + q(h0) + + + +block t1684: + type + BaseType {.inheritable pure.} = object + idx: int + + DerivedType {.final pure.} = object of BaseType + + proc index[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx + proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx) + + let d = newDerived(2) + assert(d.index == 2) + + + +block t5632: + type Option[T] = object + + proc point[A](v: A, t: typedesc[Option[A]]): Option[A] = + discard + + discard point(1, Option) + + + +block t7247: + type n8 = range[0'i8..127'i8] + var tab = initSet[n8]() + doAssert tab.contains(8) == false + + + +block t3717: + type + Foo[T] = object + a: T + Foo1[T] = Foo[T] | int + + proc foo[T](s: Foo1[Foo[T]]): T = + 5 + + var f: Foo[Foo[int]] + discard foo(f) + + + +block t5707: + proc foo[T]: seq[int] = + return lc[x | (x <- 1..10, x mod 2 == 0), int] + + doAssert foo[float32]() == @[2, 4, 6, 8, 10] diff --git a/tests/generics/tgenerics_various.nim b/tests/generics/tgenerics_various.nim new file mode 100644 index 000000000..5e18995f5 --- /dev/null +++ b/tests/generics/tgenerics_various.nim @@ -0,0 +1,245 @@ +discard """ + output: ''' +we +direct +generic +generic +''' +""" + + +import algorithm, sugar, sequtils, typetraits, asyncdispatch + + +block tconfusing_arrow: + type Deck = object + value: int + + proc sort(h: var seq[Deck]) = + # works: + h.sort(proc (x, y: Deck): auto = + cmp(x.value, y.value)) + # fails: + h.sort((x, y: Deck) => cmp(ord(x.value), ord(y.value))) + + var player: seq[Deck] = @[] + player.sort() + + + +block tdictdestruct: + type + TDict[TK, TV] = object + k: TK + v: TV + PDict[TK, TV] = ref TDict[TK, TV] + + proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) = + discard + + proc destroyDict[TK, TV](a: PDict[TK, TV]) = + return + proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] = + fakeNew(result, destroyDict[TK, TV]) + + # Problem: destroyDict is not instantiated when newDict is instantiated! + discard newDict("a", "b") + + + +block tgenericdefaults: + type + TFoo[T, U, R = int] = object + x: T + y: U + z: R + + TBar[T] = TFoo[T, array[4, T], T] + + var x1: TFoo[int, float] + + static: + assert type(x1.x) is int + assert type(x1.y) is float + assert type(x1.z) is int + + var x2: TFoo[string, R = float, U = seq[int]] + + static: + assert type(x2.x) is string + assert type(x2.y) is seq[int] + assert type(x2.z) is float + + var x3: TBar[float] + + static: + assert type(x3.x) is float + assert type(x3.y) is array[4, float] + assert type(x3.z) is float + + + +block tprop: + type + TProperty[T] = object of RootObj + getProc: proc(property: TProperty[T]): T {.nimcall.} + setProc: proc(property: TProperty[T], value: T) {.nimcall.} + value: T + + proc newProperty[T](value: RootObj): TProperty[T] = + result.getProc = proc (property: TProperty[T]) = + return property.value + + + +block trefs: + type + PA[T] = ref TA[T] + TA[T] = object + field: T + var a: PA[string] + new(a) + a.field = "some string" + + proc someOther[T](len: string): seq[T] = discard + proc someOther[T](len: int): seq[T] = echo "we" + + proc foo[T](x: T) = + var s = someOther[T](34) + #newSeq[T](34) + + foo 23 + + when false: + # Compiles unless you use var a: PA[string] + type + PA = ref TA + TA[T] = object + + # Cannot instantiate: + type + TA[T] = object + a: PA[T] + PA[T] = ref TA[T] + + type + PA[T] = ref TA[T] + TA[T] = object + + + +block tsharedcases: + proc typeNameLen(x: typedesc): int {.compileTime.} = + result = x.name.len + macro selectType(a, b: typedesc): typedesc = + result = a + + type + Foo[T] = object + data1: array[T.high, int] + data2: array[typeNameLen(T), float] + data3: array[0..T.typeNameLen, selectType(float, int)] + MyEnum = enum A, B, C, D + + var f1: Foo[MyEnum] + var f2: Foo[int8] + + doAssert high(f1.data1) == 2 # (D = 3) - 1 == 2 + doAssert high(f1.data2) == 5 # (MyEnum.len = 6) - 1 == 5 + + doAssert high(f2.data1) == 126 # 127 - 1 == 126 + doAssert high(f2.data2) == 3 # int8.len - 1 == 3 + + static: + assert high(f1.data1) == ord(C) + assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high + + assert high(f2.data1) == 126 + assert high(f2.data2) == 3 + + assert high(f1.data3) == 6 # length of MyEnum + assert high(f2.data3) == 4 # length of int8 + + assert f2.data3[0] is float + + + +block tmap_auto: + let x = map(@[1, 2, 3], x => x+10) + assert x == @[11, 12, 13] + + let y = map(@[(1,"a"), (2,"b"), (3,"c")], x => $x[0] & x[1]) + assert y == @["1a", "2b", "3c"] + + proc eatsTwoArgProc[T,S,U](a: T, b: S, f: proc(t: T, s: S): U): U = + f(a,b) + + let z = eatsTwoArgProc(1, "a", (t,s) => $t & s) + assert z == "1a" + + + +block tproctypecache_falsepositive: + type + Callback = proc() {.closure, gcsafe.} + GameState = ref object + playerChangeHandlers: seq[Callback] + + proc newGameState(): GameState = + result = GameState( + playerChangeHandlers: newSeq[Callback]() # this fails + ) + + + +block tptrinheritance: + type NSPasteboardItem = ptr object + type NSPasteboard = ptr object + type NSArrayAbstract = ptr object {.inheritable.} + type NSMutableArrayAbstract = ptr object of NSArrayAbstract + type NSArray[T] = ptr object of NSArrayAbstract + type NSMutableArray[T] = ptr object of NSArray[T] + + proc newMutableArrayAbstract(): NSMutableArrayAbstract = discard + + template newMutableArray(T: typedesc): NSMutableArray[T] = + cast[NSMutableArray[T]](newMutableArrayAbstract()) + + proc writeObjects(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard + + let a = newMutableArray NSPasteboardItem + var x: NSMutableArray[NSPasteboardItem] + var y: NSArray[NSPasteboardItem] = x + + writeObjects(nil, a) + + + +block tsigtypeop: + type Vec3[T] = array[3, T] + + proc foo(x: Vec3, y: Vec3.T, z: x.T): x.type.T = + return 10 + + var y: Vec3[int] = [1, 2, 3] + var z: int = foo(y, 3, 4) + + + +block tvarargs_vs_generics: + proc withDirectType(args: string) = + echo "direct" + proc withDirectType[T](arg: T) = + echo "generic" + proc withOpenArray(args: openarray[string]) = + echo "openarray" + proc withOpenArray[T](arg: T) = + echo "generic" + proc withVarargs(args: varargs[string]) = + echo "varargs" + proc withVarargs[T](arg: T) = + echo "generic" + + withDirectType "string" + withOpenArray "string" + withVarargs "string" diff --git a/tests/generics/tissues.nim b/tests/generics/tissues.nim deleted file mode 100644 index e958549d6..000000000 --- a/tests/generics/tissues.nim +++ /dev/null @@ -1,765 +0,0 @@ -discard """ - output: ''' -4 -3 -(weight: 17.0, color: 100) -perm: 22 det: 22 -TMatrix[3, 3, system.int] -3 -@[0.9, 0.1] -U[3] -U[(f: 3)] -U[[3]] -b() -@[1, 2] -@[3, 4] -1 -concrete 88 -123 -1 -2 -3 -!!Hi!! -G:0,1:0.1 -G:0,1:0.1 -H:1:0.1 -''' -""" - - -import macros, sequtils, sets, sugar, tables, typetraits - - -block t88: - type - BaseClass[V] = object of RootObj - b: V - - proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] = - BaseClass[V](b: v) - - proc baseMethod[V](v: BaseClass[V]): V = v.b - proc overriddenMethod[V](v: BaseClass[V]): V = v.baseMethod - - type - ChildClass[V] = object of BaseClass[V] - c: V - - proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] = - ChildClass[V](b: v1, c: v2) - - proc overriddenMethod[V](v: ChildClass[V]): V = v.c - - let c = ChildClass[string].new("Base", "Child") - - assert c.baseMethod == "Base" - assert c.overriddenMethod == "Child" - - - -block t4528: - type GenericBase[T] = ref object of RootObj - type GenericSubclass[T] = ref object of GenericBase[T] - proc foo[T](g: GenericBase[T]) = discard - var bar: GenericSubclass[int] - foo(bar) - - - -block t1050_5597: - type ArrayType[T] = distinct T - - proc arrayItem(a: ArrayType): auto = - static: echo(name(type(a).T)) - result = (type(a).T)(4) - - var arr: ArrayType[int] - echo arrayItem(arr) - - # bug #5597 - - template fail() = "what" - - proc g[T](x: var T) = - x.fail = 3 - - type - Obj = object - fail: int - - var y: Obj - g y - - - -block t1789: - type - Foo[N: static[int]] = object - - proc bindStaticN[N](foo: Foo[N]) = - var ar0: array[3, int] - var ar1: array[N, int] - var ar2: array[1..N, int] - var ar3: array[0..(N+10), float] - echo N - - var f: Foo[3] - f.bindStaticN - - # case 2 - - type - ObjectWithStatic[X, Y: static[int], T] = object - bar: array[X * Y, T] # this one works - - AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] - - var - x: ObjectWithStatic[1, 2, int] - y: AliasWithStatic[2, 3, int] - - # case 3 - - type - Bar[N: static[int], T] = object - bar: array[N, T] - - proc `[]`[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = - assert high(n) == N-1 - result = f.bar[n] - - var b: Bar[3, int] - doAssert b[2] == 0 - - - -block t3977: - type Foo[N: static[int]] = object - - proc foo[N](x: Foo[N]) = - let n = N - doAssert N == n - - var f1: Foo[42] - f1.foo - - - -block t5570: - type - BaseFruit[T] = object of RootObj - color: T - - Banana[T] = object of BaseFruit[uint32] - weight: T - - macro printTypeName(typ: typed): untyped = - echo "type ", getType(typ).repr - - proc setColor[K](self: var BaseFruit[K], c: int) = - printTypeName(self.color) - self.color = uint32(c) - - var x: Banana[float64] - x.weight = 17 - printTypeName(x.color) - x.setColor(100) - echo x - - - -block t5643: - type - Matrix[M, N: static[int], T: SomeFloat] = object - data: ref array[N * M, T] - Matrix64[M, N: static[int]] = Matrix[M, N, float64] - - proc zeros64(M,N: static[int]): Matrix64[M,N] = - new result.data - for i in 0 ..< (M * N): - result.data[i] = 0'f64 - - proc bar[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) = - discard - - let a = zeros64(2,2) - bar(a,a) - # https://github.com/nim-lang/Nim/issues/5643 - # - # The test case was failing here, because the compiler failed to - # detect the two matrix instantiations as the same type. - # - # The root cause was that the `T` type variable is a different - # type after the first Matrix type has been matched. - # - # Sigmatch was failing to match the second version of `T`, but - # due to some complex interplay between tyOr, tyTypeDesc and - # tyGenericParam this was allowed to went through. The generic - # instantiation of the second matrix was incomplete and the - # generic cache lookup failed, producing two separate types. - - - -block t5683: - type Matrix[M,N: static[int]] = array[M, array[N, float]] - - proc det[M,N](a: Matrix[M,N]): int = N*10 + M - proc perm[M,N](a: Matrix[M,N]): int = M*10 + N - - const - a = [ [1.0, 2.0] - , [3.0, 4.0] - ] - - echo "perm: ", a.perm, " det: ", a.det - - # This tests multiple instantiations of a generic - # proc involving static params: - type - Vector64[N: static[int]] = ref array[N, float64] - Array64[N: static[int]] = array[N, float64] - - proc vector[N: static[int]](xs: Array64[N]): Vector64[N] = - new result - for i in 0 ..< N: - result[i] = xs[i] - - let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) - let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0]) - let v3 = vector([1.0, 2.0, 3.0, 4.0]) - - - -block t7794: - type - Data[T:SomeNumber, U:SomeFloat] = ref object - x: T - value*: U - - var d = Data[int, float64](x:10.int, value:2'f64) - doAssert d.x == 10 - doAssert d.value == 2.0 - - - -block t8403: - proc sum[T](s: seq[T], R: typedesc): R = - var sum: R = 0 - for x in s: - sum += R(x) - return sum - - doAssert @[1, 2, 3].sum(float) == 6.0 - - - -block t8439: - type - Cardinal = enum - north, east, south, west - - proc foo[cardinal: static[Cardinal]](): int = 1 - doAssert foo[north]() == 1 - - - -block t8694: - when true: - # Error: undeclared identifier: '|' - proc bar[T](t:T): bool = - runnableExamples: - type Foo = int | float - true - doAssert bar(0) - - when true: - # ok - proc bar(t:int): bool = - runnableExamples: - type Foo = int | float - true - doAssert bar(0) - - when true: - # Error: undeclared identifier: '|' - proc bar(t:typedesc): bool = - runnableExamples: - type Foo = int | float - true - doAssert bar(int) - - - -block t9130: - when true: - # stack overflow - template baz1(iter: untyped): untyped = - runnableExamples: - import sugar - proc fun(a: proc(x:int): int) = discard - baz1(fun(x:int => x)) - discard - - proc foo1[A](ts: A) = - baz1(ts) - - when true: - # ok - template baz2(iter: untyped): untyped = - runnableExamples: - import sugar - proc fun(a: proc(x:int): int) = discard - baz2(fun(x:int => x)) - discard - - proc foo2(ts: int) = - baz2(ts) - - when true: - # stack overflow - template baz3(iter: untyped): untyped = - runnableExamples: - baz3(fun(x:int => x)) - discard - - proc foo3[A](ts: A) = - baz3(ts) - - - -block t1056: - type - TMatrix[N,M: static[int], T] = object - data: array[0..N*M-1, T] - - TMat2[T] = TMatrix[2,2,T] - - proc echoMatrix(a: TMatrix) = - echo a.type.name - echo TMatrix.N - - proc echoMat2(a: TMat2) = - echo TMat2.M - - var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) - - echoMatrix m - - - -block t4884: - type - Vec[N: static[int], T] = object - arr*: array[N, T] - - Mat[N,M: static[int], T] = object - arr: array[N, Vec[M,T]] - - var m : Mat[3,3,float] - var strMat : Mat[m.N, m.M, string] - var lenMat : Mat[m.N, m.M, int] - - - -block t2221: - var tblo: TableRef[string, int] - doAssert tblo == nil - - - -block t2304: - type TV2[T:SomeNumber] = array[0..1, T] - proc newV2T[T](x, y: T=0): TV2[T] = [x, y] - - let x = newV2T[float](0.9, 0.1) - echo(@x) - - - -block t2752: - proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) = - iterator aNameWhichWillConflict(): T {.closure.}= - for x in it(): - if f(x): - yield x - result = aNameWhichWillConflict - - iterator testIt():int {.closure.}= - yield -1 - yield 2 - - #let unusedVariable = myFilter(testIt, (x: int) => x > 0) - - proc onlyPos(it: (iterator(): int)): (iterator(): int)= - iterator aNameWhichWillConflict(): int {.closure.}= - var filtered = onlyPos(myFilter(it, (x:int) => x > 0)) - for x in filtered(): - yield x - result = aNameWhichWillConflict - - let x = onlyPos(testIt) - - - -block t5106: - 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 - - - -block t3055: - proc b(t: int | string) - proc a(t: int) = b(t) - proc b(t: int | string) = echo "b()" - a(1) - - # test recursive generics still work: - proc fac[T](x: T): T = - if x == 0: return 1 - else: return fac(x-1)*x - - doAssert fac(6) == 720 - doAssert fac(5.0) == 120.0 - - - # test recursive generic with forwarding: - proc fac2[T](x: T): T - - doAssert fac2(6) == 720 - doAssert fac2(5.0) == 120.0 - - proc fac2[T](x: T): T = - if x == 0: return 1 - else: return fac2(x-1)*x - - - -block t1187: - type - TEventArgs = object - skip: bool - TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.} - TEvent[T] = object - #handlers: seq[TEventHandler[T]] # Does not work - handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works - - TData = object - x: int - - TSomething = object - s: TEvent[TData] - - proc init[T](e: var TEvent[T]) = - e.handlers.newSeq(0) - - #proc add*[T](e: var TEvent[T], h: proc (e: var TEventArgs, data: T) {.closure.}) = - # this line works - proc add[T](e: var TEvent[T], h: TEventHandler[T]) = - # this line does not work - e.handlers.add(h) - - proc main () = - var something: TSomething - something.s.init() - var fromOutside = 4711 - - something.s.add() do (e: var TEventArgs, data: TData): - var x = data.x - x = fromOutside - - main() - - - -block t1919: - type - Base[M] = object of RootObj - a : M - Sub1[M] = object of Base[M] - b : int - Sub2[M] = object of Sub1[M] - c : int - - var x: Sub2[float] - doAssert x.a == 0.0 - - - -block t5756: - 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() - - - -block t7854: - type - Stream = ref StreamObj - StreamObj = object of RootObj - - InhStream = ref InhStreamObj - InhStreamObj = object of Stream - f: string - - proc newInhStream(f: string): InhStream = - new(result) - result.f = f - - var val: int - let str = newInhStream("input_file.json") - - block: - # works: - proc load[T](data: var T, s: Stream) = - discard - load(val, str) - - block: - # works - proc load[T](s: Stream, data: T) = - discard - load(str, val) - - block: - # broken - proc load[T](s: Stream, data: var T) = - discard - load(str, val) - - - -block t5864: - 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() - - doAssert a == 1 - doAssert b == 2 - - - -block t3498: - template defaultOf[T](t: T): untyped = (var d: T; d) - - doAssert defaultOf(1) == 0 - - # assignment using template - - template tassign[T](x: var seq[T]) = - x = @[1, 2, 3] - - var y: seq[int] - tassign(y) #<- x is expected = @[1, 2, 3] - tassign(y) - - doAssert y[0] == 1 - doAssert y[1] == 2 - doAssert y[2] == 3 - - - -block t3499: - proc foo[T](x: proc(): T) = - echo "generic ", x() - - proc foo(x: proc(): int) = - echo "concrete ", x() - - # note the following 'proc' is not .closure! - foo(proc (): auto {.nimcall.} = 88) - - # bug #3499 last snippet fixed - # bug 705 last snippet fixed - - - - -block t797: - proc foo[T](s:T):string = $s - - type IntStringProc = proc(x: int): string - - var f1 = IntStringProc(foo) - var f2: proc(x: int): string = foo - var f3: IntStringProc = foo - - echo f1(1), f2(2), f3(3) - - for x in map([1,2,3], foo): echo x - - - -block t4658: - var x = 123 - proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x)) - proc quote(s: string): string = "!" & s & "!" - echo twice(quote)("Hi") - - - -block t4589: - type SimpleTable[TKey, TVal] = TableRef[TKey, TVal] - template newSimpleTable(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]() - var fontCache : SimpleTable[string, SimpleTable[int32, int]] - fontCache = newSimpleTable(string, SimpleTable[int32, int]) - - - -block t4600: - template foo(x: untyped): untyped = echo 1 - template foo(x,y: untyped): untyped = echo 2 - - proc bar1[T](x: T) = foo(x) - proc bar2(x: float) = foo(x,x) - proc bar3[T](x: T) = foo(x,x) - - - -block t4672: - type - EnumContainer[T: enum] = object - v: T - SomeEnum {.pure.} = enum - A,B,C - - proc value[T: enum](this: EnumContainer[T]): T = - this.v - - var enumContainer: EnumContainer[SomeEnum] - discard enumContainer.value() - - - -block t4863: - type - G[i,j: static[int]] = object - v:float - H[j: static[int]] = G[0,j] - proc p[i,j: static[int]](x:G[i,j]) = echo "G:", i, ",", j, ":", x.v - proc q[j: static[int]](x:H[j]) = echo "H:", j, ":", x.v - - var - g0 = G[0,1](v: 0.1) - h0:H[1] = g0 - p(g0) - p(h0) - q(h0) - - - -block t1684: - type - BaseType {.inheritable pure.} = object - idx: int - - DerivedType {.final pure.} = object of BaseType - - proc index[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx - proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx) - - let d = newDerived(2) - assert(d.index == 2) - - - -block t5632: - type Option[T] = object - - proc point[A](v: A, t: typedesc[Option[A]]): Option[A] = - discard - - discard point(1, Option) - - - -block t7247: - type n8 = range[0'i8..127'i8] - var tab = initSet[n8]() - doAssert tab.contains(8) == false - - - -block t3717: - type - Foo[T] = object - a: T - Foo1[T] = Foo[T] | int - - proc foo[T](s: Foo1[Foo[T]]): T = - 5 - - var f: Foo[Foo[int]] - discard foo(f) diff --git a/tests/generics/tvarious.nim b/tests/generics/tvarious.nim deleted file mode 100644 index 5e18995f5..000000000 --- a/tests/generics/tvarious.nim +++ /dev/null @@ -1,245 +0,0 @@ -discard """ - output: ''' -we -direct -generic -generic -''' -""" - - -import algorithm, sugar, sequtils, typetraits, asyncdispatch - - -block tconfusing_arrow: - type Deck = object - value: int - - proc sort(h: var seq[Deck]) = - # works: - h.sort(proc (x, y: Deck): auto = - cmp(x.value, y.value)) - # fails: - h.sort((x, y: Deck) => cmp(ord(x.value), ord(y.value))) - - var player: seq[Deck] = @[] - player.sort() - - - -block tdictdestruct: - type - TDict[TK, TV] = object - k: TK - v: TV - PDict[TK, TV] = ref TDict[TK, TV] - - proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) = - discard - - proc destroyDict[TK, TV](a: PDict[TK, TV]) = - return - proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] = - fakeNew(result, destroyDict[TK, TV]) - - # Problem: destroyDict is not instantiated when newDict is instantiated! - discard newDict("a", "b") - - - -block tgenericdefaults: - type - TFoo[T, U, R = int] = object - x: T - y: U - z: R - - TBar[T] = TFoo[T, array[4, T], T] - - var x1: TFoo[int, float] - - static: - assert type(x1.x) is int - assert type(x1.y) is float - assert type(x1.z) is int - - var x2: TFoo[string, R = float, U = seq[int]] - - static: - assert type(x2.x) is string - assert type(x2.y) is seq[int] - assert type(x2.z) is float - - var x3: TBar[float] - - static: - assert type(x3.x) is float - assert type(x3.y) is array[4, float] - assert type(x3.z) is float - - - -block tprop: - type - TProperty[T] = object of RootObj - getProc: proc(property: TProperty[T]): T {.nimcall.} - setProc: proc(property: TProperty[T], value: T) {.nimcall.} - value: T - - proc newProperty[T](value: RootObj): TProperty[T] = - result.getProc = proc (property: TProperty[T]) = - return property.value - - - -block trefs: - type - PA[T] = ref TA[T] - TA[T] = object - field: T - var a: PA[string] - new(a) - a.field = "some string" - - proc someOther[T](len: string): seq[T] = discard - proc someOther[T](len: int): seq[T] = echo "we" - - proc foo[T](x: T) = - var s = someOther[T](34) - #newSeq[T](34) - - foo 23 - - when false: - # Compiles unless you use var a: PA[string] - type - PA = ref TA - TA[T] = object - - # Cannot instantiate: - type - TA[T] = object - a: PA[T] - PA[T] = ref TA[T] - - type - PA[T] = ref TA[T] - TA[T] = object - - - -block tsharedcases: - proc typeNameLen(x: typedesc): int {.compileTime.} = - result = x.name.len - macro selectType(a, b: typedesc): typedesc = - result = a - - type - Foo[T] = object - data1: array[T.high, int] - data2: array[typeNameLen(T), float] - data3: array[0..T.typeNameLen, selectType(float, int)] - MyEnum = enum A, B, C, D - - var f1: Foo[MyEnum] - var f2: Foo[int8] - - doAssert high(f1.data1) == 2 # (D = 3) - 1 == 2 - doAssert high(f1.data2) == 5 # (MyEnum.len = 6) - 1 == 5 - - doAssert high(f2.data1) == 126 # 127 - 1 == 126 - doAssert high(f2.data2) == 3 # int8.len - 1 == 3 - - static: - assert high(f1.data1) == ord(C) - assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high - - assert high(f2.data1) == 126 - assert high(f2.data2) == 3 - - assert high(f1.data3) == 6 # length of MyEnum - assert high(f2.data3) == 4 # length of int8 - - assert f2.data3[0] is float - - - -block tmap_auto: - let x = map(@[1, 2, 3], x => x+10) - assert x == @[11, 12, 13] - - let y = map(@[(1,"a"), (2,"b"), (3,"c")], x => $x[0] & x[1]) - assert y == @["1a", "2b", "3c"] - - proc eatsTwoArgProc[T,S,U](a: T, b: S, f: proc(t: T, s: S): U): U = - f(a,b) - - let z = eatsTwoArgProc(1, "a", (t,s) => $t & s) - assert z == "1a" - - - -block tproctypecache_falsepositive: - type - Callback = proc() {.closure, gcsafe.} - GameState = ref object - playerChangeHandlers: seq[Callback] - - proc newGameState(): GameState = - result = GameState( - playerChangeHandlers: newSeq[Callback]() # this fails - ) - - - -block tptrinheritance: - type NSPasteboardItem = ptr object - type NSPasteboard = ptr object - type NSArrayAbstract = ptr object {.inheritable.} - type NSMutableArrayAbstract = ptr object of NSArrayAbstract - type NSArray[T] = ptr object of NSArrayAbstract - type NSMutableArray[T] = ptr object of NSArray[T] - - proc newMutableArrayAbstract(): NSMutableArrayAbstract = discard - - template newMutableArray(T: typedesc): NSMutableArray[T] = - cast[NSMutableArray[T]](newMutableArrayAbstract()) - - proc writeObjects(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard - - let a = newMutableArray NSPasteboardItem - var x: NSMutableArray[NSPasteboardItem] - var y: NSArray[NSPasteboardItem] = x - - writeObjects(nil, a) - - - -block tsigtypeop: - type Vec3[T] = array[3, T] - - proc foo(x: Vec3, y: Vec3.T, z: x.T): x.type.T = - return 10 - - var y: Vec3[int] = [1, 2, 3] - var z: int = foo(y, 3, 4) - - - -block tvarargs_vs_generics: - proc withDirectType(args: string) = - echo "direct" - proc withDirectType[T](arg: T) = - echo "generic" - proc withOpenArray(args: openarray[string]) = - echo "openarray" - proc withOpenArray[T](arg: T) = - echo "generic" - proc withVarargs(args: varargs[string]) = - echo "varargs" - proc withVarargs[T](arg: T) = - echo "generic" - - withDirectType "string" - withOpenArray "string" - withVarargs "string" diff --git a/tests/iter/tissues.nim b/tests/iter/tissues.nim deleted file mode 100644 index 773e7dbff..000000000 --- a/tests/iter/tissues.nim +++ /dev/null @@ -1,215 +0,0 @@ -discard """ - output: ''' -0 -1 -2 -3 -4 -1 -start -false -0 -1 -2 -end -@[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42] -1002 -0 -1 -2 -7 -''' -""" - - -import algorithm, math, sequtils, strutils - - -block t338: - proc moo(): iterator (): int = - iterator fooGen: int {.closure.} = - while true: - yield result - result.inc - return fooGen - - var foo = moo() - - for i in 0 .. 4: - echo foo() - - - -block t8041: - iterator xy[T](a: T, b: set[T]): T = - if a in b: - yield a - - for a in xy(1'i8, {}): - for b in xy(a, {}): - echo a - - - -block t3837_chained: - iterator t1(): int {.closure.} = - yield 1 - - iterator t2(): int {.closure.} = - for i in t1(): - yield i - - for i in t2(): - echo $i - - - proc iter1(): (iterator: int) = - let coll = [0,1,2] - result = iterator: int {.closure.} = - for i in coll: - yield i - - proc iter2(it: (iterator: int)): (iterator: int) = - result = iterator: int {.closure.} = - echo finished(it) - for i in it(): - yield i - - echo "start" - let myiter1 = iter1() - let myiter2 = iter2(myiter1) - for i in myiter2(): - echo i - echo "end" - - - type Iterable[T] = (iterator: T) | Slice[T] - ## Everything that can be iterated over, iterators and slices so far. - - proc toIter[T](s: Slice[T]): iterator: T = - ## Iterate over a slice. - iterator it: T {.closure.} = - for x in s.a..s.b: - yield x - return it - - proc toIter[T](i: iterator: T): iterator: T = - ## Nop - i - - iterator map[T,S](i: Iterable[T], f: proc(x: T): S): S = - let i = toIter(i) - for x in i(): - yield f(x) - - proc filter[T](i: Iterable[T], f: proc(x: T): bool): iterator: T = - let i = toIter(i) - iterator it: T {.closure.} = - for x in i(): - if f(x): - yield x - result = it - - iterator filter[T](i: Iterable[T], f: proc(x: T): bool): T = - let i = toIter(i) - for x in i(): - if f(x): - yield x - - var it = toSeq(filter(2..10, proc(x: int): bool = x mod 2 == 0)) - doAssert it == @[2, 4, 6, 8, 10] - it = toSeq(map(filter(2..10, proc(x: int): bool = x mod 2 == 0), proc(x: int): int = x * 2)) - doAssert it == @[4, 8, 12, 16, 20] - - - -block t3221_complex: - iterator permutations[T](ys: openarray[T]): seq[T] = - var - d = 1 - c = newSeq[int](ys.len) - xs = newSeq[T](ys.len) - for i, y in ys: xs[i] = y - yield xs - block outer: - while true: - while d > 1: - dec d - c[d] = 0 - while c[d] >= d: - inc d - if d >= ys.len: break outer - let i = if (d and 1) == 1: c[d] else: 0 - swap xs[i], xs[d] - yield xs - inc c[d] - - proc dig_vectors(): void = - var v_nums: seq[int] - v_nums = newSeq[int](1) - for perm in permutations(toSeq(0 .. 1)): - v_nums[0] = 1 - - dig_vectors() - - - -block t3499_keepstate: - proc slice[T](iter: iterator(): T {.closure.}, sl: auto): seq[T] = - var res: seq[int64] = @[] - var i = 0 - for n in iter(): - if i > sl.b: - break - if i >= sl.a: - res.add(n) - inc i - res - - iterator harshad(): int64 {.closure.} = - for n in 1 ..< int64.high: - var sum = 0 - for ch in string($n): - sum += parseInt("" & ch) - if n mod sum == 0: - yield n - - echo harshad.slice 0 ..< 20 - - for n in harshad(): - if n > 1000: - echo n - break - - # bug #3499 last snippet fixed - # bug 705 last snippet fixed - - - -block t1725_nested: - iterator factory(): int {.closure.} = - iterator bar(): int {.closure.} = - yield 0 - yield 1 - yield 2 - - for x in bar(): yield x - - for x in factory(): - echo x - - - -block t2023_objiter: - type - Obj = object - iter: iterator (): int8 {.closure.} - - iterator test(): int8 {.closure.} = - yield 7 - - proc init():Obj= - result.iter = test - - var o = init() - echo(o.iter()) diff --git a/tests/iter/titer_issues.nim b/tests/iter/titer_issues.nim new file mode 100644 index 000000000..773e7dbff --- /dev/null +++ b/tests/iter/titer_issues.nim @@ -0,0 +1,215 @@ +discard """ + output: ''' +0 +1 +2 +3 +4 +1 +start +false +0 +1 +2 +end +@[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42] +1002 +0 +1 +2 +7 +''' +""" + + +import algorithm, math, sequtils, strutils + + +block t338: + proc moo(): iterator (): int = + iterator fooGen: int {.closure.} = + while true: + yield result + result.inc + return fooGen + + var foo = moo() + + for i in 0 .. 4: + echo foo() + + + +block t8041: + iterator xy[T](a: T, b: set[T]): T = + if a in b: + yield a + + for a in xy(1'i8, {}): + for b in xy(a, {}): + echo a + + + +block t3837_chained: + iterator t1(): int {.closure.} = + yield 1 + + iterator t2(): int {.closure.} = + for i in t1(): + yield i + + for i in t2(): + echo $i + + + proc iter1(): (iterator: int) = + let coll = [0,1,2] + result = iterator: int {.closure.} = + for i in coll: + yield i + + proc iter2(it: (iterator: int)): (iterator: int) = + result = iterator: int {.closure.} = + echo finished(it) + for i in it(): + yield i + + echo "start" + let myiter1 = iter1() + let myiter2 = iter2(myiter1) + for i in myiter2(): + echo i + echo "end" + + + type Iterable[T] = (iterator: T) | Slice[T] + ## Everything that can be iterated over, iterators and slices so far. + + proc toIter[T](s: Slice[T]): iterator: T = + ## Iterate over a slice. + iterator it: T {.closure.} = + for x in s.a..s.b: + yield x + return it + + proc toIter[T](i: iterator: T): iterator: T = + ## Nop + i + + iterator map[T,S](i: Iterable[T], f: proc(x: T): S): S = + let i = toIter(i) + for x in i(): + yield f(x) + + proc filter[T](i: Iterable[T], f: proc(x: T): bool): iterator: T = + let i = toIter(i) + iterator it: T {.closure.} = + for x in i(): + if f(x): + yield x + result = it + + iterator filter[T](i: Iterable[T], f: proc(x: T): bool): T = + let i = toIter(i) + for x in i(): + if f(x): + yield x + + var it = toSeq(filter(2..10, proc(x: int): bool = x mod 2 == 0)) + doAssert it == @[2, 4, 6, 8, 10] + it = toSeq(map(filter(2..10, proc(x: int): bool = x mod 2 == 0), proc(x: int): int = x * 2)) + doAssert it == @[4, 8, 12, 16, 20] + + + +block t3221_complex: + iterator permutations[T](ys: openarray[T]): seq[T] = + var + d = 1 + c = newSeq[int](ys.len) + xs = newSeq[T](ys.len) + for i, y in ys: xs[i] = y + yield xs + block outer: + while true: + while d > 1: + dec d + c[d] = 0 + while c[d] >= d: + inc d + if d >= ys.len: break outer + let i = if (d and 1) == 1: c[d] else: 0 + swap xs[i], xs[d] + yield xs + inc c[d] + + proc dig_vectors(): void = + var v_nums: seq[int] + v_nums = newSeq[int](1) + for perm in permutations(toSeq(0 .. 1)): + v_nums[0] = 1 + + dig_vectors() + + + +block t3499_keepstate: + proc slice[T](iter: iterator(): T {.closure.}, sl: auto): seq[T] = + var res: seq[int64] = @[] + var i = 0 + for n in iter(): + if i > sl.b: + break + if i >= sl.a: + res.add(n) + inc i + res + + iterator harshad(): int64 {.closure.} = + for n in 1 ..< int64.high: + var sum = 0 + for ch in string($n): + sum += parseInt("" & ch) + if n mod sum == 0: + yield n + + echo harshad.slice 0 ..< 20 + + for n in harshad(): + if n > 1000: + echo n + break + + # bug #3499 last snippet fixed + # bug 705 last snippet fixed + + + +block t1725_nested: + iterator factory(): int {.closure.} = + iterator bar(): int {.closure.} = + yield 0 + yield 1 + yield 2 + + for x in bar(): yield x + + for x in factory(): + echo x + + + +block t2023_objiter: + type + Obj = object + iter: iterator (): int8 {.closure.} + + iterator test(): int8 {.closure.} = + yield 7 + + proc init():Obj= + result.iter = test + + var o = init() + echo(o.iter()) diff --git a/tests/macros/tissues.nim b/tests/macros/tissues.nim deleted file mode 100644 index ecdcd5da9..000000000 --- a/tests/macros/tissues.nim +++ /dev/null @@ -1,241 +0,0 @@ -discard """ - msg: ''' -proc init(foo129050: int; bar129052: typedesc[int]): int = - foo129050 - -IntLit 5 -proc (x: int): string => typeDesc[proc[string, int]] -proc (x: int): void => typeDesc[proc[void, int]] -proc (x: int) => typeDesc[proc[void, int]] -x => uncheckedArray[int] -a -s -d -f -TTaa -TTaa -TTaa -TTaa -true -true -nil -42 -false -true -''' - - output: ''' -range[0 .. 100] -array[0 .. 100, int] -10 -test -''' -""" - - -import macros, parseutils - - -block t7723: - macro foo1(): untyped = - result = newStmtList() - result.add quote do: - proc init(foo: int, bar: typedesc[int]): int = - foo - - expandMacros: - foo1() - - doAssert init(1, int) == 1 - - - -block t8706: - macro varargsLen(args:varargs[untyped]): untyped = - doAssert args.kind == nnkArglist - doAssert args.len == 0 - result = newLit(args.len) - - template bar(a0:varargs[untyped]): untyped = - varargsLen(a0) - - template foo(x: int, a0:varargs[untyped]): untyped = - bar(a0) - - doAssert foo(42) == 0 - doAssert bar() == 0 - - - -block t9194: - type - Foo1 = range[0 .. 100] - Foo2 = array[0 .. 100, int] - - macro get(T: typedesc): untyped = - # Get the X out of typedesc[X] - let tmp = getTypeImpl(T) - result = newStrLitNode(getTypeImpl(tmp[1]).repr) - - echo Foo1.get - echo Foo2.get - - - -block t1944: - template t(e: untyped): untyped = - macro m(eNode: untyped): untyped = - echo eNode.treeRepr - m e - - t 5 - - -block t926: - proc test(f: var NimNode) {.compileTime.} = - f = newNimNode(nnkStmtList) - f.add newCall(newIdentNode("echo"), newLit(10)) - - macro blah(prc: untyped): untyped = - result = prc - test(result) - - proc test() {.blah.} = - echo 5 - - - -block t2211: - macro showType(t:typed): untyped = - let ty = t.getType - echo t.repr, " => ", ty.repr - - showType(proc(x:int): string) - showType(proc(x:int): void) - showType(proc(x:int)) - - var x: UncheckedArray[int] - showType(x) - - - -block t1140: - proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} = - var splitValue: string - var read = value.parseUntil(splitValue, '$', index) - - # when false: - if false: - var identifier: string - read = value.parseWhile(identifier, {}, index) - node.add newCall("add", ident("result"), newCall("$", ident(identifier))) - - if splitValue.len > 0: - node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue)) - - proc parse_template(node: NimNode, value: string) {.compiletime.} = - var index = 0 - while index < value.len and - parse_until_symbol(node, value, index): discard - - macro tmpli(body: untyped): typed = - result = newStmtList() - result.add parseExpr("result = \"\"") - result.parse_template body[1].strVal - - - proc actual: string = tmpli html""" -

Test!

- """ - - proc another: string = tmpli html""" -

what

- """ - - - -block tbugs: - type - Foo = object - s: char - - iterator test2(f: string): Foo = - for i in f: - yield Foo(s: i) - - macro test(): untyped = - for i in test2("asdf"): - echo i.s - - test() - - - # bug 1297 - - type TType = tuple[s: string] - - macro echotest(): untyped = - var t: TType - t.s = "" - t.s.add("test") - result = newCall(newIdentNode("echo"), newStrLitNode(t.s)) - - echotest() - - # bug #1103 - - type - Td = tuple - a:string - b:int - - proc get_data(d: Td) : string {.compileTime.} = - result = d.a # Works if a literal string is used here. - # Bugs if line A or B is active. Works with C - result &= "aa" # A - #result.add("aa") # B - #result = result & "aa" # C - - macro m(s:static[Td]) : untyped = - echo get_data(s) - echo get_data(s) - result = newEmptyNode() - - const s = ("TT", 3) - m(s) - m(s) - - # bug #933 - - proc nilcheck(): NimNode {.compileTime.} = - echo(result == nil) # true - echo(result.isNil) # true - echo(repr(result)) # nil - - macro testnilcheck(): untyped = - result = newNimNode(nnkStmtList) - discard nilcheck() - - testnilcheck() - - # bug #1323 - - proc calc(): array[1, int] = - result[0].inc() - result[0].inc() - - const c = calc() - doAssert c[0] == 2 - - - # bug #3046 - - macro sampleMacroInt(i: int): untyped = - echo i.intVal - - macro sampleMacroBool(b: bool): untyped = - echo b.boolVal - - sampleMacroInt(42) - sampleMacroBool(false) - sampleMacroBool(system.true) diff --git a/tests/macros/tmacros_issues.nim b/tests/macros/tmacros_issues.nim new file mode 100644 index 000000000..ecdcd5da9 --- /dev/null +++ b/tests/macros/tmacros_issues.nim @@ -0,0 +1,241 @@ +discard """ + msg: ''' +proc init(foo129050: int; bar129052: typedesc[int]): int = + foo129050 + +IntLit 5 +proc (x: int): string => typeDesc[proc[string, int]] +proc (x: int): void => typeDesc[proc[void, int]] +proc (x: int) => typeDesc[proc[void, int]] +x => uncheckedArray[int] +a +s +d +f +TTaa +TTaa +TTaa +TTaa +true +true +nil +42 +false +true +''' + + output: ''' +range[0 .. 100] +array[0 .. 100, int] +10 +test +''' +""" + + +import macros, parseutils + + +block t7723: + macro foo1(): untyped = + result = newStmtList() + result.add quote do: + proc init(foo: int, bar: typedesc[int]): int = + foo + + expandMacros: + foo1() + + doAssert init(1, int) == 1 + + + +block t8706: + macro varargsLen(args:varargs[untyped]): untyped = + doAssert args.kind == nnkArglist + doAssert args.len == 0 + result = newLit(args.len) + + template bar(a0:varargs[untyped]): untyped = + varargsLen(a0) + + template foo(x: int, a0:varargs[untyped]): untyped = + bar(a0) + + doAssert foo(42) == 0 + doAssert bar() == 0 + + + +block t9194: + type + Foo1 = range[0 .. 100] + Foo2 = array[0 .. 100, int] + + macro get(T: typedesc): untyped = + # Get the X out of typedesc[X] + let tmp = getTypeImpl(T) + result = newStrLitNode(getTypeImpl(tmp[1]).repr) + + echo Foo1.get + echo Foo2.get + + + +block t1944: + template t(e: untyped): untyped = + macro m(eNode: untyped): untyped = + echo eNode.treeRepr + m e + + t 5 + + +block t926: + proc test(f: var NimNode) {.compileTime.} = + f = newNimNode(nnkStmtList) + f.add newCall(newIdentNode("echo"), newLit(10)) + + macro blah(prc: untyped): untyped = + result = prc + test(result) + + proc test() {.blah.} = + echo 5 + + + +block t2211: + macro showType(t:typed): untyped = + let ty = t.getType + echo t.repr, " => ", ty.repr + + showType(proc(x:int): string) + showType(proc(x:int): void) + showType(proc(x:int)) + + var x: UncheckedArray[int] + showType(x) + + + +block t1140: + proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} = + var splitValue: string + var read = value.parseUntil(splitValue, '$', index) + + # when false: + if false: + var identifier: string + read = value.parseWhile(identifier, {}, index) + node.add newCall("add", ident("result"), newCall("$", ident(identifier))) + + if splitValue.len > 0: + node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue)) + + proc parse_template(node: NimNode, value: string) {.compiletime.} = + var index = 0 + while index < value.len and + parse_until_symbol(node, value, index): discard + + macro tmpli(body: untyped): typed = + result = newStmtList() + result.add parseExpr("result = \"\"") + result.parse_template body[1].strVal + + + proc actual: string = tmpli html""" +

Test!

+ """ + + proc another: string = tmpli html""" +

what

+ """ + + + +block tbugs: + type + Foo = object + s: char + + iterator test2(f: string): Foo = + for i in f: + yield Foo(s: i) + + macro test(): untyped = + for i in test2("asdf"): + echo i.s + + test() + + + # bug 1297 + + type TType = tuple[s: string] + + macro echotest(): untyped = + var t: TType + t.s = "" + t.s.add("test") + result = newCall(newIdentNode("echo"), newStrLitNode(t.s)) + + echotest() + + # bug #1103 + + type + Td = tuple + a:string + b:int + + proc get_data(d: Td) : string {.compileTime.} = + result = d.a # Works if a literal string is used here. + # Bugs if line A or B is active. Works with C + result &= "aa" # A + #result.add("aa") # B + #result = result & "aa" # C + + macro m(s:static[Td]) : untyped = + echo get_data(s) + echo get_data(s) + result = newEmptyNode() + + const s = ("TT", 3) + m(s) + m(s) + + # bug #933 + + proc nilcheck(): NimNode {.compileTime.} = + echo(result == nil) # true + echo(result.isNil) # true + echo(repr(result)) # nil + + macro testnilcheck(): untyped = + result = newNimNode(nnkStmtList) + discard nilcheck() + + testnilcheck() + + # bug #1323 + + proc calc(): array[1, int] = + result[0].inc() + result[0].inc() + + const c = calc() + doAssert c[0] == 2 + + + # bug #3046 + + macro sampleMacroInt(i: int): untyped = + echo i.intVal + + macro sampleMacroBool(b: bool): untyped = + echo b.boolVal + + sampleMacroInt(42) + sampleMacroBool(false) + sampleMacroBool(system.true) diff --git a/tests/macros/tmacros_various.nim b/tests/macros/tmacros_various.nim new file mode 100644 index 000000000..15bd28a37 --- /dev/null +++ b/tests/macros/tmacros_various.nim @@ -0,0 +1,111 @@ +discard """ + msg: ''' +range[0 .. 100] +array[0 .. 100, int] +10 +test +''' + + output: ''' +x = 10 +x + y = 30 +proc foo[T, N: static[int]]() +proc foo[T; N: static[int]]() +a[0]: 42 +a[1]: 45 +x: some string +''' +""" + + +import macros, sugar + + +block tdump: + let + x = 10 + y = 20 + dump x + dump(x + y) + + +block texprcolonexpr: + macro def(x): untyped = + echo treeRepr(x) + + def name(a, b:cint) => nil + + + +block tgenericparams: + macro test():string = + let expr0 = "proc foo[T, N: static[int]]()" + let expr1 = "proc foo[T; N: static[int]]()" + + $toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1)) + + echo test() + + + +block tidgen: + # Test compile-time state in same module + var gid {.compileTime.} = 3 + + macro genId(): int = + result = newIntLitNode(gid) + inc gid + + proc Id1(): int {.compileTime.} = return genId() + proc Id2(): int {.compileTime.} = return genId() + + doAssert Id1() == 3 + doAssert Id2() == 4 + + + +block tlexerex: + macro match(s: cstring|string; pos: int; sections: varargs[untyped]): untyped = + for sec in sections: + expectKind sec, nnkOfBranch + expectLen sec, 2 + result = newStmtList() + + var input = "the input" + var pos = 0 + match input, pos: + of r"[a-zA-Z_]\w+": echo "an identifier" + of r"\d+": echo "an integer" + of r".": echo "something else" + + + +block tlineinfo: + # issue #5617, feature request + type Test = object + + macro mixer(n: typed): untyped = + let x = newIdentNode("echo") + x.copyLineInfo(n) + result = newLit(x.lineInfo == n.lineInfo) + + var z = mixer(Test) + doAssert z + + + +block tdebugstmt: + macro debug(n: varargs[untyped]): untyped = + result = newNimNode(nnkStmtList, n) + for i in 0..n.len-1: + add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) + add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) + add(result, newCall("writeLine", newIdentNode("stdout"), n[i])) + + var + a: array[0..10, int] + x = "some string" + a[0] = 42 + a[1] = 45 + + debug(a[0], a[1], x) diff --git a/tests/macros/tvarious.nim b/tests/macros/tvarious.nim deleted file mode 100644 index 15bd28a37..000000000 --- a/tests/macros/tvarious.nim +++ /dev/null @@ -1,111 +0,0 @@ -discard """ - msg: ''' -range[0 .. 100] -array[0 .. 100, int] -10 -test -''' - - output: ''' -x = 10 -x + y = 30 -proc foo[T, N: static[int]]() -proc foo[T; N: static[int]]() -a[0]: 42 -a[1]: 45 -x: some string -''' -""" - - -import macros, sugar - - -block tdump: - let - x = 10 - y = 20 - dump x - dump(x + y) - - -block texprcolonexpr: - macro def(x): untyped = - echo treeRepr(x) - - def name(a, b:cint) => nil - - - -block tgenericparams: - macro test():string = - let expr0 = "proc foo[T, N: static[int]]()" - let expr1 = "proc foo[T; N: static[int]]()" - - $toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1)) - - echo test() - - - -block tidgen: - # Test compile-time state in same module - var gid {.compileTime.} = 3 - - macro genId(): int = - result = newIntLitNode(gid) - inc gid - - proc Id1(): int {.compileTime.} = return genId() - proc Id2(): int {.compileTime.} = return genId() - - doAssert Id1() == 3 - doAssert Id2() == 4 - - - -block tlexerex: - macro match(s: cstring|string; pos: int; sections: varargs[untyped]): untyped = - for sec in sections: - expectKind sec, nnkOfBranch - expectLen sec, 2 - result = newStmtList() - - var input = "the input" - var pos = 0 - match input, pos: - of r"[a-zA-Z_]\w+": echo "an identifier" - of r"\d+": echo "an integer" - of r".": echo "something else" - - - -block tlineinfo: - # issue #5617, feature request - type Test = object - - macro mixer(n: typed): untyped = - let x = newIdentNode("echo") - x.copyLineInfo(n) - result = newLit(x.lineInfo == n.lineInfo) - - var z = mixer(Test) - doAssert z - - - -block tdebugstmt: - macro debug(n: varargs[untyped]): untyped = - result = newNimNode(nnkStmtList, n) - for i in 0..n.len-1: - add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) - add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) - add(result, newCall("writeLine", newIdentNode("stdout"), n[i])) - - var - a: array[0..10, int] - x = "some string" - a[0] = 42 - a[1] = 45 - - debug(a[0], a[1], x) diff --git a/tests/metatype/tissues.nim b/tests/metatype/tissues.nim deleted file mode 100644 index 5c5380c9f..000000000 --- a/tests/metatype/tissues.nim +++ /dev/null @@ -1,150 +0,0 @@ - - -import typetraits, macros - - -block t898: - proc measureTime(e: auto) = - echo e.type.name - - proc generate(a: int): void = - discard - - proc runExample = - var builder: int = 0 - - measureTime: - builder.generate() - - measureTime: - discard - - - -block t7528: - macro bar(n: untyped): typed = - result = newNimNode(nnkStmtList, n) - result.add(newCall("write", newIdentNode("stdout"), n)) - - proc foo0[T](): auto = return (T.name, T.name) - bar foo0[string]() - echo "" - - - -block t5638: - type X = object - a_impl: int - - proc a(x: X): int = - x.a_impl - - var x: X - assert(not compiles((block: - x.a = 1 - ))) - - - -block t3706: - type Modulo[M: static[int]] = distinct int - proc modulo(a: int, M: static[int]): Modulo[M] = Modulo[M](a %% M) - proc `+`[M: static[int]](a, b: Modulo[M]): Modulo[M] = (a.int + b.int).modulo(M) - proc `$`[M: static[int]](a: Modulo[M]): string = $(a.int) & " mod " & $(M) - - let - a = 3.modulo(7) - b = 5.modulo(7) - echo a + b - - - -block t3144: - type IntArray[N: static[int]] = array[N, int] - - proc `$`(a: IntArray): string = $(@(a)) - - proc `+=`[N: static[int]](a: var IntArray[N], b: IntArray[N]) = - for i in 0 ..< N: - a[i] += b[i] - - proc zeros(N: static[int]): IntArray[N] = - for i in 0 ..< N: - result[i] = 0 - - proc ones(N: static[int]): IntArray[N] = - for i in 0 ..< N: - result[i] = 1 - - proc sum[N: static[int]](vs: seq[IntArray[N]]): IntArray[N] = - result = zeros(N) - for v in vs: - result += v - - echo sum(@[ones(5), ones(5)]) - - - -block t6533: - type Value[T: static[int]] = typedesc - proc foo(order: Value[1]): auto = 0 - doAssert foo(Value[1]) == 0 - - - -block t2266: - proc impl(op: static[int]) = echo "impl 1 called" - proc impl(op: static[int], init: int) = echo "impl 2 called" - - macro wrapper2: untyped = newCall(bindSym"impl", newLit(0), newLit(0)) - - wrapper2() # Code generation for this fails. - - - -block t602: - type - TTest = object - TTest2 = object - TFoo = TTest | TTest2 - - proc f(src: ptr TFoo, dst: ptr TFoo) = - echo("asd") - - var x: TTest - f(addr x, addr x) - - - -block t3338: - type - Base[T] = Foo[T] | Bar[T] - - Foo[T] = ref object - x: T - - Bar[T] = ref object - x: T - - proc test[T](ks: Foo[T], x, y: T): T = - echo("Foo") - return x + y + ks.x - - proc test[T](ks: Bar[T], x, y: T): T = - echo("Bar") - return x - - proc add[T](ksa: Base[T]) = - var test = ksa.test(5, 10) - ksa.x = test - - var t1 = Foo[int32]() - t1.add() - doAssert t1.x == 15 - - var t2 = Bar[int32]() - t2.add() - doAssert t2.x == 5 - - - diff --git a/tests/metatype/tmetatype_issues.nim b/tests/metatype/tmetatype_issues.nim new file mode 100644 index 000000000..5c5380c9f --- /dev/null +++ b/tests/metatype/tmetatype_issues.nim @@ -0,0 +1,150 @@ + + +import typetraits, macros + + +block t898: + proc measureTime(e: auto) = + echo e.type.name + + proc generate(a: int): void = + discard + + proc runExample = + var builder: int = 0 + + measureTime: + builder.generate() + + measureTime: + discard + + + +block t7528: + macro bar(n: untyped): typed = + result = newNimNode(nnkStmtList, n) + result.add(newCall("write", newIdentNode("stdout"), n)) + + proc foo0[T](): auto = return (T.name, T.name) + bar foo0[string]() + echo "" + + + +block t5638: + type X = object + a_impl: int + + proc a(x: X): int = + x.a_impl + + var x: X + assert(not compiles((block: + x.a = 1 + ))) + + + +block t3706: + type Modulo[M: static[int]] = distinct int + proc modulo(a: int, M: static[int]): Modulo[M] = Modulo[M](a %% M) + proc `+`[M: static[int]](a, b: Modulo[M]): Modulo[M] = (a.int + b.int).modulo(M) + proc `$`[M: static[int]](a: Modulo[M]): string = $(a.int) & " mod " & $(M) + + let + a = 3.modulo(7) + b = 5.modulo(7) + echo a + b + + + +block t3144: + type IntArray[N: static[int]] = array[N, int] + + proc `$`(a: IntArray): string = $(@(a)) + + proc `+=`[N: static[int]](a: var IntArray[N], b: IntArray[N]) = + for i in 0 ..< N: + a[i] += b[i] + + proc zeros(N: static[int]): IntArray[N] = + for i in 0 ..< N: + result[i] = 0 + + proc ones(N: static[int]): IntArray[N] = + for i in 0 ..< N: + result[i] = 1 + + proc sum[N: static[int]](vs: seq[IntArray[N]]): IntArray[N] = + result = zeros(N) + for v in vs: + result += v + + echo sum(@[ones(5), ones(5)]) + + + +block t6533: + type Value[T: static[int]] = typedesc + proc foo(order: Value[1]): auto = 0 + doAssert foo(Value[1]) == 0 + + + +block t2266: + proc impl(op: static[int]) = echo "impl 1 called" + proc impl(op: static[int], init: int) = echo "impl 2 called" + + macro wrapper2: untyped = newCall(bindSym"impl", newLit(0), newLit(0)) + + wrapper2() # Code generation for this fails. + + + +block t602: + type + TTest = object + TTest2 = object + TFoo = TTest | TTest2 + + proc f(src: ptr TFoo, dst: ptr TFoo) = + echo("asd") + + var x: TTest + f(addr x, addr x) + + + +block t3338: + type + Base[T] = Foo[T] | Bar[T] + + Foo[T] = ref object + x: T + + Bar[T] = ref object + x: T + + proc test[T](ks: Foo[T], x, y: T): T = + echo("Foo") + return x + y + ks.x + + proc test[T](ks: Bar[T], x, y: T): T = + echo("Bar") + return x + + proc add[T](ksa: Base[T]) = + var test = ksa.test(5, 10) + ksa.x = test + + var t1 = Foo[int32]() + t1.add() + doAssert t1.x == 15 + + var t2 = Bar[int32]() + t2.add() + doAssert t2.x == 5 + + + diff --git a/tests/metatype/tmetatype_various.nim b/tests/metatype/tmetatype_various.nim new file mode 100644 index 000000000..a56eca018 --- /dev/null +++ b/tests/metatype/tmetatype_various.nim @@ -0,0 +1,49 @@ + + +block tconstraints: + proc myGenericProc[T: object|tuple|int|ptr|ref|distinct](x: T): string = + result = $x + + type TMyObj = tuple[x, y: int] + + var x: TMyObj + + assert myGenericProc(232) == "232" + assert myGenericProc(x) == "(x: 0, y: 0)" + + + +block tfieldaccessor: + type + Test = object + x: int + case p: bool + of true: + a: int + else: + case q: bool + of true: + b: int + else: + discard + + proc f[T](t: typedesc[T]): int = + 1 + + assert Test.f == 1 + + + +block tprocbothmeta: + proc myFun[A](x: A): auto = + result = float(x+10) + + proc myMap[T,S](sIn: seq[T], f: proc (q: T): S): seq[S] = + result = newSeq[S](sIn.len) + for i in 0..= 3: - 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](x: X) = - echo "This has the lowest precedence." - - p(B()) - -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 - - - -# bug #2481 -import math - -template test(loopCount: int, extraI: int, testBody: untyped): typed = - block: - for i in 0..loopCount-1: - testBody - echo "done extraI=", extraI - -template test(loopCount: int, extraF: float, testBody: untyped): typed = - block: - test(loopCount, round(extraF).int, testBody) - -template test(loopCount: int, testBody: untyped): typed = - block: - test(loopCount, 0, testBody) - echo "done extraI passed 0" - -when isMainModule: - var - loops = 0 - - test 0, 0: - loops += 1 - echo "test 0 complete, loops=", loops - - test 1, 1.0: - loops += 1 - echo "test 1.0 complete, loops=", loops - - when true: - # when true we get the following compile time error: - # b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous) - loops = 0 - test 2: - loops += 1 - echo "test no extra complete, loops=", loops - - - - -# bug #2229 -type - Type1 = object - id: int - Type2 = object - id: int - -proc init(self: var Type1, a: int, b: ref Type2) = - echo "1" - -proc init(self: var Type2, a: int) = - echo """ - Works when this proc commented out - Otherwise error: - test.nim(14, 4) Error: ambiguous call; both test.init(self: var Type1, a: int, b: ref Type2) and test.init(self: var Type1, a: int, b: ref Type2) match for: (Type1, int literal(1), ref Type2) - """ - -var aa: Type1 -init(aa, 1, ( - var bb = new(Type2); - bb -)) - - - -# bug #4545 -type - SomeObject = object - a: int - AbstractObject = object - objet: ptr SomeObject - -proc convert(this: var SomeObject): AbstractObject = - AbstractObject(objet: this.addr) - -proc varargProc(args: varargs[AbstractObject, convert]): int = - for arg in args: - result += arg.objet.a - -var obj = SomeObject(a: 17) -discard varargProc(obj) diff --git a/tests/overload/toverload_issues.nim b/tests/overload/toverload_issues.nim new file mode 100644 index 000000000..7980f51a9 --- /dev/null +++ b/tests/overload/toverload_issues.nim @@ -0,0 +1,185 @@ +discard """ + output: ''' +Version 2 was called. +This has the highest precedence. +This has the second-highest precedence. +This has the lowest precedence. +baseobj == +true +even better! == +true +done extraI=0 +test 0 complete, loops=0 +done extraI=1 +test 1.0 complete, loops=1 +done extraI=0 +done extraI passed 0 +test no extra complete, loops=2 +1 +''' +""" + + +# issue 4675 +import importA # comment this out to make it work +import importB + +var x: Foo[float] +var y: Foo[float] +let r = t1(x) + t2(y) + + + +# Bug: https://github.com/nim-lang/Nim/issues/4475 +# Fix: https://github.com/nim-lang/Nim/pull/4477 +proc test(x: varargs[string], y: int) = discard +test(y = 1) + + + +# bug #2220 +when true: + type A[T] = object + type B = A[int] + + proc q[X](x: X) = + echo "Version 1 was called." + + proc q(x: B) = + echo "Version 2 was called." + + q(B()) # This call reported as ambiguous. + + + +# bug #2219 +template testPred(a: untyped) = + block: + type A = object of RootObj + type B = object of A + type SomeA = A|A # A hack to make "A" a typeclass. + + when a >= 3: + 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](x: X) = + echo "This has the lowest precedence." + + p(B()) + +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 + + + +# bug #2481 +import math + +template test(loopCount: int, extraI: int, testBody: untyped): typed = + block: + for i in 0..loopCount-1: + testBody + echo "done extraI=", extraI + +template test(loopCount: int, extraF: float, testBody: untyped): typed = + block: + test(loopCount, round(extraF).int, testBody) + +template test(loopCount: int, testBody: untyped): typed = + block: + test(loopCount, 0, testBody) + echo "done extraI passed 0" + +when isMainModule: + var + loops = 0 + + test 0, 0: + loops += 1 + echo "test 0 complete, loops=", loops + + test 1, 1.0: + loops += 1 + echo "test 1.0 complete, loops=", loops + + when true: + # when true we get the following compile time error: + # b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous) + loops = 0 + test 2: + loops += 1 + echo "test no extra complete, loops=", loops + + + + +# bug #2229 +type + Type1 = object + id: int + Type2 = object + id: int + +proc init(self: var Type1, a: int, b: ref Type2) = + echo "1" + +proc init(self: var Type2, a: int) = + echo """ + Works when this proc commented out + Otherwise error: + test.nim(14, 4) Error: ambiguous call; both test.init(self: var Type1, a: int, b: ref Type2) and test.init(self: var Type1, a: int, b: ref Type2) match for: (Type1, int literal(1), ref Type2) + """ + +var aa: Type1 +init(aa, 1, ( + var bb = new(Type2); + bb +)) + + + +# bug #4545 +type + SomeObject = object + a: int + AbstractObject = object + objet: ptr SomeObject + +proc convert(this: var SomeObject): AbstractObject = + AbstractObject(objet: this.addr) + +proc varargProc(args: varargs[AbstractObject, convert]): int = + for arg in args: + result += arg.objet.a + +var obj = SomeObject(a: 17) +discard varargProc(obj) diff --git a/tests/overload/toverload_various.nim b/tests/overload/toverload_various.nim new file mode 100644 index 000000000..4c17b6031 --- /dev/null +++ b/tests/overload/toverload_various.nim @@ -0,0 +1,176 @@ +discard """ + output: ''' +true012innertrue +m1 +tup1 +another number: 123 +yay +helloa 1 b 2 x @[3, 4, 5] y 6 z 7 +yay +12 +ref ref T ptr S +dynamic: let +dynamic: var +static: const +static: literal +static: constant folding +static: static string +''' +""" + + +import strutils, sequtils + + +block overl2: + # Test new overloading resolution rules + proc toverl2(x: int): string = return $x + proc toverl2(x: bool): string = return $x + + iterator toverl2(x: int): int = + var res = 0 + while res < x: + yield res + inc(res) + + var + pp: proc (x: bool): string {.nimcall.} = toverl2 + + stdout.write(pp(true)) + + for x in toverl2(3): + stdout.write(toverl2(x)) + + block: + proc toverl2(x: int): string = return "inner" + stdout.write(toverl2(5)) + stdout.write(true) + + stdout.write("\n") + #OUT true012innertrue + + + +block overl3: + # Tests more specific generic match: + proc m[T](x: T) = echo "m2" + proc m[T](x: var ref T) = echo "m1" + proc tup[S, T](x: tuple[a: S, b: ref T]) = echo "tup1" + proc tup[S, T](x: tuple[a: S, b: T]) = echo "tup2" + + var + obj: ref int + tu: tuple[a: int, b: ref bool] + + m(obj) + tup(tu) + + + +block toverprc: + # Test overloading of procs when used as function pointers + proc parseInt(x: float): int {.noSideEffect.} = discard + proc parseInt(x: bool): int {.noSideEffect.} = discard + proc parseInt(x: float32): int {.noSideEffect.} = discard + proc parseInt(x: int8): int {.noSideEffect.} = discard + proc parseInt(x: File): int {.noSideEffect.} = discard + proc parseInt(x: char): int {.noSideEffect.} = discard + proc parseInt(x: int16): int {.noSideEffect.} = discard + + proc parseInt[T](x: T): int = echo x; 34 + + type + TParseInt = proc (x: string): int {.noSideEffect.} + + var + q = TParseInt(parseInt) + p: TParseInt = parseInt + + proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = + result = x("123") + + if false: + echo "Give a list of numbers (separated by spaces): " + var x = stdin.readline.split.map(parseInt).max + echo x, " is the maximum!" + echo "another number: ", takeParseInt(parseInt) + + + type + TFoo[a,b] = object + lorem: a + ipsum: b + + proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum) + proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum) + + discard parseInt[string]("yay") + + + +block toverwr: + # Test the overloading resolution in connection with a qualifier + proc write(t: File, s: string) = + discard # a nop + system.write(stdout, "hello") + #OUT hello + + + +block tparams_after_varargs: + proc test(a, b: int, x: varargs[int]; y, z: int) = + echo "a ", a, " b ", b, " x ", @x, " y ", y, " z ", z + + test 1, 2, 3, 4, 5, 6, 7 + + # XXX maybe this should also work with ``varargs[untyped]`` + template takesBlockA(a, b: untyped; x: varargs[typed]; blck: untyped): untyped = + blck + echo a, b + + takesBlockA 1, 2, "some", 0.90, "random stuff": + echo "yay" + + + +block tprefer_specialized_generic: + proc foo[T](x: T) = + echo "only T" + + proc foo[T](x: ref T) = + echo "ref T" + + proc foo[T, S](x: ref ref T; y: ptr S) = + echo "ref ref T ptr S" + + proc foo[T, S](x: ref T; y: ptr S) = + echo "ref T ptr S" + + proc foo[T](x: ref T; default = 0) = + echo "ref T; default" + + var x: ref ref int + var y: ptr ptr int + foo(x, y) + + + +block tstaticoverload: + 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/overload/tvarious.nim b/tests/overload/tvarious.nim deleted file mode 100644 index 4c17b6031..000000000 --- a/tests/overload/tvarious.nim +++ /dev/null @@ -1,176 +0,0 @@ -discard """ - output: ''' -true012innertrue -m1 -tup1 -another number: 123 -yay -helloa 1 b 2 x @[3, 4, 5] y 6 z 7 -yay -12 -ref ref T ptr S -dynamic: let -dynamic: var -static: const -static: literal -static: constant folding -static: static string -''' -""" - - -import strutils, sequtils - - -block overl2: - # Test new overloading resolution rules - proc toverl2(x: int): string = return $x - proc toverl2(x: bool): string = return $x - - iterator toverl2(x: int): int = - var res = 0 - while res < x: - yield res - inc(res) - - var - pp: proc (x: bool): string {.nimcall.} = toverl2 - - stdout.write(pp(true)) - - for x in toverl2(3): - stdout.write(toverl2(x)) - - block: - proc toverl2(x: int): string = return "inner" - stdout.write(toverl2(5)) - stdout.write(true) - - stdout.write("\n") - #OUT true012innertrue - - - -block overl3: - # Tests more specific generic match: - proc m[T](x: T) = echo "m2" - proc m[T](x: var ref T) = echo "m1" - proc tup[S, T](x: tuple[a: S, b: ref T]) = echo "tup1" - proc tup[S, T](x: tuple[a: S, b: T]) = echo "tup2" - - var - obj: ref int - tu: tuple[a: int, b: ref bool] - - m(obj) - tup(tu) - - - -block toverprc: - # Test overloading of procs when used as function pointers - proc parseInt(x: float): int {.noSideEffect.} = discard - proc parseInt(x: bool): int {.noSideEffect.} = discard - proc parseInt(x: float32): int {.noSideEffect.} = discard - proc parseInt(x: int8): int {.noSideEffect.} = discard - proc parseInt(x: File): int {.noSideEffect.} = discard - proc parseInt(x: char): int {.noSideEffect.} = discard - proc parseInt(x: int16): int {.noSideEffect.} = discard - - proc parseInt[T](x: T): int = echo x; 34 - - type - TParseInt = proc (x: string): int {.noSideEffect.} - - var - q = TParseInt(parseInt) - p: TParseInt = parseInt - - proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = - result = x("123") - - if false: - echo "Give a list of numbers (separated by spaces): " - var x = stdin.readline.split.map(parseInt).max - echo x, " is the maximum!" - echo "another number: ", takeParseInt(parseInt) - - - type - TFoo[a,b] = object - lorem: a - ipsum: b - - proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum) - proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum) - - discard parseInt[string]("yay") - - - -block toverwr: - # Test the overloading resolution in connection with a qualifier - proc write(t: File, s: string) = - discard # a nop - system.write(stdout, "hello") - #OUT hello - - - -block tparams_after_varargs: - proc test(a, b: int, x: varargs[int]; y, z: int) = - echo "a ", a, " b ", b, " x ", @x, " y ", y, " z ", z - - test 1, 2, 3, 4, 5, 6, 7 - - # XXX maybe this should also work with ``varargs[untyped]`` - template takesBlockA(a, b: untyped; x: varargs[typed]; blck: untyped): untyped = - blck - echo a, b - - takesBlockA 1, 2, "some", 0.90, "random stuff": - echo "yay" - - - -block tprefer_specialized_generic: - proc foo[T](x: T) = - echo "only T" - - proc foo[T](x: ref T) = - echo "ref T" - - proc foo[T, S](x: ref ref T; y: ptr S) = - echo "ref ref T ptr S" - - proc foo[T, S](x: ref T; y: ptr S) = - echo "ref T ptr S" - - proc foo[T](x: ref T; default = 0) = - echo "ref T; default" - - var x: ref ref int - var y: ptr ptr int - foo(x, y) - - - -block tstaticoverload: - 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/sets/tsets_various.nim b/tests/sets/tsets_various.nim new file mode 100644 index 000000000..7cb9a6eec --- /dev/null +++ b/tests/sets/tsets_various.nim @@ -0,0 +1,200 @@ +discard """ + output: ''' +set is empty +''' +""" + + +import sets, hashes + + +block tsetpop: + var a = initSet[int]() + for i in 1..1000: + a.incl(i) + doAssert len(a) == 1000 + for i in 1..1000: + discard a.pop() + doAssert len(a) == 0 + + try: + echo a.pop() + except KeyError as e: + echo e.msg + + + +block tsets_lt: + var s, s1: set[char] + s = {'a'..'d'} + s1 = {'a'..'c'} + doAssert s1 < s + doAssert s1 * s == {'a'..'c'} + doAssert s1 <= s + + + +block tsets2: + const + data = [ + "34", "12", + "90", "0", + "1", "2", + "3", "4", + "5", "6", + "7", "8", + "9", "---00", + "10", "11", "19", + "20", "30", "40", + "50", "60", "70", + "80"] + + block tableTest1: + var t = initSet[tuple[x, y: int]]() + t.incl((0,0)) + t.incl((1,0)) + assert(not t.containsOrIncl((0,1))) + t.incl((1,1)) + + for x in 0..1: + for y in 0..1: + assert((x,y) in t) + #assert($t == + # "{(x: 0, y: 0), (x: 0, y: 1), (x: 1, y: 0), (x: 1, y: 1)}") + + block setTest2: + var t = initSet[string]() + t.incl("test") + t.incl("111") + t.incl("123") + t.excl("111") + t.incl("012") + t.incl("123") # test duplicates + + assert "123" in t + assert "111" notin t # deleted + + assert t.missingOrExcl("000") + assert "000" notin t + assert t.missingOrExcl("012") == false + assert "012" notin t + + assert t.containsOrIncl("012") == false + assert t.containsOrIncl("012") + assert "012" in t # added back + + for key in items(data): t.incl(key) + for key in items(data): assert key in t + + for key in items(data): t.excl(key) + for key in items(data): assert key notin t + + block orderedSetTest1: + var t = data.toOrderedSet + for key in items(data): assert key in t + var i = 0 + # `items` needs to yield in insertion order: + for key in items(t): + assert key == data[i] + inc(i) + + + +block tsets3: + let + s1: TSet[int] = toSet([1, 2, 4, 8, 16]) + s2: TSet[int] = toSet([1, 2, 3, 5, 8]) + s3: TSet[int] = toSet([3, 5, 7]) + + block union: + let + s1_s2 = union(s1, s2) + s1_s3 = s1 + s3 + s2_s3 = s2 + s3 + + assert s1_s2.len == 7 + assert s1_s3.len == 8 + assert s2_s3.len == 6 + + for i in s1: + assert i in s1_s2 + assert i in s1_s3 + for i in s2: + assert i in s1_s2 + assert i in s2_s3 + for i in s3: + assert i in s1_s3 + assert i in s2_s3 + + assert((s1 + s1) == s1) + assert((s2 + s1) == s1_s2) + + block intersection: + let + s1_s2 = intersection(s1, s2) + s1_s3 = intersection(s1, s3) + s2_s3 = s2 * s3 + + assert s1_s2.len == 3 + assert s1_s3.len == 0 + assert s2_s3.len == 2 + + for i in s1_s2: + assert i in s1 + assert i in s2 + for i in s1_s3: + assert i in s1 + assert i in s3 + for i in s2_s3: + assert i in s2 + assert i in s3 + + assert((s2 * s2) == s2) + assert((s3 * s2) == s2_s3) + + block symmetricDifference: + let + s1_s2 = symmetricDifference(s1, s2) + s1_s3 = s1 -+- s3 + s2_s3 = s2 -+- s3 + + assert s1_s2.len == 4 + assert s1_s3.len == 8 + assert s2_s3.len == 4 + + for i in s1: + assert i in s1_s2 xor i in s2 + assert i in s1_s3 xor i in s3 + for i in s2: + assert i in s1_s2 xor i in s1 + assert i in s2_s3 xor i in s3 + for i in s3: + assert i in s1_s3 xor i in s1 + assert i in s2_s3 xor i in s2 + + assert((s3 -+- s3) == initSet[int]()) + assert((s3 -+- s1) == s1_s3) + + block difference: + let + s1_s2 = difference(s1, s2) + s1_s3 = difference(s1, s3) + s2_s3 = s2 - s3 + + assert s1_s2.len == 2 + assert s1_s3.len == 5 + assert s2_s3.len == 3 + + for i in s1: + assert i in s1_s2 xor i in s2 + assert i in s1_s3 xor i in s3 + for i in s2: + assert i in s2_s3 xor i in s3 + + assert((s2 - s2) == initSet[int]()) + + block disjoint: + assert(not disjoint(s1, s2)) + assert disjoint(s1, s3) + assert(not disjoint(s2, s3)) + assert(not disjoint(s2, s2)) diff --git a/tests/sets/tvarious.nim b/tests/sets/tvarious.nim deleted file mode 100644 index 7cb9a6eec..000000000 --- a/tests/sets/tvarious.nim +++ /dev/null @@ -1,200 +0,0 @@ -discard """ - output: ''' -set is empty -''' -""" - - -import sets, hashes - - -block tsetpop: - var a = initSet[int]() - for i in 1..1000: - a.incl(i) - doAssert len(a) == 1000 - for i in 1..1000: - discard a.pop() - doAssert len(a) == 0 - - try: - echo a.pop() - except KeyError as e: - echo e.msg - - - -block tsets_lt: - var s, s1: set[char] - s = {'a'..'d'} - s1 = {'a'..'c'} - doAssert s1 < s - doAssert s1 * s == {'a'..'c'} - doAssert s1 <= s - - - -block tsets2: - const - data = [ - "34", "12", - "90", "0", - "1", "2", - "3", "4", - "5", "6", - "7", "8", - "9", "---00", - "10", "11", "19", - "20", "30", "40", - "50", "60", "70", - "80"] - - block tableTest1: - var t = initSet[tuple[x, y: int]]() - t.incl((0,0)) - t.incl((1,0)) - assert(not t.containsOrIncl((0,1))) - t.incl((1,1)) - - for x in 0..1: - for y in 0..1: - assert((x,y) in t) - #assert($t == - # "{(x: 0, y: 0), (x: 0, y: 1), (x: 1, y: 0), (x: 1, y: 1)}") - - block setTest2: - var t = initSet[string]() - t.incl("test") - t.incl("111") - t.incl("123") - t.excl("111") - t.incl("012") - t.incl("123") # test duplicates - - assert "123" in t - assert "111" notin t # deleted - - assert t.missingOrExcl("000") - assert "000" notin t - assert t.missingOrExcl("012") == false - assert "012" notin t - - assert t.containsOrIncl("012") == false - assert t.containsOrIncl("012") - assert "012" in t # added back - - for key in items(data): t.incl(key) - for key in items(data): assert key in t - - for key in items(data): t.excl(key) - for key in items(data): assert key notin t - - block orderedSetTest1: - var t = data.toOrderedSet - for key in items(data): assert key in t - var i = 0 - # `items` needs to yield in insertion order: - for key in items(t): - assert key == data[i] - inc(i) - - - -block tsets3: - let - s1: TSet[int] = toSet([1, 2, 4, 8, 16]) - s2: TSet[int] = toSet([1, 2, 3, 5, 8]) - s3: TSet[int] = toSet([3, 5, 7]) - - block union: - let - s1_s2 = union(s1, s2) - s1_s3 = s1 + s3 - s2_s3 = s2 + s3 - - assert s1_s2.len == 7 - assert s1_s3.len == 8 - assert s2_s3.len == 6 - - for i in s1: - assert i in s1_s2 - assert i in s1_s3 - for i in s2: - assert i in s1_s2 - assert i in s2_s3 - for i in s3: - assert i in s1_s3 - assert i in s2_s3 - - assert((s1 + s1) == s1) - assert((s2 + s1) == s1_s2) - - block intersection: - let - s1_s2 = intersection(s1, s2) - s1_s3 = intersection(s1, s3) - s2_s3 = s2 * s3 - - assert s1_s2.len == 3 - assert s1_s3.len == 0 - assert s2_s3.len == 2 - - for i in s1_s2: - assert i in s1 - assert i in s2 - for i in s1_s3: - assert i in s1 - assert i in s3 - for i in s2_s3: - assert i in s2 - assert i in s3 - - assert((s2 * s2) == s2) - assert((s3 * s2) == s2_s3) - - block symmetricDifference: - let - s1_s2 = symmetricDifference(s1, s2) - s1_s3 = s1 -+- s3 - s2_s3 = s2 -+- s3 - - assert s1_s2.len == 4 - assert s1_s3.len == 8 - assert s2_s3.len == 4 - - for i in s1: - assert i in s1_s2 xor i in s2 - assert i in s1_s3 xor i in s3 - for i in s2: - assert i in s1_s2 xor i in s1 - assert i in s2_s3 xor i in s3 - for i in s3: - assert i in s1_s3 xor i in s1 - assert i in s2_s3 xor i in s2 - - assert((s3 -+- s3) == initSet[int]()) - assert((s3 -+- s1) == s1_s3) - - block difference: - let - s1_s2 = difference(s1, s2) - s1_s3 = difference(s1, s3) - s2_s3 = s2 - s3 - - assert s1_s2.len == 2 - assert s1_s3.len == 5 - assert s2_s3.len == 3 - - for i in s1: - assert i in s1_s2 xor i in s2 - assert i in s1_s3 xor i in s3 - for i in s2: - assert i in s2_s3 xor i in s3 - - assert((s2 - s2) == initSet[int]()) - - block disjoint: - assert(not disjoint(s1, s2)) - assert disjoint(s1, s3) - assert(not disjoint(s2, s3)) - assert(not disjoint(s2, s2)) diff --git a/tests/stdlib/tissues.nim b/tests/stdlib/tissues.nim deleted file mode 100644 index b5a1c8206..000000000 --- a/tests/stdlib/tissues.nim +++ /dev/null @@ -1,109 +0,0 @@ -discard """ -output: ''' -02 -1 -2 -3 -4 -5 -9 -b = true -123456789 -Second readLine raised an exception -123456789 -1 -2aaaaaaaa -3bbbbbbb -''' -""" - -import terminal, colors, re, encodings, strutils, os - - -block t9394: - let codeFg = ansiForegroundColorCode(colAliceBlue) - let codeBg = ansiBackgroundColorCode(colAliceBlue) - - doAssert codeFg == "\27[38;2;240;248;255m" - doAssert codeBg == "\27[48;2;240;248;255m" - - - -block t5382: - let regexp = re"^\/([0-9]{2})\.html$" - var matches: array[1, string] - discard "/02.html".find(regexp, matches) - echo matches[0] - - - -block tcount: - # bug #1845, #2224 - var arr = [3,2,1,5,4] - - # bubble sort - for i in low(arr)..high(arr): - for j in i+1..high(arr): # Error: unhandled exception: value out of range: 5 [RangeError] - if arr[i] > arr[j]: - let tmp = arr[i] - arr[i] = arr[j] - arr[j] = tmp - - for i in low(arr)..high(arr): - echo arr[i] - - # check this terminates: - for x in countdown('\255', '\0'): - discard - - - -block t8468: - when defined(windows): - var utf16to8 = open(destEncoding = "utf-16", srcEncoding = "utf-8") - var s = "some string" - var c = utf16to8.convert(s) - - var z = newStringOfCap(s.len * 2) - for x in s: - z.add x - z.add chr(0) - - doAssert z == c - - - -block t5349: - const fn = "file9char.txt" - writeFile(fn, "123456789") - - var f = system.open(fn) - echo getFileSize(f) - - var line = newString(10) - try: - let b = readLine(f, line) - echo "b = ", b - except: - echo "First readLine raised an exception" - echo line - - try: - line = readLine(f) - let b = readLine(f, line) - echo "b = ", b - except: - echo "Second readLine raised an exception" - echo line - f.close() - - removeFile(fn) - # bug #8961 - writeFile("test.txt", "1\C\L2aaaaaaaa\C\L3bbbbbbb") - - for line in lines("test.txt"): - echo line - -block t9456: - var f: File - f.close() diff --git a/tests/stdlib/tstdlib_issues.nim b/tests/stdlib/tstdlib_issues.nim new file mode 100644 index 000000000..b5a1c8206 --- /dev/null +++ b/tests/stdlib/tstdlib_issues.nim @@ -0,0 +1,109 @@ +discard """ +output: ''' +02 +1 +2 +3 +4 +5 +9 +b = true +123456789 +Second readLine raised an exception +123456789 +1 +2aaaaaaaa +3bbbbbbb +''' +""" + +import terminal, colors, re, encodings, strutils, os + + +block t9394: + let codeFg = ansiForegroundColorCode(colAliceBlue) + let codeBg = ansiBackgroundColorCode(colAliceBlue) + + doAssert codeFg == "\27[38;2;240;248;255m" + doAssert codeBg == "\27[48;2;240;248;255m" + + + +block t5382: + let regexp = re"^\/([0-9]{2})\.html$" + var matches: array[1, string] + discard "/02.html".find(regexp, matches) + echo matches[0] + + + +block tcount: + # bug #1845, #2224 + var arr = [3,2,1,5,4] + + # bubble sort + for i in low(arr)..high(arr): + for j in i+1..high(arr): # Error: unhandled exception: value out of range: 5 [RangeError] + if arr[i] > arr[j]: + let tmp = arr[i] + arr[i] = arr[j] + arr[j] = tmp + + for i in low(arr)..high(arr): + echo arr[i] + + # check this terminates: + for x in countdown('\255', '\0'): + discard + + + +block t8468: + when defined(windows): + var utf16to8 = open(destEncoding = "utf-16", srcEncoding = "utf-8") + var s = "some string" + var c = utf16to8.convert(s) + + var z = newStringOfCap(s.len * 2) + for x in s: + z.add x + z.add chr(0) + + doAssert z == c + + + +block t5349: + const fn = "file9char.txt" + writeFile(fn, "123456789") + + var f = system.open(fn) + echo getFileSize(f) + + var line = newString(10) + try: + let b = readLine(f, line) + echo "b = ", b + except: + echo "First readLine raised an exception" + echo line + + try: + line = readLine(f) + let b = readLine(f, line) + echo "b = ", b + except: + echo "Second readLine raised an exception" + echo line + f.close() + + removeFile(fn) + # bug #8961 + writeFile("test.txt", "1\C\L2aaaaaaaa\C\L3bbbbbbb") + + for line in lines("test.txt"): + echo line + +block t9456: + var f: File + f.close() diff --git a/tests/stdlib/tstdlib_various.nim b/tests/stdlib/tstdlib_various.nim new file mode 100644 index 000000000..7abc9a391 --- /dev/null +++ b/tests/stdlib/tstdlib_various.nim @@ -0,0 +1,247 @@ +discard """ +output: ''' +abc +def +definition +prefix +xyz +def +definition +Hi Andreas! How do you feel, Rumpf? + +@[0, 2, 1] +@[1, 0, 2] +@[1, 2, 0] +@[2, 0, 1] +@[2, 1, 0] +@[2, 0, 1] +@[1, 2, 0] +@[1, 0, 2] +@[0, 2, 1] +@[0, 1, 2] +055this should be the casehugh@["(", "+", " 1", " 2", ")"] +caught a crash! +caught a crash! +caught a crash! +caught a crash! +caught a crash! +caught a crash! +[5] +[4, 5] +[3, 4, 5] +[2, 3, 4, 5] +[2, 3, 4, 5, 6] +[1, 2, 3, 4, 5, 6] +true +

Nim

+''' +""" + +import + critbits, sets, strutils, tables, random, algorithm, re, ropes, segfaults, + lists, parsesql, streams, os, htmlgen, xmltree, strtabs + + +block tcritbits: + var r: CritBitTree[void] + r.incl "abc" + r.incl "xyz" + r.incl "def" + r.incl "definition" + r.incl "prefix" + doAssert r.contains"def" + #r.del "def" + + for w in r.items: + echo w + for w in r.itemsWithPrefix("de"): + echo w + + + +block testequivalence: + doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "equivalent or subset") + doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3]), "equivalent or subset") + doAssert((not(toSet(@[1,2,3]) <= toSet(@[1,2]))), "equivalent or subset") + doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "strict subset") + doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2,3]))), "strict subset") + doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2]))), "strict subset") + doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2,3,4]))), "==") + doAssert(toSet(@[1,2,3]) == toSet(@[1,2,3]), "==") + doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2]))), "==") + + + +block tformat: + echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"]) + + + +block tnilecho: + var x = @["1", "", "3"] + doAssert $x == """@["1", "", "3"]""" + + + +block torderedtable: + var t = initOrderedTable[int,string]() + + # this tests issue #5917 + var data = newSeq[int]() + for i in 0..<1000: + var x = rand(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) + + + +block tpermutations: + var v = @[0, 1, 2] + while v.nextPermutation(): + echo v + while v.prevPermutation(): + echo v + + + +block treguse: + proc main(a, b: int) = + var x = 0 + write(stdout, x) + if x == 0: + var y = 55 + write(stdout, y) + write(stdout, "this should be the case") + var input = "" + if input == "Andreas": + write(stdout, "wow") + else: + write(stdout, "hugh") + else: + var z = 66 + write(stdout, z) # "bug!") + + main(45, 1000) + + + +block treloop: + let str = "(+ 1 2)" + var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)""" + echo str.findAll(tokenRE) + + + +block tropes: + var + r1 = rope("") + r2 = rope("123") + doAssert r1.len == 0 + doAssert r2.len == 3 + doAssert $r1 == "" + doAssert $r2 == "123" + + r1.add("123") + r2.add("456") + doAssert r1.len == 3 + doAssert r2.len == 6 + doAssert $r1 == "123" + doAssert $r2 == "123456" + doAssert $r1[1] == "2" + doAssert $r2[2] == "3" + + + +block tsegfaults: + proc main = + try: + var x: ptr int + echo x[] + try: + raise newException(ValueError, "not a crash") + except ValueError: + discard + except NilAccessError: + echo "caught a crash!" + for i in 0..5: + main() + + + +block tsinglylinkedring: + var r = initSinglyLinkedRing[int]() + r.prepend(5) + echo r + r.prepend(4) + echo r + r.prepend(3) + echo r + r.prepend(2) + echo r + r.append(6) + echo r + r.prepend(1) + echo r + + + +block tsplit: + var s = "" + for w in split("|abc|xy|z", {'|'}): + s.add("#") + s.add(w) + + doAssert s == "##abc#xy#z" + + + +block tsplit2: + var s = "" + for w in split("|abc|xy|z", {'|'}): + s.add("#") + s.add(w) + + try: + discard "hello".split("") + echo "false" + except AssertionError: + echo "true" + + + +block tsqlparser: + # Just check that we can parse 'somesql' and render it without crashes. + var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") + discard renderSql(tree) + + + +block txmlgen: + var nim = "Nim" + echo h1(a(href="http://force7.de/nim", nim)) + + + +block txmltree: + var x = <>a(href="nim.de", newText("www.nim-test.de")) + + doAssert($x == "www.nim-test.de") + doAssert(newText("foo").innerText == "foo") + doAssert(newEntity("bar").innerText == "bar") + doAssert(newComment("baz").innerText == "") + + let y = newXmlTree("x", [ + newText("foo"), + newXmlTree("y", [ + newText("bar") + ]) + ]) + doAssert(y.innerText == "foobar") diff --git a/tests/stdlib/tvarious.nim b/tests/stdlib/tvarious.nim deleted file mode 100644 index 7abc9a391..000000000 --- a/tests/stdlib/tvarious.nim +++ /dev/null @@ -1,247 +0,0 @@ -discard """ -output: ''' -abc -def -definition -prefix -xyz -def -definition -Hi Andreas! How do you feel, Rumpf? - -@[0, 2, 1] -@[1, 0, 2] -@[1, 2, 0] -@[2, 0, 1] -@[2, 1, 0] -@[2, 0, 1] -@[1, 2, 0] -@[1, 0, 2] -@[0, 2, 1] -@[0, 1, 2] -055this should be the casehugh@["(", "+", " 1", " 2", ")"] -caught a crash! -caught a crash! -caught a crash! -caught a crash! -caught a crash! -caught a crash! -[5] -[4, 5] -[3, 4, 5] -[2, 3, 4, 5] -[2, 3, 4, 5, 6] -[1, 2, 3, 4, 5, 6] -true -

Nim

-''' -""" - -import - critbits, sets, strutils, tables, random, algorithm, re, ropes, segfaults, - lists, parsesql, streams, os, htmlgen, xmltree, strtabs - - -block tcritbits: - var r: CritBitTree[void] - r.incl "abc" - r.incl "xyz" - r.incl "def" - r.incl "definition" - r.incl "prefix" - doAssert r.contains"def" - #r.del "def" - - for w in r.items: - echo w - for w in r.itemsWithPrefix("de"): - echo w - - - -block testequivalence: - doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "equivalent or subset") - doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3]), "equivalent or subset") - doAssert((not(toSet(@[1,2,3]) <= toSet(@[1,2]))), "equivalent or subset") - doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "strict subset") - doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2,3]))), "strict subset") - doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2]))), "strict subset") - doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2,3,4]))), "==") - doAssert(toSet(@[1,2,3]) == toSet(@[1,2,3]), "==") - doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2]))), "==") - - - -block tformat: - echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"]) - - - -block tnilecho: - var x = @["1", "", "3"] - doAssert $x == """@["1", "", "3"]""" - - - -block torderedtable: - var t = initOrderedTable[int,string]() - - # this tests issue #5917 - var data = newSeq[int]() - for i in 0..<1000: - var x = rand(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) - - - -block tpermutations: - var v = @[0, 1, 2] - while v.nextPermutation(): - echo v - while v.prevPermutation(): - echo v - - - -block treguse: - proc main(a, b: int) = - var x = 0 - write(stdout, x) - if x == 0: - var y = 55 - write(stdout, y) - write(stdout, "this should be the case") - var input = "" - if input == "Andreas": - write(stdout, "wow") - else: - write(stdout, "hugh") - else: - var z = 66 - write(stdout, z) # "bug!") - - main(45, 1000) - - - -block treloop: - let str = "(+ 1 2)" - var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)""" - echo str.findAll(tokenRE) - - - -block tropes: - var - r1 = rope("") - r2 = rope("123") - doAssert r1.len == 0 - doAssert r2.len == 3 - doAssert $r1 == "" - doAssert $r2 == "123" - - r1.add("123") - r2.add("456") - doAssert r1.len == 3 - doAssert r2.len == 6 - doAssert $r1 == "123" - doAssert $r2 == "123456" - doAssert $r1[1] == "2" - doAssert $r2[2] == "3" - - - -block tsegfaults: - proc main = - try: - var x: ptr int - echo x[] - try: - raise newException(ValueError, "not a crash") - except ValueError: - discard - except NilAccessError: - echo "caught a crash!" - for i in 0..5: - main() - - - -block tsinglylinkedring: - var r = initSinglyLinkedRing[int]() - r.prepend(5) - echo r - r.prepend(4) - echo r - r.prepend(3) - echo r - r.prepend(2) - echo r - r.append(6) - echo r - r.prepend(1) - echo r - - - -block tsplit: - var s = "" - for w in split("|abc|xy|z", {'|'}): - s.add("#") - s.add(w) - - doAssert s == "##abc#xy#z" - - - -block tsplit2: - var s = "" - for w in split("|abc|xy|z", {'|'}): - s.add("#") - s.add(w) - - try: - discard "hello".split("") - echo "false" - except AssertionError: - echo "true" - - - -block tsqlparser: - # Just check that we can parse 'somesql' and render it without crashes. - var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") - discard renderSql(tree) - - - -block txmlgen: - var nim = "Nim" - echo h1(a(href="http://force7.de/nim", nim)) - - - -block txmltree: - var x = <>a(href="nim.de", newText("www.nim-test.de")) - - doAssert($x == "www.nim-test.de") - doAssert(newText("foo").innerText == "foo") - doAssert(newEntity("bar").innerText == "bar") - doAssert(newComment("baz").innerText == "") - - let y = newXmlTree("x", [ - newText("foo"), - newXmlTree("y", [ - newText("bar") - ]) - ]) - doAssert(y.innerText == "foobar") -- cgit 1.4.1-2-gfad0