summary refs log tree commit diff stats
path: root/tests/objects
diff options
context:
space:
mode:
Diffstat (limited to 'tests/objects')
-rw-r--r--tests/objects/tobjconstr.nim41
-rw-r--r--tests/objects/tobjconstr2.nim22
-rw-r--r--tests/objects/tobjcov.nim17
-rw-r--r--tests/objects/tobject.nim15
-rw-r--r--tests/objects/tobject2.nim21
-rw-r--r--tests/objects/tobject3.nim28
-rw-r--r--tests/objects/tofopr.nim26
-rw-r--r--tests/objects/toop.nim21
-rw-r--r--tests/objects/toop1.nim89
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
+
+
+