new tester; all tests categorized
This commit is contained in:
parent
51ee524109
commit
20b5f31c03
481 changed files with 794 additions and 2506 deletions
91
tests/metatype/tbindtypedesc.nim
Normal file
91
tests/metatype/tbindtypedesc.nim
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
discard """
|
||||
msg: '''
|
||||
int
|
||||
float
|
||||
TFoo
|
||||
TFoo
|
||||
'''
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
TFoo = object
|
||||
x, y: int
|
||||
|
||||
TBar = tuple
|
||||
x, y: int
|
||||
|
||||
template accept(e: expr) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template reject(e: expr) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
proc genericParamRepeated[T: typedesc](a: T, b: T) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
accept genericParamRepeated(int, int)
|
||||
accept genericParamRepeated(float, float)
|
||||
|
||||
reject genericParamRepeated(string, int)
|
||||
reject genericParamRepeated(int, float)
|
||||
|
||||
proc genericParamOnce[T: typedesc](a, b: T) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
accept genericParamOnce(int, int)
|
||||
accept genericParamOnce(TFoo, TFoo)
|
||||
|
||||
reject genericParamOnce(string, int)
|
||||
reject genericParamOnce(TFoo, float)
|
||||
|
||||
type
|
||||
type1 = typedesc
|
||||
type2 = typedesc
|
||||
|
||||
proc typePairs(A, B: type1; C, D: type2) = nil
|
||||
|
||||
accept typePairs(int, int, TFoo, TFOO)
|
||||
accept typePairs(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs(int, int, string, string)
|
||||
|
||||
reject typePairs(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs(string, int, TBAR, TBAR)
|
||||
|
||||
proc typePairs2[T: typedesc, U: typedesc](A, B: T; C, D: U) = nil
|
||||
|
||||
accept typePairs2(int, int, TFoo, TFOO)
|
||||
accept typePairs2(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs2(int, int, string, string)
|
||||
|
||||
reject typePairs2(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs2(string, int, TBAR, TBAR)
|
||||
|
||||
proc dontBind(a: typedesc, b: typedesc) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
accept dontBind(int, float)
|
||||
accept dontBind(TFoo, TFoo)
|
||||
|
||||
proc dontBind2(a, b: typedesc) = nil
|
||||
|
||||
accept dontBind2(int, float)
|
||||
accept dontBind2(TBar, int)
|
||||
|
||||
proc bindArg(T: typedesc, U: typedesc, a, b: T, c, d: U) = nil
|
||||
|
||||
accept bindArg(int, string, 10, 20, "test", "nest")
|
||||
accept bindArg(int, int, 10, 20, 30, 40)
|
||||
|
||||
reject bindArg(int, string, 10, "test", "test", "nest")
|
||||
reject bindArg(int, int, 10, 20, 30, "test")
|
||||
reject bindArg(int, string, 10.0, 20, "test", "nest")
|
||||
reject bindArg(int, string, "test", "nest", 10, 20)
|
||||
|
||||
59
tests/metatype/tcompositetypeclasses.nim
Normal file
59
tests/metatype/tcompositetypeclasses.nim
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
template accept(e) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template reject(e) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
type
|
||||
TFoo[T, U] = tuple
|
||||
x: T
|
||||
y: U
|
||||
|
||||
TBar[K] = TFoo[K, K]
|
||||
|
||||
TUserClass = int|string
|
||||
|
||||
TBaz = TBar[TUserClass]
|
||||
|
||||
var
|
||||
vfoo: TFoo[int, string]
|
||||
vbar: TFoo[string, string]
|
||||
vbaz: TFoo[int, int]
|
||||
vnotbaz: TFoo[TObject, TObject]
|
||||
|
||||
proc foo(x: TFoo) = echo "foo"
|
||||
proc bar(x: TBar) = echo "bar"
|
||||
proc baz(x: TBaz) = echo "baz"
|
||||
|
||||
accept foo(vfoo)
|
||||
accept bar(vbar)
|
||||
accept baz(vbar)
|
||||
accept baz(vbaz)
|
||||
|
||||
reject baz(vnotbaz)
|
||||
reject bar(vfoo)
|
||||
|
||||
# https://github.com/Araq/Nimrod/issues/517
|
||||
type
|
||||
TVecT*[T] = array[0..1, T]|array[0..2, T]|array[0..3, T]
|
||||
TVec2* = array[0..1, float32]
|
||||
|
||||
proc f[T](a: TVecT[T], b: TVecT[T]): T = discard
|
||||
|
||||
var x: float = f([0.0'f32, 0.0'f32], [0.0'f32, 0.0'f32])
|
||||
var y = f(TVec2([0.0'f32, 0.0'f32]), TVec2([0.0'f32, 0.0'f32]))
|
||||
|
||||
# https://github.com/Araq/Nimrod/issues/602
|
||||
type
|
||||
TTest = object
|
||||
TTest2* = object
|
||||
TUnion = TTest | TTest2
|
||||
|
||||
proc f(src: ptr TUnion, dst: ptr TUnion) =
|
||||
echo("asd")
|
||||
|
||||
var tx: TTest
|
||||
var ty: TTest2
|
||||
|
||||
accept f(addr tx, addr tx)
|
||||
reject f(addr tx, addr ty)
|
||||
15
tests/metatype/tconstraints.nim
Normal file
15
tests/metatype/tconstraints.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
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)"
|
||||
|
||||
|
||||
24
tests/metatype/tsemistatic.nim
Normal file
24
tests/metatype/tsemistatic.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
discard """
|
||||
msg: "static 10\ndynamic\nstatic 20\n"
|
||||
output: "s\nd\nd\ns"
|
||||
"""
|
||||
|
||||
proc foo(x: semistatic[int]) =
|
||||
when isStatic(x):
|
||||
static: echo "static ", x
|
||||
echo "s"
|
||||
else:
|
||||
static: echo "dynamic"
|
||||
echo "d"
|
||||
|
||||
foo 10
|
||||
|
||||
var
|
||||
x = 10
|
||||
y: int
|
||||
|
||||
foo x
|
||||
foo y
|
||||
|
||||
foo 20
|
||||
|
||||
14
tests/metatype/ttypebar.nim
Normal file
14
tests/metatype/ttypebar.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
# bug #602
|
||||
|
||||
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)
|
||||
|
||||
55
tests/metatype/ttypeclasses.nim
Normal file
55
tests/metatype/ttypeclasses.nim
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
type
|
||||
TFoo[T] = object
|
||||
val: T
|
||||
|
||||
T1 = expr
|
||||
T2 = expr
|
||||
|
||||
Numeric = int|float
|
||||
|
||||
proc takesExpr(x, y) =
|
||||
echo x, y
|
||||
|
||||
proc same(x, y: T1) =
|
||||
echo x, y
|
||||
|
||||
proc takesFoo(x, y: TFoo) =
|
||||
echo x.val, y.val
|
||||
|
||||
proc takes2Types(x,y: T1, z: T2) =
|
||||
echo x, y, z
|
||||
|
||||
takesExpr(1, 2)
|
||||
takesExpr(1, "xxx")
|
||||
takesExpr[bool, int](true, 0)
|
||||
|
||||
same(1, 2)
|
||||
same("test", "test")
|
||||
|
||||
var f: TFoo[int]
|
||||
f.val = 10
|
||||
|
||||
takesFoo(f, f)
|
||||
|
||||
takes2Types(1, 1, "string")
|
||||
takes2Types[string, int]("test", "test", 1)
|
||||
|
||||
proc takesSeq(x: seq) =
|
||||
echo "seq"
|
||||
|
||||
takesSeq(@[1, 2, 3])
|
||||
takesSeq(@["x", "y", "z"])
|
||||
|
||||
proc takesSeqOfFoos(x: seq[TFoo]) =
|
||||
echo "foo seq"
|
||||
|
||||
var sf = newSeq[TFoo[int]](3)
|
||||
|
||||
takesSeq(sf)
|
||||
takesSeqOfFoos(sf)
|
||||
|
||||
proc takesFooOfNumeric(x: TFoo[Numeric]) =
|
||||
echo "foo of numeric"
|
||||
|
||||
takesFooOfNumeric(sf[0])
|
||||
|
||||
42
tests/metatype/ttypedesc1.nim
Normal file
42
tests/metatype/ttypedesc1.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import unittest, typetraits
|
||||
|
||||
type
|
||||
TFoo[T, U] = object
|
||||
x: T
|
||||
y: U
|
||||
|
||||
proc getTypeName(t: typedesc): string = t.name
|
||||
|
||||
proc foo(T: typedesc[float], a: expr): string =
|
||||
result = "float " & $(a.len > 5)
|
||||
|
||||
proc foo(T: typedesc[TFoo], a: int): string =
|
||||
result = "TFoo " & $(a)
|
||||
|
||||
proc foo(T: typedesc[int or bool]): string =
|
||||
var a: T
|
||||
a = 10
|
||||
result = "int or bool " & ($a)
|
||||
|
||||
template foo(T: typedesc[seq]): expr = "seq"
|
||||
|
||||
test "types can be used as proc params":
|
||||
# XXX: `check` needs to know that TFoo[int, float] is a type and
|
||||
# cannot be assigned for a local variable for later inspection
|
||||
check ((string.getTypeName == "string"))
|
||||
check ((getTypeName(int) == "int"))
|
||||
|
||||
check ((foo(TFoo[int, float], 1000) == "TFoo 1000"))
|
||||
|
||||
var f = 10.0
|
||||
check ((foo(float, "long string") == "float true"))
|
||||
check ((foo(type(f), [1, 2, 3]) == "float false"))
|
||||
|
||||
check ((foo(int) == "int or bool 10"))
|
||||
|
||||
check ((foo(seq[int]) == "seq"))
|
||||
check ((foo(seq[TFoo[bool, string]]) == "seq"))
|
||||
|
||||
when false:
|
||||
proc foo(T: typedesc[seq], s: T) = nil
|
||||
|
||||
39
tests/metatype/ttypeselectors.nim
Normal file
39
tests/metatype/ttypeselectors.nim
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import macros
|
||||
|
||||
template selectType(x: int): typeDesc =
|
||||
when x < 10:
|
||||
int
|
||||
else:
|
||||
string
|
||||
|
||||
template simpleTypeTempl: typeDesc =
|
||||
string
|
||||
|
||||
macro typeFromMacro: typedesc = string
|
||||
|
||||
proc t1*(x: int): simpleTypeTempl() =
|
||||
result = "test"
|
||||
|
||||
proc t2*(x: int): selectType(100) =
|
||||
result = "test"
|
||||
|
||||
proc t3*(x: int): selectType(1) =
|
||||
result = 10
|
||||
|
||||
proc t4*(x: int): typeFromMacro() =
|
||||
result = "test"
|
||||
|
||||
var x*: selectType(50) = "test"
|
||||
|
||||
proc t5*(x: selectType(5)) =
|
||||
var y = x + 10
|
||||
echo y
|
||||
|
||||
var y*: type(t2(100)) = "test"
|
||||
|
||||
proc t6*(x: type(t3(0))): type(t1(0)) =
|
||||
result = $x
|
||||
|
||||
proc t7*(x: int): type($x) =
|
||||
result = "test"
|
||||
|
||||
59
tests/metatype/ttypetraits.nim
Normal file
59
tests/metatype/ttypetraits.nim
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
discard """
|
||||
msg: "int\nstring\nTBar[int]"
|
||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
# simple case of type trait usage inside/outside of static blocks
|
||||
proc foo(x) =
|
||||
static:
|
||||
var t = type(x)
|
||||
echo t.name
|
||||
|
||||
echo x.type.name
|
||||
|
||||
type
|
||||
TBar[U] = object
|
||||
x: U
|
||||
|
||||
var bar: TBar[int]
|
||||
|
||||
foo 10
|
||||
foo "test"
|
||||
foo bar
|
||||
|
||||
# generic params on user types work too
|
||||
proc foo2[T](x: TBar[T]) =
|
||||
echo T.name
|
||||
|
||||
foo2 bar
|
||||
|
||||
# less usual generic params on built-in types
|
||||
var arr: array[0..2, int] = [1, 2, 3]
|
||||
|
||||
proc foo3[R, T](x: array[R, T]) =
|
||||
echo name(R)
|
||||
|
||||
foo3 arr
|
||||
|
||||
const TypeList = [int, string, seq[int]]
|
||||
|
||||
macro selectType(inType: typedesc): typedesc =
|
||||
var typeSeq = @[float, TBar[int]]
|
||||
|
||||
for t in TypeList:
|
||||
typeSeq.add(t)
|
||||
|
||||
typeSeq.add(inType)
|
||||
typeSeq.add(type(10))
|
||||
|
||||
var typeSeq2: seq[typedesc] = @[]
|
||||
typeSeq2 = typeSeq
|
||||
|
||||
result = typeSeq2[5]
|
||||
|
||||
var xvar: selectType(string)
|
||||
xvar = "proba"
|
||||
echo xvar.type.name
|
||||
|
||||
28
tests/metatype/tusertypeclasses.nim
Normal file
28
tests/metatype/tusertypeclasses.nim
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
discard """
|
||||
output: "Sortable\nSortable\nContainer"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
TObj = object
|
||||
x: int
|
||||
|
||||
Sortable = generic x, y
|
||||
(x < y) is bool
|
||||
|
||||
ObjectContainer = generic C
|
||||
C.len is ordinal
|
||||
for v in items(C):
|
||||
v.type is tuple|object
|
||||
|
||||
proc foo(c: ObjectContainer) =
|
||||
echo "Container"
|
||||
|
||||
proc foo(x: Sortable) =
|
||||
echo "Sortable"
|
||||
|
||||
foo 10
|
||||
foo "test"
|
||||
foo(@[TObj(x: 10), TObj(x: 20)])
|
||||
|
||||
13
tests/metatype/utypeclasses.nim
Normal file
13
tests/metatype/utypeclasses.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import unittest
|
||||
|
||||
proc concat(a, b): string =
|
||||
result = $a & $b
|
||||
|
||||
test "if proc param types are not supplied, the params are assumed to be generic":
|
||||
check concat(1, "test") == "1test"
|
||||
check concat(1, 20) == "120"
|
||||
check concat("foo", "bar") == "foobar"
|
||||
|
||||
test "explicit param types can still be specified":
|
||||
check concat[cstring, cstring]("x", "y") == "xy"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue