PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/unit/TestBasetypes.hx

http://github.com/MarcWeber/haxe-compiler-experiments
Haxe | 406 lines | 313 code | 63 blank | 30 comment | 8 complexity | 0a70c6a93c3c281ddbeecacace31055b 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. eq( Std.int( -10000000000.7), 0xABF41C00 );
  141. #if (js || flash8 || as3 || php)
  142. // higher Int resolution : should we fix this or not ?
  143. eq( Math.floor( -10000000000.7)*1.0, -10000000001. );
  144. eq( Math.ceil( -10000000000.7)*1.0, -10000000000. );
  145. eq( Math.round( -10000000000.7)*1.0, -10000000001. );
  146. #else
  147. eq( Math.floor( -10000000000.7), 0xABF41BFF);
  148. eq( Math.ceil( -10000000000.7), 0xABF41C00);
  149. eq( Math.round( -10000000000.7), 0xABF41BFF);
  150. #end
  151. eq( Math.ffloor( -10000000000.7), -10000000001. );
  152. eq( Math.fceil( -10000000000.7), -10000000000. );
  153. eq( Math.fround( -10000000000.7), -10000000001. );
  154. }
  155. function testStringMap() {
  156. var h = new haxe.ds.StringMap<Null<Int>>();
  157. h.set("x", -1);
  158. h.set("abcd", 8546);
  159. eq( h.get("x"), -1);
  160. eq( h.get("abcd"), 8546 );
  161. eq( h.get("e"), null );
  162. var k = Lambda.array(h);
  163. k.sort(Reflect.compare);
  164. eq( k.join("#"), "-1#8546" );
  165. var k = Lambda.array( { iterator : h.keys } );
  166. k.sort(Reflect.compare);
  167. eq( k.join("#"), "abcd#x" );
  168. t( h.exists("x") );
  169. t( h.exists("abcd") );
  170. f( h.exists("e") );
  171. h.remove("abcd");
  172. t( h.exists("x") );
  173. f( h.exists("abcd") );
  174. f( h.exists("e") );
  175. eq( h.get("abcd"), null);
  176. h.set("x", null);
  177. t( h.exists("x") );
  178. t( h.remove("x") );
  179. f( h.remove("x") );
  180. }
  181. function testIntMap() {
  182. var h = new haxe.ds.IntMap<Null<Int>>();
  183. h.set(0, -1);
  184. h.set(-4815, 8546);
  185. eq( h.get(0), -1);
  186. eq( h.get(-4815), 8546 );
  187. eq( h.get(456), null );
  188. var k = Lambda.array(h);
  189. k.sort(Reflect.compare);
  190. eq( k.join("#"), "-1#8546" );
  191. var k = Lambda.array( { iterator : h.keys } );
  192. k.sort(Reflect.compare);
  193. eq( k.join("#"), "-4815#0" );
  194. t( h.exists(0) );
  195. t( h.exists(-4815) );
  196. f( h.exists(456) );
  197. h.remove(-4815);
  198. t( h.exists(0) );
  199. f( h.exists(-4815) );
  200. f( h.exists(456) );
  201. eq( h.get( -4815), null);
  202. h.set(65, null);
  203. t( h.exists(65) );
  204. t( h.remove(65) );
  205. f( h.remove(65) );
  206. var h = new haxe.ds.IntMap();
  207. h.set(1, ['a', 'b']);
  208. t( h.exists(1) );
  209. t( h.remove(1) );
  210. f( h.remove(1) );
  211. }
  212. function testObjectKeyword() {
  213. // new is a keyword in Haxe
  214. var l = { "new": "test" };
  215. var prefix = #if as3 "_" #else "" #end;
  216. eq(Reflect.field(l, prefix + "new"), "test");
  217. // const is a keyword on some platforms but not in Haxe
  218. // check that with can still access it normally
  219. var o = { const : 6 }
  220. eq(o.const, 6);
  221. eq(Reflect.field(o, prefix+"const"), 6);
  222. }
  223. function testFormat() {
  224. eq('', "");
  225. eq('$', "$");
  226. eq('$$', "$");
  227. eq('x$*', "x$*");
  228. var x = 5, y = [];
  229. eq('$x', "5");
  230. eq('a$x$', "a5$");
  231. eq('${5}', "5");
  232. eq('${5}${2}', "52");
  233. eq('a${x}b', "a5b");
  234. eq('${x}${y}', "5[]");
  235. }
  236. function testAbstract() {
  237. var a = new MyAbstract(33);
  238. t( Std.is(a, Int) );
  239. eq( a.toInt(), 33 );
  240. var b = a;
  241. a.incr();
  242. eq( a.toInt(), 34 );
  243. eq( b.toInt(), 33 );
  244. }
  245. function testAbstractCast() {
  246. // flash 8 cannot handle Templates
  247. #if !flash8
  248. var s = "Abstract casting ::t::";
  249. // var from
  250. var tpl:unit.MyAbstract.TemplateWrap = s;
  251. t(Std.is(tpl, haxe.Template));
  252. t(Std.is(tpl.get(), haxe.Template));
  253. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  254. //var to
  255. var str:String = tpl;
  256. t(Std.is(str, String));
  257. eq(str, "Abstract casting really works!");
  258. // assign from
  259. var tpl:unit.MyAbstract.TemplateWrap;
  260. tpl = s;
  261. t(Std.is(tpl, haxe.Template));
  262. t(Std.is(tpl.get(), haxe.Template));
  263. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  264. //assign to
  265. var str:String;
  266. str = tpl;
  267. t(Std.is(str, String));
  268. eq(str, "Abstract casting really works!");
  269. // call arg from
  270. function from(tpl:unit.MyAbstract.TemplateWrap) {
  271. eq(tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  272. }
  273. from(s);
  274. // call arg to
  275. function from(s:String) {
  276. eq(s, "Abstract casting really works!");
  277. }
  278. from(tpl);
  279. // object decl from variant
  280. var obj: { tpl:unit.MyAbstract.TemplateWrap } = { tpl:s };
  281. eq(obj.tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  282. // object decl from
  283. var obj: { tpl:unit.MyAbstract.TemplateWrap };
  284. obj = { tpl:s };
  285. eq(obj.tpl.get().execute( { t:"works!" } ), "Abstract casting works!");
  286. // object decl to variant
  287. var obj: { s:String } = { s:tpl };
  288. eq(obj.s, "Abstract casting really works!");
  289. // object decl to
  290. var obj: { s:String };
  291. obj = { s:tpl };
  292. eq(obj.s, "Abstract casting really works!");
  293. // array from
  294. var arr:Array<unit.MyAbstract.TemplateWrap> = [s, "foo"];
  295. eq(arr[0].get().execute( { t:"works!" } ), "Abstract casting works!");
  296. eq(arr[1].get().execute( { } ), "foo");
  297. // array to
  298. var arr:Array<String> = [tpl];
  299. eq(arr[0], "Abstract casting really works!");
  300. #end
  301. }
  302. function testAbstractToAbstractCast() {
  303. var m:unit.MyAbstract.Meter = 122.2;
  304. var km:unit.MyAbstract.Kilometer = m;
  305. feq(km, 0.1222);
  306. }
  307. function testAbstractTypeParameters() {
  308. var hash1:unit.MyAbstract.MyHash<String> = ["k1", "v1", "k2", "v2"];
  309. eq("v1", hash1.get("k1"));
  310. eq("v2", hash1.get("k2"));
  311. var hash1:unit.MyAbstract.MyHash<Int> = [1, 2, 3, 4];
  312. eq(2, hash1.get("_s1"));
  313. eq(4, hash1.get("_s3"));
  314. }
  315. function testAbstractToString() {
  316. var km:unit.MyAbstract.Kilometer = 12.5;
  317. var m:unit.MyAbstract.Meter = 12.5;
  318. eq("12.5km", km);
  319. eq("12.5m", m);
  320. eq("Distance: 12.5km", "Distance: " + km);
  321. eq("Distance: 12.5m", "Distance: " + m);
  322. }
  323. function testAbstractOperatorOverload() {
  324. var v1:unit.MyAbstract.MyVector = new unit.MyAbstract.MyPoint3(1, 1, 1);
  325. var v2:unit.MyAbstract.MyVector = new unit.MyAbstract.MyPoint3(1, 2, 3);
  326. eq("(2,3,4)", v1 + v2);
  327. eq("(2,4,6)", v2 * 2.);
  328. var v1Old = v1;
  329. v1 *= 2.;
  330. eq("(2,2,2)", v1);
  331. eq(v1Old, v1);
  332. var v3 = v1 * 2.;
  333. eq("(4,4,4)", v3);
  334. f(v1 == v3);
  335. var i:unit.MyAbstract.MyInt = 1;
  336. eq(2, i + i);
  337. i = i + i;
  338. eq(2, i);
  339. var r:unit.MyAbstract.MyInt = 5;
  340. eq("aaaaa", r * "a");
  341. eq("aaaaa", "a" * r);
  342. }
  343. }