diff options
Diffstat (limited to 'tests/objects')
-rw-r--r-- | tests/objects/tobjconstr.nim | 41 | ||||
-rw-r--r-- | tests/objects/tobjconstr2.nim | 22 | ||||
-rw-r--r-- | tests/objects/tobjcov.nim | 17 | ||||
-rw-r--r-- | tests/objects/tobject.nim | 15 | ||||
-rw-r--r-- | tests/objects/tobject2.nim | 21 | ||||
-rw-r--r-- | tests/objects/tobject3.nim | 28 | ||||
-rw-r--r-- | tests/objects/tofopr.nim | 26 | ||||
-rw-r--r-- | tests/objects/toop.nim | 21 | ||||
-rw-r--r-- | tests/objects/toop1.nim | 89 |
9 files changed, 280 insertions, 0 deletions
diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim new file mode 100644 index 000000000..3bd785728 --- /dev/null +++ b/tests/objects/tobjconstr.nim @@ -0,0 +1,41 @@ +discard """ + output: '''(k: kindA, a: (x: abc, z: [1, 1, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 2, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 3, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 4, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 5, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 6, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 7, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 8, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 9, 3]), empty: ()) +(k: kindA, a: (x: abc, z: [1, 10, 3]), empty: ())''' +""" + +type + TArg = object + x: string + z: seq[int] + TKind = enum kindXY, kindA + TEmpty = object + TDummy = ref object + case k: TKind + of kindXY: x, y: int + of kindA: + a: TArg + empty: TEmpty + +proc `$`[T](s: seq[T]): string = + # XXX why is that not in the stdlib? + result = "[" + for i, x in s: + if i > 0: result.add(", ") + result.add($x) + result.add("]") + +proc main() = + for i in 1..10: + let d = TDummy(k: kindA, a: TArg(x: "abc", z: @[1,i,3]), empty: TEmpty()) + echo d[] + +main() + diff --git a/tests/objects/tobjconstr2.nim b/tests/objects/tobjconstr2.nim new file mode 100644 index 000000000..cb47e146d --- /dev/null +++ b/tests/objects/tobjconstr2.nim @@ -0,0 +1,22 @@ +type TFoo{.exportc.} = object + x:int + +var s{.exportc.}: seq[TFoo] = @[] + +s.add TFoo(x: 42) + +echo s[0].x + + +# bug #563 +type + Foo = + object {.inheritable.} + x: int + + Bar = + object of Foo + y: int + +var a = Bar(y: 100, x: 200) # works +var b = Bar(x: 100, y: 200) # used to fail diff --git a/tests/objects/tobjcov.nim b/tests/objects/tobjcov.nim new file mode 100644 index 000000000..fc44edf8e --- /dev/null +++ b/tests/objects/tobjcov.nim @@ -0,0 +1,17 @@ +# Covariance is not type safe: + +type + TA = object of TObject + a: int + TB = object of TA + b: array[0..5000_000, int] + +proc ap(x: var TA) = x.a = -1 +proc bp(x: var TB) = x.b[high(x.b)] = -1 + +# in Nimrod proc (x: TB) is compatible to proc (x: TA), +# but this is not type safe: +var f = cast[proc (x: var TA) {.nimcall.}](bp) +var a: TA +f(a) # bp expects a TB, but gets a TA + diff --git a/tests/objects/tobject.nim b/tests/objects/tobject.nim new file mode 100644 index 000000000..5fec84441 --- /dev/null +++ b/tests/objects/tobject.nim @@ -0,0 +1,15 @@ +import unittest + +type Obj = object + foo: int + +proc makeObj(x: int): Obj = + result.foo = x + +suite "object basic methods": + test "it should convert an object to a string": + var obj = makeObj(1) + # Should be "obj: (foo: 1)" or similar. + check($obj == "(foo: 1)") + test "it should test equality based on fields": + check(makeObj(1) == makeObj(1)) diff --git a/tests/objects/tobject2.nim b/tests/objects/tobject2.nim new file mode 100644 index 000000000..0f1869695 --- /dev/null +++ b/tests/objects/tobject2.nim @@ -0,0 +1,21 @@ +# Tests the object implementation + +type + TPoint2d {.inheritable.} = object + x, y: int + + TPoint3d = object of TPoint2d + z: int # added a field + +proc getPoint( p: var TPoint2d) = + {.breakpoint.} + writeln(stdout, p.x) + +var + p: TPoint3d + +TPoint2d(p).x = 34 +p.y = 98 +p.z = 343 + +getPoint(p) diff --git a/tests/objects/tobject3.nim b/tests/objects/tobject3.nim new file mode 100644 index 000000000..935e6ca8c --- /dev/null +++ b/tests/objects/tobject3.nim @@ -0,0 +1,28 @@ +type + TFoo = ref object of TObject + Data: int + TBar = ref object of TFoo + nil + TBar2 = ref object of TBar + d2: int + +template super(self: TBar): TFoo = self + +template super(self: TBar2): TBar = self + +proc Foo(self: TFoo) = + echo "TFoo" + +#proc Foo(self: TBar) = +# echo "TBar" +# Foo(super(self)) +# works when this code is uncommented + +proc Foo(self: TBar2) = + echo "TBar2" + Foo(super(self)) + +var b: TBar2 +new(b) + +Foo(b) diff --git a/tests/objects/tofopr.nim b/tests/objects/tofopr.nim new file mode 100644 index 000000000..961d81bd3 --- /dev/null +++ b/tests/objects/tofopr.nim @@ -0,0 +1,26 @@ +discard """ + file: "tofopr.nim" + output: "falsetrue" +""" +# Test is operator + +type + TMyType = object {.inheritable.} + len: int + data: string + + TOtherType = object of TMyType + +proc p(x: TMyType): bool = + return x of TOtherType + +var + m: TMyType + n: TOtherType + +write(stdout, p(m)) +write(stdout, p(n)) + +#OUT falsetrue + + diff --git a/tests/objects/toop.nim b/tests/objects/toop.nim new file mode 100644 index 000000000..0b42c2c22 --- /dev/null +++ b/tests/objects/toop.nim @@ -0,0 +1,21 @@ +discard """ + output: "b" +""" + +type + TA = object of TObject + x, y: int + + TB = object of TA + z: int + + TC = object of TB + whatever: string + +proc p(a: var TA) = echo "a" +proc p(b: var TB) = echo "b" + +var c: TC + +p(c) + diff --git a/tests/objects/toop1.nim b/tests/objects/toop1.nim new file mode 100644 index 000000000..350799f51 --- /dev/null +++ b/tests/objects/toop1.nim @@ -0,0 +1,89 @@ +discard """ + file: "toop1.nim" + output: "34[]o 5" +""" +# Test the stuff in the tutorial +import macros + +type + TFigure = object of TObject # abstract base class: + draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this + +proc init(f: var TFigure) = + f.draw = nil + +type + TCircle = object of TFigure + radius: int + +proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius) + +proc init(my: var TCircle) = + init(TFigure(my)) # call base constructor + my.radius = 5 + my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawCircle) + +type + TRectangle = object of TFigure + width, height: int + +proc drawRectangle(my: var TRectangle) = stdout.write("[]") + +proc init(my: var TRectangle) = + init(TFigure(my)) # call base constructor + my.width = 5 + my.height = 10 + my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle) + +macro `!` (n: expr): stmt {.immediate.} = + let n = callsite() + result = newNimNode(nnkCall, n) + var dot = newNimNode(nnkDotExpr, n) + dot.add(n[1]) # obj + if n[2].kind == nnkCall: + # transforms ``obj!method(arg1, arg2, ...)`` to + # ``(obj.method)(obj, arg1, arg2, ...)`` + dot.add(n[2][0]) # method + result.add(dot) + result.add(n[1]) # obj + for i in 1..n[2].len-1: + result.add(n[2][i]) + else: + # transforms ``obj!method`` to + # ``(obj.method)(obj)`` + dot.add(n[2]) # method + result.add(dot) + result.add(n[1]) # obj + +type + TSocket* = object of TObject + FHost: int # cannot be accessed from the outside of the module + # the `F` prefix is a convention to avoid clashes since + # the accessors are named `host` + +proc `host=`*(s: var TSocket, value: int) {.inline.} = + ## setter of hostAddr + s.FHost = value + +proc host*(s: TSocket): int {.inline.} = + ## getter of hostAddr + return s.FHost + +var + s: TSocket +s.host = 34 # same as `host=`(s, 34) +stdout.write(s.host) + +# now use these classes: +var + r: TRectangle + c: TCircle +init(r) +init(c) +r!draw +c!draw() + +#OUT 34[]o 5 + + + |