PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/unit/src/unit/TestBasetypes.hx

https://gitlab.com/ezeql/haxe
Haxe | 510 lines | 397 code | 81 blank | 32 comment | 7 complexity | d4f4feb5856c18377c14ecb3a3a43afe MD5 | raw file
  1. package unit;
  2. class TestBasetypes extends Test {
  3. function testArray() {
  4. var a : Array<Null<Int>> = [1,2,3];
  5. eq( a.length, 3 );
  6. eq( a[0], 1 );
  7. eq( a[2], 3 );
  8. eq( a[3], null );
  9. eq( a[1000], null );
  10. eq( a[-1], null );
  11. a.remove(2);
  12. eq( a.length, 2);
  13. eq( a[0], 1 );
  14. eq( a[1], 3 );
  15. eq( a[2], null );
  16. var a : Array<Null<Int>> = [1,2,3];
  17. a.splice(1,1);
  18. eq( a.length, 2 );
  19. eq( a[0], 1 );
  20. eq( a[1], 3 );
  21. eq( a[2], null );
  22. }
  23. function testString() {
  24. eq( String.fromCharCode(77), "M" );
  25. unspec(function() String.fromCharCode(0));
  26. unspec(function() String.fromCharCode(-1));
  27. unspec(function() String.fromCharCode(256));
  28. #if php
  29. eq( Std.string(null) + "x", "nullx" );
  30. eq( "x" + Std.string(null), "xnull" );
  31. #else
  32. eq( null + "x", "nullx" );
  33. eq( "x" + null, "xnull" );
  34. #end
  35. var abc = "abc".split("");
  36. eq( abc.length, 3 );
  37. eq( abc[0], "a" );
  38. eq( abc[1], "b" );
  39. eq( abc[2], "c" );
  40. var str = "abc";
  41. eq( str.charCodeAt(0), "a".code );
  42. eq( str.charCodeAt(1), "b".code );
  43. eq( str.charCodeAt(2), "c".code );
  44. eq( str.charCodeAt(-1), null );
  45. eq( str.charCodeAt(3), null );
  46. // substr tests
  47. var sentence:String = "Pack my box with five dozen liquor jugs.";
  48. eq(sentence.substr(0, 4), "Pack");
  49. eq(sentence.substr(5, 2), "my");
  50. eq(sentence.substr(0), sentence);
  51. eq(sentence.substr(35), "jugs.");
  52. eq(sentence.substr(40), "");
  53. eq(sentence.substr(42), "");
  54. eq(sentence.substr(-5, 4), "jugs");
  55. eq(sentence.substr(-5), "jugs.");
  56. eq(sentence.substr(-42), sentence);
  57. eq(sentence.substr(4, 0), "");
  58. eq(sentence.substr(0, -36), "Pack");
  59. // null should not be swallowed
  60. eq("hello" +null, "hellonull");
  61. eq(null + "hello", "nullhello");
  62. var x:Dynamic = null;
  63. //String const + Dynamic var with null ref
  64. eq("hello" +x, "hellonull");
  65. eq(x + "hello", "nullhello");
  66. var y:Dynamic = "hello";
  67. //Dynamic var + Dynamic var, where one is null, the other is a string:
  68. eq(x + y, "nullhello");
  69. eq(y + x, "hellonull");
  70. var x:String = null;
  71. //String const + String var with null ref
  72. eq("hello" +x, "hellonull");
  73. eq(x + "hello", "nullhello");
  74. var x = { hello:"world", val:5 };
  75. var xs = "" + x;
  76. // Output should contain hello followed by world, and val followed by 5.
  77. // The order of fields and operator between key and value remain unspecified.
  78. var h = xs.indexOf("hello");
  79. t(h != -1);
  80. t(xs.indexOf("world", h) != -1);
  81. h = xs.indexOf("val");
  82. t(h != -1);
  83. t(xs.indexOf("5", h) != -1);
  84. eq(x + "", xs);
  85. // Let's just make sure this is not 10 on any platform.
  86. eq(5 + "5", "55");
  87. eq("5" + 5, "55");
  88. eq("5" + 5.1, "55.1");
  89. // Some precedence checks.
  90. eq(1 + 1 + 1 + 1 + "1", "41");
  91. eq("1" + 1 + 1 + 1 + 1, "11111");
  92. eq(1 + 1 + "1" + 1 * 2, "212");
  93. // check recursive formating
  94. var x = [[1], [2, 3]];
  95. eq("" + x, "[[1],[2,3]]");
  96. // Brackets around array values should not be stripped.
  97. var x : Array<Dynamic> = [1, "hello"];
  98. eq("" + x, "[1,hello]");
  99. eq(x + "", "" + x);
  100. // This is also true for iterables that are arrays.
  101. var x:Iterable<Dynamic> = x;
  102. eq("" + x, "[1,hello]");
  103. eq(x + "", "" + x);
  104. // I don't think this should throw an exception on PHP.
  105. try {
  106. "" + x.iterator();
  107. } catch (e:Dynamic) {
  108. Test.report("Could not convert Iterator to String");
  109. }
  110. var str = "he\nlo\"'";
  111. eq( Std.string(str), str);
  112. eq( Std.string([str]), "[" + str + "]");
  113. var e = MyEnum.C(0, "h");
  114. eq( Std.string(e), "C(0,h)");
  115. eq(Std.string([e]), "[C(0,h)]");
  116. var tester:String = "show me the (show me!) index of show me";
  117. eq(tester.lastIndexOf("show me"), 32);
  118. eq(tester.lastIndexOf("show me", 1), 0);
  119. eq(tester.lastIndexOf("show me",28), 13);
  120. }
  121. function testMath() {
  122. eq( Math.floor(-1.7), -2 );
  123. eq( Math.floor(-1.5), -2 );
  124. eq( Math.floor(-1.2), -2 );
  125. eq( Math.floor(1.7), 1 );
  126. eq( Math.floor(1.5), 1 );
  127. eq( Math.floor(1.2), 1 );
  128. eq( Math.ceil(-1.7), -1 );
  129. eq( Math.ceil(-1.5), -1 );
  130. eq( Math.ceil(-1.2), -1 );
  131. eq( Math.ceil(1.7), 2 );
  132. eq( Math.ceil(1.5), 2 );
  133. eq( Math.ceil(1.2), 2 );
  134. eq( Math.round(-1.7), -2 );
  135. eq( Math.round(-1.5), -1 );
  136. eq( Math.round(-1.2), -1 );
  137. eq( Math.round(1.7), 2 );
  138. eq( Math.round(1.5), 2 );
  139. eq( Math.round(1.2), 1 );
  140. // we don't specify Std.int and other to-int conversions when outside the Int range
  141. #if (js || flash)
  142. eq( Std.int( -10000000000.7), 0xABF41C00 );
  143. eq( Std.int( 10000000000.7), 0x540BE400 );
  144. eq( Std.int( -4294967296.7), 0 );
  145. eq( Std.int( -4294967296.001), 0 );
  146. eq( Std.int( 4294967296.7), 0 );
  147. eq( Std.int( 4294967296.001), 0 );
  148. eq( Std.int( -4294967295.7), 1 );
  149. eq( Std.int( -4294967295.001), 1 );
  150. eq( Std.int( 4294967295.7), -1 );
  151. eq( Std.int( 4294967295.001), -1 );
  152. eq( Std.int( -2147483648.7), 0x80000000 );
  153. eq( Std.int( -2147483648.001), 0x80000000 );
  154. eq( Std.int( 2147483648.7), 0x80000000 );
  155. eq( Std.int( 2147483648.001), 0x80000000 );
  156. eq( Std.int( -2147483647.7), 0x80000001 );
  157. eq( Std.int( -2147483647.001), 0x80000001 );
  158. eq( Std.int( 2147483647.7), 0x7FFFFFFF );
  159. eq( Std.int( 2147483647.001), 0x7FFFFFFF );
  160. #if (flash && !as3)
  161. eq( Math.floor( -10000000000.7), 0xABF41BFF);
  162. eq( Math.ceil( -10000000000.7), 0xABF41C00);
  163. eq( Math.round( -10000000000.7), 0xABF41BFF);
  164. #else
  165. eq( Math.floor( -10000000000.7)*1.0, -10000000001. );
  166. eq( Math.ceil( -10000000000.7)*1.0, -10000000000. );
  167. eq( Math.round( -10000000000.7)*1.0, -10000000001. );
  168. #end
  169. #end
  170. eq( Math.ffloor( -10000000000.7), -10000000001. );
  171. eq( Math.fceil( -10000000000.7), -10000000000. );
  172. eq( Math.fround( -10000000000.7), -10000000001. );
  173. }
  174. function testStringMap() {
  175. var h = new haxe.ds.StringMap<Null<Int>>();
  176. h.set("x", -1);
  177. h.set("abcd", 8546);
  178. eq( h.get("x"), -1);
  179. eq( h.get("abcd"), 8546 );
  180. eq( h.get("e"), null );
  181. var k = Lambda.array(h);
  182. k.sort(Reflect.compare);
  183. eq( k.join("#"), "-1#8546" );
  184. var k = Lambda.array( { iterator : h.keys } );
  185. k.sort(Reflect.compare);
  186. eq( k.join("#"), "abcd#x" );
  187. t( h.exists("x") );
  188. t( h.exists("abcd") );
  189. f( h.exists("e") );
  190. h.remove("abcd");
  191. t( h.exists("x") );
  192. f( h.exists("abcd") );
  193. f( h.exists("e") );
  194. eq( h.get("abcd"), null);
  195. h.set("x", null);
  196. t( h.exists("x") );
  197. t( h.remove("x") );
  198. f( h.remove("x") );
  199. }
  200. function testIntMap() {
  201. var h = new haxe.ds.IntMap<Null<Int>>();
  202. h.set(0, -1);
  203. h.set(-4815, 8546);
  204. eq( h.get(0), -1);
  205. eq( h.get(-4815), 8546 );
  206. eq( h.get(456), null );
  207. var k = Lambda.array(h);
  208. k.sort(Reflect.compare);
  209. eq( k.join("#"), "-1#8546" );
  210. var k = Lambda.array( { iterator : h.keys } );
  211. k.sort(Reflect.compare);
  212. eq( k.join("#"), "-4815#0" );
  213. t( h.exists(0) );
  214. t( h.exists(-4815) );
  215. f( h.exists(456) );
  216. h.remove(-4815);
  217. t( h.exists(0) );
  218. f( h.exists(-4815) );
  219. f( h.exists(456) );
  220. eq( h.get( -4815), null);
  221. h.set(65, null);
  222. t( h.exists(65) );
  223. t( h.remove(65) );
  224. f( h.remove(65) );
  225. var h = new haxe.ds.IntMap();
  226. h.set(1, ['a', 'b']);
  227. t( h.exists(1) );
  228. t( h.remove(1) );
  229. f( h.remove(1) );
  230. }
  231. function testMap() {
  232. var i = new Map();
  233. i[1] = 0;
  234. var x = 1;
  235. i[x++] += 4;
  236. eq(x, 2);
  237. eq(i[1], 4);
  238. }
  239. function testObjectKeyword() {
  240. // new is a keyword in Haxe
  241. var l = { "new": "test" };
  242. var prefix = #if as3 "_" #else "" #end;
  243. eq(Reflect.field(l, prefix + "new"), "test");
  244. // const is a keyword on some platforms but not in Haxe
  245. // check that with can still access it normally
  246. var o = { const : 6 }
  247. eq(o.const, 6);
  248. eq(Reflect.field(o, prefix+"const"), 6);
  249. }
  250. function testFormat() {
  251. eq('', "");
  252. eq('$', "$");
  253. eq('$$', "$");
  254. eq('x$*', "x$*");
  255. var x = 5, y = [];
  256. eq('$x', "5");
  257. eq('a$x$', "a5$");
  258. eq('${5}', "5");
  259. eq('${5}${2}', "52");
  260. eq('a${x}b', "a5b");
  261. eq('${x}${y}', "5[]");
  262. }
  263. function testAbstract() {
  264. var a = new MyAbstract(33);
  265. t( Std.is(a, Int) );
  266. eq( a.toInt(), 33 );
  267. var b = a;
  268. a.incr();
  269. eq( a.toInt(), 34 );
  270. eq( b.toInt(), 33 );
  271. }
  272. function testAbstractCast() {
  273. var s = "Abstract casting ::t::";
  274. // var from
  275. var tpl:unit.MyAbstract.TemplateWrap = s;
  276. t(Std.is(tpl, haxe.Template));
  277. t(Std.is(tpl.get(), haxe.Template));
  278. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  279. //var to
  280. var str:String = tpl;
  281. t(Std.is(str, String));
  282. eq(str, "Abstract casting really works!");
  283. // assign from
  284. var tpl:unit.MyAbstract.TemplateWrap;
  285. tpl = s;
  286. t(Std.is(tpl, haxe.Template));
  287. t(Std.is(tpl.get(), haxe.Template));
  288. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  289. //assign to
  290. var str:String;
  291. str = tpl;
  292. t(Std.is(str, String));
  293. eq(str, "Abstract casting really works!");
  294. // call arg from
  295. function from(tpl:unit.MyAbstract.TemplateWrap) {
  296. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  297. }
  298. from(s);
  299. // call arg to
  300. function from(s:String) {
  301. eq(s, "Abstract casting really works!");
  302. }
  303. from(tpl);
  304. // object decl from variant
  305. var obj: { tpl:unit.MyAbstract.TemplateWrap } = { tpl:s };
  306. eq(obj.tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  307. // object decl from
  308. var obj: { tpl:unit.MyAbstract.TemplateWrap };
  309. obj = { tpl:s };
  310. eq(obj.tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  311. // object decl to variant
  312. var obj: { s:String } = { s:tpl };
  313. eq(obj.s, "Abstract casting really works!");
  314. // object decl to
  315. var obj: { s:String };
  316. obj = { s:tpl };
  317. eq(obj.s, "Abstract casting really works!");
  318. // array from
  319. var arr:Array<unit.MyAbstract.TemplateWrap> = [s, "foo"];
  320. eq(arr[0].get().execute( { t:"works!" } ), "Abstract casting works!");
  321. eq(arr[1].get().execute( { } ), "foo");
  322. // array to
  323. var arr:Array<String> = [tpl];
  324. eq(arr[0], "Abstract casting really works!");
  325. // cast to return
  326. function returnAbstractCast():String {
  327. return new unit.MyAbstract.Meter(12.2);
  328. }
  329. eq(returnAbstractCast(), "12.2m");
  330. // switch
  331. function switchMe(b):String {
  332. return switch(b) {
  333. case true: new unit.MyAbstract.Meter(12.2);
  334. default: new unit.MyAbstract.Meter(2.4);
  335. }
  336. }
  337. eq(switchMe(true), "12.2m");
  338. eq(switchMe(false), "2.4m");
  339. // ctor
  340. var m:unit.MyAbstract.Meter = 3000;
  341. var c = new unit.MyAbstract.MyClassWithAbstractArgCtor(m);
  342. feq(c.km, 3);
  343. }
  344. function testAbstractToAbstractCast() {
  345. var m:unit.MyAbstract.Meter = 122.2;
  346. var km:unit.MyAbstract.Kilometer = m;
  347. feq(km, 0.1222);
  348. }
  349. function testAbstractTypeParameters() {
  350. var hash1:unit.MyAbstract.MyHash<String> = ["k1", "v1", "k2", "v2"];
  351. eq("v1", hash1.get("k1"));
  352. eq("v2", hash1.get("k2"));
  353. var hash1:unit.MyAbstract.MyHash<Int> = [1, 2, 3, 4];
  354. eq(2, hash1.get("_s1"));
  355. eq(4, hash1.get("_s3"));
  356. }
  357. function testAbstractToString() {
  358. var km:unit.MyAbstract.Kilometer = 12.5;
  359. var m:unit.MyAbstract.Meter = 12.5;
  360. eq("12.5km", km);
  361. eq("12.5m", m);
  362. eq("Distance: 12.5km", "Distance: " + km);
  363. eq("Distance: 12.5m", "Distance: " + m);
  364. }
  365. function testAbstractInline() {
  366. eq(getAbstractValue(1), 2);
  367. eq(unit.MyAbstract.MyAbstractCounter.counter, 1);
  368. eq(getAbstractValue(2), 3);
  369. eq(unit.MyAbstract.MyAbstractCounter.counter, 2);
  370. eq(getAbstractValue(3), 4);
  371. eq(unit.MyAbstract.MyAbstractCounter.counter, 3);
  372. }
  373. inline function getAbstractValue(a:unit.MyAbstract.MyAbstractCounter) {
  374. return a.getValue();
  375. }
  376. function testAbstractOperatorOverload() {
  377. var v1:unit.MyAbstract.MyVector = new unit.MyAbstract.MyPoint3(1, 1, 1);
  378. var v2:unit.MyAbstract.MyVector = new unit.MyAbstract.MyPoint3(1, 2, 3);
  379. eq("(2,3,4)", v1 + v2);
  380. eq("(2,4,6)", v2 * 2.);
  381. var v1Old = v1;
  382. v1 *= 2.;
  383. eq("(2,2,2)", v1);
  384. eq(v1Old, v1);
  385. var v3 = v1 * 2.;
  386. eq("(4,4,4)", v3);
  387. f(v1 == v3);
  388. var i:unit.MyAbstract.MyInt = 1;
  389. eq(2, i + i);
  390. i = i + i;
  391. eq(2, i);
  392. var s = "";
  393. function getString() {
  394. s += "b";
  395. return s;
  396. }
  397. var r:unit.MyAbstract.MyInt = 5;
  398. eq("aaaaa", r * "a");
  399. eq("aaaaa", "a" * r);
  400. eq("bbbbb", r * getString());
  401. eq("bbbbbbbbbb", getString() * r);
  402. var v:unit.MyAbstract.MyInt = 5;
  403. eq("abcde", "abcdefghijk" / v);
  404. }
  405. function testAbstractSetter() {
  406. var as = new unit.MyAbstract.MyAbstractSetter();
  407. as.value = "foo";
  408. eq(as.value, "foo");
  409. }
  410. function testAbstractMemberCall() {
  411. var as = new MyAbstract.MyAbstractThatCallsAMember(2);
  412. eq(3, as);
  413. }
  414. function testAbstractMultitypeInline() {
  415. var a = new unit.MyAbstract.MySpecialString("My debugging abstract");
  416. eq("debugging abstract", a.substr(3));
  417. }
  418. @:analyzer(no_local_dce)
  419. function testOptionalStructureFields() {
  420. var a:{?f:Int} = {};
  421. eq(a.f, null);
  422. var o:Dynamic = {};
  423. var a:{?f:Int} = o;
  424. eq(a.f, null);
  425. var i:Dynamic = 1;
  426. var a:{?f:Int} = i;
  427. unspec(function() a.f);
  428. }
  429. }