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

/qooxdoo/framework/source/class/qx/test/Interface.js

https://github.com/Wkasel/qooxdoo
JavaScript | 523 lines | 389 code | 93 blank | 41 comment | 8 complexity | 6f66ec5d3af08134c9f6fcdf86377bd4 MD5 | raw file
  1. /* ************************************************************************
  2. qooxdoo - the new era of web development
  3. http://qooxdoo.org
  4. Copyright:
  5. 2007-2008 1&1 Internet AG, Germany, http://www.1und1.de
  6. License:
  7. LGPL: http://www.gnu.org/licenses/lgpl.html
  8. EPL: http://www.eclipse.org/org/documents/epl-v10.php
  9. See the LICENSE file in the project's top-level directory for details.
  10. Authors:
  11. * Fabian Jakobs (fjakobs)
  12. ************************************************************************ */
  13. /* ************************************************************************
  14. #ignore(qx.AbstractJuhu2)
  15. #ignore(qx.AbstractJuhu1)
  16. #ignore(qx.Complex)
  17. #ignore(qx.ICar)
  18. #ignore(qx.Audi)
  19. ************************************************************************ */
  20. qx.Class.define("qx.test.Interface",
  21. {
  22. extend : qx.dev.unit.TestCase,
  23. members :
  24. {
  25. testInterface : function()
  26. {
  27. qx.Interface.define("qx.ICar",
  28. {
  29. members :
  30. {
  31. startEngine : function() {
  32. return true;
  33. }
  34. },
  35. properties : { color : {} }
  36. });
  37. // test correct implementations
  38. qx.Class.define("qx.Audi",
  39. {
  40. extend : Object,
  41. construct : function() {},
  42. implement : [ qx.ICar ],
  43. members :
  44. {
  45. startEngine : function() {
  46. return "start";
  47. }
  48. },
  49. statics :
  50. {
  51. honk : function() {
  52. return "honk";
  53. }
  54. },
  55. properties : { color : { } }
  56. });
  57. var audi = new qx.Audi("audi");
  58. if (this.isDebugOn())
  59. {
  60. this.assertException(function() {
  61. var i = new qx.ICar();
  62. }, Error);
  63. // nothing defined
  64. this.assertException(function()
  65. {
  66. qx.Class.define("qx.Audi1",
  67. {
  68. extend : Object,
  69. construct : function() {},
  70. implement : [ qx.ICar ]
  71. });
  72. },
  73. Error, new RegExp('Implementation of method .* is missing'));
  74. // members not defined
  75. this.assertException(function()
  76. {
  77. qx.Class.define("qx.Audi2",
  78. {
  79. extend : Object,
  80. construct : function() {},
  81. implement : [ qx.ICar ],
  82. statics :
  83. {
  84. honk : function() {
  85. return "honk";
  86. }
  87. },
  88. properties : { color : { } }
  89. });
  90. },
  91. Error, 'Implementation of method "startEngine" is missing');
  92. // property not defined
  93. this.assertException(function()
  94. {
  95. qx.Class.define("qx.Audi4",
  96. {
  97. extend : Object,
  98. construct : function() {},
  99. implement : [ qx.ICar ],
  100. members :
  101. {
  102. startEngine : function() {
  103. return "start";
  104. }
  105. },
  106. statics :
  107. {
  108. honk : function() {
  109. return "honk";
  110. }
  111. }
  112. });
  113. },
  114. Error, new RegExp("property .* not supported"));
  115. }
  116. },
  117. testAssertions : function()
  118. {
  119. qx.Interface.define("qx.IComplex",
  120. {
  121. members :
  122. {
  123. add : function(a) {
  124. this.assertArgumentsCount(arguments, 1, 1);
  125. this.assertInterface(a.constructor, qx.IComplex);
  126. },
  127. setReal : function(r) {
  128. this.assertArgumentsCount(arguments, 1, 1);
  129. this.assertType(r, "number");
  130. },
  131. abs : function() {
  132. this.assert(arguments[0] == undefined);
  133. }
  134. }
  135. });
  136. qx.Class.define("qx.Complex",
  137. {
  138. extend : qx.core.Object,
  139. implement : qx.IComplex,
  140. construct : function(real, imag)
  141. {
  142. this._real = real;
  143. this._imag = imag;
  144. },
  145. members :
  146. {
  147. add : function(a)
  148. {
  149. this._real += a._real;
  150. this._imag += a._imag;
  151. },
  152. setReal : function(r) {
  153. this._real = r;
  154. },
  155. abs : function() {
  156. return Math.sqrt((this._real * this._real) + (this._imag + this._imag));
  157. },
  158. toString : function() {
  159. return this._real + "+" + this._imag + "i";
  160. }
  161. }
  162. });
  163. var a = new qx.Complex(1, 1);
  164. var b = new qx.Complex(2, -3.4);
  165. // valid usage
  166. a.add(b);
  167. a.setReal(20);
  168. a.abs();
  169. // invalid usage
  170. if (this.isDebugOn())
  171. {
  172. this.assertException(function() {
  173. a.add(b, b);
  174. }, qx.dev.unit.AssertionError, null, "a");
  175. this.assertException(function() {
  176. a.setReal();
  177. }, qx.dev.unit.AssertionError, null, "b");
  178. this.assertException(function() {
  179. a.setReal(1, 2);
  180. }, qx.dev.unit.AssertionError, null, "c");
  181. this.assertException(function() {
  182. a.setReal("Juhu");
  183. }, qx.dev.unit.AssertionError, null, "d");
  184. this.assertException(function() {
  185. a.abs({});
  186. }, qx.dev.unit.AssertionError, null, "e");
  187. this.assertException(function() {
  188. a.add("Juhu");
  189. }, qx.dev.unit.AssertionError, null, "f");
  190. };
  191. },
  192. testProperties : function()
  193. {
  194. qx.Interface.define("qx.IProperties1", {
  195. properties : {
  196. value : {}
  197. }
  198. });
  199. qx.Class.define("qx.Properties1",
  200. {
  201. extend : qx.core.Object,
  202. implement : [qx.IProperties1],
  203. properties :
  204. {
  205. value : { check : "Integer"}
  206. }
  207. });
  208. if (this.isDebugOn())
  209. {
  210. this.assertException(function() {
  211. qx.Class.define("qx.Properties2",
  212. {
  213. extend : qx.core.Object,
  214. implement : [qx.IProperties1],
  215. members :
  216. {
  217. getValue : function() {},
  218. setValue : function(value) {}
  219. }
  220. });
  221. });
  222. };
  223. qx.Interface.define("qx.IProperties2",
  224. {
  225. members :
  226. {
  227. getValue : function() {},
  228. setValue : function(value) {}
  229. }
  230. });
  231. qx.Class.define("qx.Properties3",
  232. {
  233. extend : qx.core.Object,
  234. implement : [qx.IProperties2],
  235. properties :
  236. {
  237. value : { check : "Integer"}
  238. }
  239. });
  240. qx.Class.define("qx.Properties4",
  241. {
  242. extend : qx.core.Object,
  243. implement : [qx.IProperties2],
  244. members :
  245. {
  246. getValue : function() {},
  247. setValue : function(value) {}
  248. }
  249. })
  250. },
  251. testEvents : function()
  252. {
  253. qx.Interface.define("qx.IEvents1",
  254. {
  255. events : {
  256. "change" : "qx.event.type.Event"
  257. }
  258. });
  259. qx.Class.define("qx.Event1",
  260. {
  261. extend : qx.core.Object,
  262. implement : [qx.IEvents1],
  263. events : {
  264. change : "qx.event.type.Event"
  265. }
  266. })
  267. if (this.isDebugOn())
  268. {
  269. this.assertException(function() {
  270. qx.Class.define("qx.Event2",
  271. {
  272. extend : qx.core.Object,
  273. implement : [qx.IEvents1]
  274. })
  275. });
  276. };
  277. },
  278. testIncludes : function()
  279. {
  280. qx.Interface.define("qx.IMember",
  281. {
  282. members :
  283. {
  284. sayJuhu : function() {
  285. return true;
  286. }
  287. }
  288. });
  289. qx.Interface.define("qx.IProperties",
  290. {
  291. properties :
  292. {
  293. "color" : {},
  294. "name" : {}
  295. }
  296. });
  297. qx.Interface.define("qx.IAll", { extend : [ qx.IMember, qx.IProperties ] });
  298. qx.Interface.define("qx.IOther",
  299. {
  300. members :
  301. {
  302. bar : function() {
  303. return true;
  304. }
  305. }
  306. });
  307. var classDef =
  308. {
  309. extend : Object,
  310. implement : qx.IAll,
  311. members :
  312. {
  313. sayJuhu : function() {}
  314. },
  315. statics :
  316. {
  317. sayHello : function() {
  318. return true;
  319. }
  320. },
  321. properties :
  322. {
  323. "color" : { },
  324. "name" : { }
  325. }
  326. };
  327. // all implemented
  328. var def = qx.lang.Object.clone(classDef);
  329. qx.Class.define("qx.Implement1", def);
  330. this.assertTrue(qx.Class.implementsInterface(qx.Implement1, qx.IAll), "implements IAll");
  331. this.assertTrue(qx.Class.implementsInterface(qx.Implement1, qx.IMember), "implements IMember");
  332. this.assertTrue(qx.Class.implementsInterface(qx.Implement1, qx.IProperties), "implements IProperties");
  333. this.assertFalse(qx.Class.implementsInterface(qx.Implement1, qx.IOther), "not implements IOther");
  334. // no members
  335. var def = qx.lang.Object.clone(classDef);
  336. delete (def.members);
  337. if (this.isDebugOn())
  338. {
  339. this.assertException(function() {
  340. qx.Class.define("qx.Implement2", def);
  341. }, Error, "Implementation of method", "No members defined.");
  342. };
  343. // no properties
  344. var def = qx.lang.Object.clone(classDef);
  345. delete (def.properties);
  346. if (this.isDebugOn())
  347. {
  348. this.assertException(function() {
  349. qx.Class.define("qx.Implement4", def);
  350. }, Error, new RegExp("property .* is not supported"), "No properties defined.");
  351. };
  352. },
  353. /**
  354. * abstract classes may define an interface and implement it only partially
  355. * sub classes must implement the missing methods
  356. */
  357. testAbstractClass : function()
  358. {
  359. qx.Interface.define("qx.IJuhu",
  360. {
  361. members :
  362. {
  363. sayJuhu : function() {},
  364. sayKinners : function() {}
  365. }
  366. });
  367. // should not raise an exception
  368. qx.Class.define("qx.AbstractJuhu1", {
  369. extend : qx.core.Object,
  370. implement : qx.IJuhu,
  371. type : "abstract"
  372. });
  373. // should not raise an exception
  374. qx.Class.define("qx.AbstractJuhu2", {
  375. extend : qx.core.Object,
  376. implement : qx.IJuhu,
  377. type : "abstract",
  378. members :
  379. {
  380. sayJuhu : function() { return "Juhu"; }
  381. }
  382. });
  383. // should raise an exception
  384. if (this.isDebugOn())
  385. {
  386. this.assertException(function() {
  387. qx.Class.define("qx.Juhu1", {
  388. extend : qx.AbstractJuhu1,
  389. members :
  390. {
  391. sayJuhu : function() { return "Juhu"; }
  392. }
  393. });
  394. }, Error, '.*Implementation of method "sayKinners" is missing in class "qx.Juhu1" required by interface "qx.IJuhu"');
  395. };
  396. qx.Class.define("qx.Juhu1", {
  397. extend : qx.AbstractJuhu2,
  398. members :
  399. {
  400. sayKinners : function() { return "Kinners"; }
  401. }
  402. });
  403. },
  404. testGeneratedIsMethods: function() {
  405. qx.Interface.define("qx.IIs",
  406. {
  407. members :
  408. {
  409. isProp : function() {}
  410. }
  411. });
  412. qx.Class.define("qx.Is", {
  413. extend : qx.core.Object,
  414. implement : qx.IIs,
  415. properties : {
  416. prop : {
  417. check : "Boolean",
  418. init : true
  419. }
  420. }
  421. });
  422. }
  423. }
  424. });