""" tests: pass dynamic to method parameter (receiver is statically typed, method is overloaded) invoke an operator (comparisons, arithmetic) dynamic crossed with slicing (target is dynamic and/or args are dynamic) dynamic points to a Type and you invoke shared properties, indexers and methods on it IDynamic return a dynamic expr in a getter, method or indexer whose return type is static return - other cases """ class A shared def inherited(i as int) as int return i class B inherits A shared def two as int return 2 get three as int return 3 def double(i as int) as int return i * 2 class Test def main .testShared .testOther def testShared b = B to dynamic assert b.two == 2 assert b.three == 3 assert b.double(4) == 8 assert b.inherited(5) == 5 def testOther # to-do: break up this method # use dynamic type explicitly x as dynamic = 'aoeu' assert x=='aoeu' x = 5 assert x==5 x = [1, 2, 3] assert x==[1, 2, 3] # assert with dynamic x = 2 assert x x = 'aoeu' assert x x = [1, 2, 3] assert x x = 0 assert not x x = 0.0 assert not x x = false assert not x # assign dynamic to correct static type x = 5 i as int = x assert i==5 # assign dynamic to incorrect static type expect InvalidCastException d as decimal = x # switch-a-roo x = 5.0 d = x expect InvalidCastException i = x CobraCore.noOp(d) # statically typed property t = Test() assert t.integer == 0 x = 1 t.integer = x assert t.integer == 1 t.integer = 5 x = t.integer assert x == 5 # dynamically typed property assert t.dyn is nil t.dyn = 5 assert t.dyn == 5 t.dyn = 'aoeu' assert t.dyn == 'aoeu' x = t.dyn to ! assert x == 'aoeu' x = 5 t.dyn = x assert t.dyn == 5 a = Test() b = Test() t.dyn = a t.dyn.dyn = b # double up assert t.dyn is a assert t.dyn.dyn is b # method parameters x = 2 t.takeIntValue2(x) expect InvalidCastException x = 'aoeu' t.takeIntValue2(x) x = 1 t.takeDynamic(x) x = 'aoeu' t.takeDynamic(x) # TODO: overloaded method # method return values x = t.return42 assert x == 42 x = t.returnDynamic assert x == 'aoeu' s = '' s = t.returnDynamic assert s == 'aoeu' # invoke a property on a dynamic variable x = t x.integer = 5 assert x.integer == 5 # invoke a method on a dynamic variable x = t x.takeIntValue2(2) assert x.returnArg(5) == 5 assert x.returnArg('aoeu') == 'aoeu' assert x.returnNilableArg(5) == 5 assert x.returnNilableArg('aoeu') == 'aoeu' # to-do assert x.returnNilableArg(nil) is nil assert x.take2Args(1, 2) == 1 assert x.take2Args(1, nil) == 1 assert x.take2Args(nil, 1) is nil assert x.take2Args(nil, nil) is nil # assert x.getType is not nil # would give error: The left and right sides of the "is not" expression can never be identical because of their types ("Type" and "nil"). someType = x.getType assert someType.name == 'Test' assert x.getType.name == 'Test' # invoke overloaded methods on a dynamic variable assert x.overloaded(5) == 1 assert x.overloaded('aoeu') == 2 dyn as dynamic = 5 assert x.overloaded(dyn) == 1 # dynamic receiver *and* dynamic arg dyn = 'aoeu' assert x.overloaded(dyn) == 2 # dynamic receiver *and* dynamic arg # return types are nilable x = Test() r1 = x.dyn r1 = nil # verify that r1 is nilable r2 = x.returnDynamic r2 = nil # verify that r2 is nilable CobraCore.noOp(r1, r2) list = [1, 2, 3] to dynamic anInt = 0 anInt = list.indexOf(2) # verify that dynamic? result can be assigned to a static type CobraCore.noOp(anInt) # .typeOf x = 1 assert x.typeOf is int # TODO: test for each of the exceptions that you can get var _integer as int pro integer from var var _dyn as dynamic? pro dyn from var def return42 as int return 42 def returnDynamic as dynamic return 'aoeu' def takeIntValue2(x as int) assert x == 2 def takeDynamic(d as dynamic) assert d def returnArg(arg as Object) as Object return arg def returnNilableArg(arg as Object?) as Object? return arg def take2Args(a as Object?, b as int?) as Object? return a def overloaded(i as int) as int return 1 def overloaded(s as String) as int return 2