TestCSharp.hx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. package unit;
  2. import haxe.io.Bytes;
  3. import haxe.test.Base;
  4. import haxe.test.Base.Base_InnerClass;
  5. import haxe.test.TEnum;
  6. //C#-specific tests, like unsafe code
  7. class TestCSharp extends Test
  8. {
  9. #if cs
  10. // -net-lib tests
  11. function testHaxeKeywords()
  12. {
  13. eq(Base._inline, 42);
  14. eq(Base._callback, 43);
  15. eq(Base._cast, 44);
  16. eq(Base._untyped, 45);
  17. Base._untyped = 40;
  18. eq(Base._untyped, 40);
  19. }
  20. function testTypes()
  21. {
  22. eq(Base.charTest(cast 10), cast 10);
  23. eq(Base.byteTest(cast 10), cast 10);
  24. }
  25. function testInnerClass()
  26. {
  27. //-java-lib should be able to detect inner classes on import
  28. var i = new Base_InnerClass();
  29. eq(10,i.nameClash());
  30. var i2 = new Base_InnerClass_InnerInnerClass();
  31. t(true);
  32. }
  33. function testGenerics()
  34. {
  35. t(haxe.test.GenericHelper.staticTypedGeneric(new Base_InnerClass_InnerInnerClass()) != null);
  36. var helper = new haxe.test.GenericHelper();
  37. var val = new Base_InnerClass();
  38. var g1 = new haxe.test.Generic1_1(val);
  39. g1.complexTypeParameterOfTypeParameter(new Base_InnerClass_InnerInnerClass());
  40. //if no compile-time error, we're fine!
  41. t(true);
  42. }
  43. function testDelegates()
  44. {
  45. var run = false;
  46. var v:haxe.test.VoidVoid = function () run = true;
  47. f(run);
  48. v.Invoke();
  49. t(run);
  50. f(didRun);
  51. v = doRun;
  52. v.Invoke();
  53. t(didRun);
  54. run = false;
  55. var someFunc = function() run = true;
  56. f(run);
  57. v = someFunc;
  58. f(run);
  59. v.Invoke();
  60. t(run);
  61. var someFunc2 = someFunc;
  62. var getFun = function() return someFunc2;
  63. run = false;
  64. f(run);
  65. v = { var x = "complex body"; getFun(); };
  66. f(run);
  67. v.Invoke();
  68. t(run);
  69. var dyn:Dynamic = v;
  70. t(Std.is(dyn, haxe.test.VoidVoid));
  71. }
  72. var didRun = false;
  73. function doRun()
  74. {
  75. didRun = true;
  76. }
  77. function testOverloadOverride()
  78. {
  79. var c = new haxe.test.MyClass();
  80. eq(42,c.SomeProp);
  81. eq(42,c.SomeProp2);
  82. var c = new TestMyClass();
  83. c.normalOverload(true);
  84. t(c.boolCalled);
  85. c.normalOverload(10);
  86. t(c.intCalled);
  87. c.normalOverload(haxe.Int64.ofInt(0));
  88. t(c.int64Called);
  89. c.normalOverload("");
  90. t(c.stringCalled);
  91. c.normalOverload({});
  92. t(c.dynamicCalled);
  93. eq(21,c.SomeProp);
  94. t(c.getCalled);
  95. eq(21,c.SomeProp2);
  96. var c = new TestMyClass("");
  97. t(c.alternativeCtorCalled);
  98. var b:haxe.test.MyClass = c;
  99. b.normalOverload(true);
  100. t(c.boolCalled);
  101. b.normalOverload(10);
  102. t(c.intCalled);
  103. b.normalOverload(haxe.Int64.ofInt(0));
  104. t(c.int64Called);
  105. b.normalOverload("");
  106. t(c.stringCalled);
  107. b.normalOverload({});
  108. t(c.dynamicCalled);
  109. eq(21,c.SomeProp);
  110. t(c.getCalled);
  111. eq(21,c.SomeProp2);
  112. }
  113. function testEnum()
  114. {
  115. var e = TEnum.TA;
  116. switch(e)
  117. {
  118. case TA:
  119. t(true);
  120. case _:
  121. t(false);
  122. }
  123. eq("TA",Type.enumConstructor(e));
  124. }
  125. @:skipReflection private function refTest(i:cs.Ref<Int>):Void
  126. {
  127. i *= 2;
  128. }
  129. @:skipReflection private function outTest(out:cs.Out<Int>, x:Int):Void
  130. {
  131. out = x * 2;
  132. }
  133. // test for https://github.com/HaxeFoundation/haxe/issues/2528
  134. public function testDynObjectSetField()
  135. {
  136. var a:Dynamic = {};
  137. a.status = 10;
  138. var b:{status:Int} = a;
  139. b.status = 15;
  140. eq(a, b);
  141. eq(Reflect.fields(a).length, 1);
  142. eq(Reflect.fields(b).length, 1);
  143. eq(a.status, 15);
  144. eq(b.status, 15);
  145. }
  146. public function testRef()
  147. {
  148. var i = 10;
  149. refTest(i);
  150. eq(i, 20);
  151. var cl:NativeClass = new HxClass();
  152. cl.refTest(i);
  153. eq(i, 80);
  154. cl.test = 100;
  155. cl.refTest(cl.test);
  156. eq(cl.test,400);
  157. }
  158. public function testOut()
  159. {
  160. var i = 0;
  161. outTest(i, 10);
  162. eq(i, 20);
  163. var cl:NativeClass = new HxClass();
  164. cl.outTest(i, 10);
  165. eq(i, 40);
  166. cl.test = 20;
  167. cl.outTest(cl.test, 10);
  168. eq(cl.test,40);
  169. }
  170. public function testChecked()
  171. {
  172. exc(function()
  173. {
  174. cs.Lib.checked({
  175. var x = 1000;
  176. while(true)
  177. {
  178. x *= x;
  179. }
  180. });
  181. });
  182. }
  183. public function testUncheckedAttribute()
  184. {
  185. var cls = cs.Lib.toNativeType( TestMyClass ),
  186. attribType = cs.Lib.toNativeType( cs.system.componentmodel.DescriptionAttribute );
  187. var attrib:cs.system.componentmodel.DescriptionAttribute = cast cs.system.Attribute.GetCustomAttribute(cls,attribType,true);
  188. t(attrib != null);
  189. eq("MyClass Description", attrib.Description);
  190. attrib = cast cs.system.Attribute.GetCustomAttribute(cls.GetMethod("argumentDescription"), attribType,true);
  191. t(attrib != null);
  192. eq("Argument description", attrib.Description);
  193. attrib = cast cs.system.Attribute.GetCustomAttribute(cls.GetMethod("argumentDescription").GetParameters()[0], attribType,true);
  194. t(attrib != null);
  195. eq("Type description test", attrib.Description);
  196. }
  197. public function testEvents()
  198. {
  199. var x = new haxe.test.MyClass();
  200. var hasFired = false;
  201. f(hasFired);
  202. var fn:haxe.test.VoidVoid = function() hasFired = true;
  203. x.add_voidvoid( fn );
  204. f(hasFired);
  205. x.dispatch();
  206. t(hasFired);
  207. hasFired = false;
  208. x.dispatch();
  209. t(hasFired);
  210. hasFired = false;
  211. x.remove_voidvoid( fn );
  212. x.dispatch();
  213. f(hasFired);
  214. }
  215. #if unsafe
  216. @:unsafe public function testUnsafe()
  217. {
  218. var x:cs.NativeArray<Int> = new cs.NativeArray(10);
  219. cs.Lib.fixed({
  220. var p = cs.Lib.pointerOfArray(x);
  221. for (i in 0...10)
  222. {
  223. p[0] = i;
  224. p = p.add(1);
  225. }
  226. });
  227. cs.Lib.fixed( {
  228. var p = cs.Lib.pointerOfArray(x);
  229. for (i in 0...10)
  230. {
  231. eq(p[i], i);
  232. }
  233. });
  234. var x:Int = 0;
  235. var addr = cs.Lib.addressOf(x);
  236. eq(cs.Lib.valueOf(addr), 0);
  237. eq(addr[0], 0);
  238. addr[0] = 42;
  239. eq(cs.Lib.valueOf(addr), 42);
  240. eq(addr[0], 42);
  241. eq(x, 42);
  242. }
  243. #end
  244. // test these because C# generator got a special filter for these expressions
  245. public function testNullConstEq()
  246. {
  247. var a:Null<Int> = 10;
  248. f(a == null);
  249. f(null == a);
  250. t(a != null);
  251. t(null != a);
  252. }
  253. #end
  254. }
  255. @:nativeGen private class NativeClass
  256. {
  257. public var test:Int;
  258. public function outTest(out:cs.Out<Int>, x:Int):Void
  259. {
  260. out = x * 2;
  261. }
  262. public function refTest(i:cs.Ref<Int>):Void
  263. {
  264. i *= 2;
  265. }
  266. }
  267. @:meta(System.ComponentModel.Description("Type description test"))
  268. typedef StringWithDescription = String;
  269. private class HxClass extends NativeClass
  270. {
  271. public function new()
  272. {
  273. }
  274. //here it would normally fail due to the added fast reflection field
  275. override public function outTest(out:cs.Out<Int>, x:Int):Void
  276. {
  277. out = x * 4;
  278. }
  279. override public function refTest(i:cs.Ref<Int>):Void
  280. {
  281. super.refTest(i);
  282. i *= 2;
  283. }
  284. }
  285. @:meta(System.ComponentModel.Description("MyClass Description"))
  286. private class TestMyClass extends haxe.test.MyClass
  287. {
  288. @:overload public function new()
  289. {
  290. super();
  291. }
  292. @:overload public function new(str:String)
  293. {
  294. super();
  295. alternativeCtorCalled = true;
  296. }
  297. public var alternativeCtorCalled:Bool;
  298. public var boolCalled:Bool;
  299. public var intCalled:Bool;
  300. public var int64Called:Bool;
  301. public var stringCalled:Bool;
  302. public var dynamicCalled:Bool;
  303. public var getCalled:Bool;
  304. @:meta(System.ComponentModel.Description("Argument description"))
  305. @:keep public function argumentDescription(arg:StringWithDescription)
  306. {
  307. }
  308. @:overload override public function normalOverload(b:Bool):Void
  309. {
  310. this.boolCalled = true;
  311. }
  312. @:overload override public function normalOverload(i:Int):Void
  313. {
  314. this.intCalled = true;
  315. }
  316. @:overload override public function normalOverload(i64:haxe.Int64):Void
  317. {
  318. this.int64Called = true;
  319. }
  320. @:overload override public function normalOverload(str:String):Void
  321. {
  322. this.stringCalled = true;
  323. }
  324. @:overload override public function normalOverload(dyn:Dynamic):Void
  325. {
  326. this.dynamicCalled = true;
  327. }
  328. @:overload override private function get_SomeProp():Int
  329. {
  330. getCalled = true;
  331. return 21;
  332. }
  333. @:overload override private function get_SomeProp2():Int
  334. {
  335. return Std.int(super.get_SomeProp2() / 2);
  336. }
  337. }