Surface.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /* global expect, Ext */
  2. topSuite("Ext.draw.Surface", function() {
  3. describe('add', function () {
  4. it("should not add the same sprite to the surface twice", function () {
  5. var surface = new Ext.draw.Surface({}),
  6. sprite = new Ext.draw.sprite.Rect({});
  7. surface.add(sprite);
  8. surface.add(sprite);
  9. expect(surface.getItems().length).toEqual(1);
  10. surface.removeAll(true);
  11. expect(surface.getItems().length).toEqual(0);
  12. surface.add([sprite, sprite]);
  13. expect(surface.getItems().length).toEqual(0);
  14. surface.destroy();
  15. });
  16. it("should remove the sprite from the old surface", function () {
  17. var surface1 = new Ext.draw.Surface({}),
  18. surface2 = new Ext.draw.Surface({}),
  19. sprite = new Ext.draw.sprite.Rect({});
  20. surface1.add(sprite);
  21. surface2.add(sprite);
  22. expect(surface1.getItems().length).toEqual(0);
  23. expect(surface2.getItems().length).toEqual(1);
  24. expect(surface2.get(0)).toBe(sprite);
  25. Ext.destroy(sprite, surface1, surface2);
  26. });
  27. it("should set the sprite's 'parent' and 'surface' configs to itself", function () {
  28. var sprite = new Ext.draw.sprite.Rect(),
  29. surface = new Ext.draw.Surface();
  30. surface.add(sprite);
  31. expect(sprite.getParent()).toBe(surface);
  32. expect(sprite.getSurface()).toBe(surface);
  33. surface.destroy();
  34. });
  35. });
  36. describe('get', function () {
  37. var surface, result;
  38. beforeEach(function () {
  39. surface = new Ext.draw.Surface({
  40. items: [
  41. {
  42. type: 'rect',
  43. id: 'sprite1'
  44. },
  45. {
  46. type: 'text',
  47. id: 'sprite2'
  48. }
  49. ]
  50. });
  51. });
  52. afterEach(function () {
  53. surface.destroy();
  54. });
  55. it("should be able to get a sprite by id", function () {
  56. result = surface.get('sprite1');
  57. expect(result.isSprite).toBe(true);
  58. expect(result.type).toBe('rect');
  59. result = surface.get('sprite2');
  60. expect(result.isSprite).toBe(true);
  61. expect(result.type).toBe('text');
  62. });
  63. it("should be able to get a sprite by index", function () {
  64. result = surface.get(0);
  65. expect(result.isSprite).toBe(true);
  66. expect(result.type).toBe('rect');
  67. result = surface.get(1);
  68. expect(result.isSprite).toBe(true);
  69. expect(result.type).toBe('text');
  70. });
  71. });
  72. describe('remove', function () {
  73. it("should be able to remove the sprite (instance or id), should return removed sprite", function () {
  74. var givenId = 'testing',
  75. sprite = new Ext.draw.sprite.Rect({}),
  76. spriteId = new Ext.draw.sprite.Text({id: givenId}),
  77. surface = new Ext.draw.Surface({}),
  78. result, id;
  79. surface.add(sprite, spriteId);
  80. expect(surface.getItems().length).toBe(2);
  81. id = sprite.getId();
  82. result = surface.remove(sprite);
  83. expect(result).toEqual(sprite);
  84. expect(sprite.destroyed).toBe(false);
  85. expect(surface.getItems().length).toBe(1);
  86. expect(surface.get(id)).toBe(undefined);
  87. result = surface.remove(givenId);
  88. expect(result).toEqual(spriteId);
  89. expect(spriteId.destroyed).toBe(false);
  90. expect(surface.getItems().length).toBe(0);
  91. expect(surface.get(givenId)).toBe(undefined);
  92. surface.destroy();
  93. sprite.destroy();
  94. spriteId.destroy();
  95. });
  96. it("should be able to destroy the sprite (instance or id) in the process, should return destroyed sprite", function () {
  97. var sprite = new Ext.draw.sprite.Rect({}),
  98. spriteId = new Ext.draw.sprite.Text({id: 'testing'}),
  99. surface = new Ext.draw.Surface({}),
  100. result;
  101. surface.add(sprite, spriteId);
  102. expect(surface.getItems().length).toBe(2);
  103. result = surface.remove(sprite, true);
  104. expect(result).toEqual(sprite);
  105. expect(result.destroyed).toBe(true);
  106. expect(surface.getItems().length).toBe(1);
  107. result = surface.remove('testing', true);
  108. expect(result).toEqual(spriteId);
  109. expect(result.destroyed).toBe(true);
  110. expect(surface.getItems().length).toBe(0);
  111. surface.destroy();
  112. });
  113. it("should return null if not given a sprite", function () {
  114. var surface = new Ext.draw.Surface({});
  115. function isNull(value) {
  116. return (null === surface.remove(value)) && (null === surface.remove(value, true));
  117. }
  118. expect(isNull(0)).toBe(true);
  119. expect(isNull(5)).toBe(true);
  120. expect(isNull(true)).toBe(true);
  121. expect(isNull(false)).toBe(true);
  122. expect(isNull(undefined)).toBe(true);
  123. expect(isNull(null)).toBe(true);
  124. expect(isNull('hello')).toBe(true);
  125. expect(isNull('')).toBe(true);
  126. expect(isNull({})).toBe(true);
  127. expect(isNull([])).toBe(true);
  128. surface.destroy();
  129. });
  130. // This spec is only "to do" in modern browsers
  131. TODO(Object.setPrototypeOf && jasmine.CLEAR_PROTOTYPE, 'Make it work with prototype clearing').
  132. it("if passed an already destroyed sprite, should return it without doing anything", function () {
  133. var deadSprite = new Ext.draw.sprite.Rect({}),
  134. surface = new Ext.draw.Surface({}),
  135. result;
  136. deadSprite.destroy();
  137. result = surface.remove(deadSprite);
  138. expect(result).toBe(deadSprite);
  139. result = surface.remove(deadSprite, true);
  140. expect(result).toBe(deadSprite);
  141. surface.destroy();
  142. });
  143. it("should be able to destroy (but not remove!) a sprite that belongs to another or no surface", function () {
  144. var surface1 = new Ext.draw.Surface({}),
  145. surface2 = new Ext.draw.Surface({}),
  146. sprite1 = new Ext.draw.sprite.Rect({}),
  147. sprite = new Ext.draw.sprite.Text({}),
  148. result;
  149. surface1.add(sprite1);
  150. result = surface2.remove(sprite1);
  151. expect(result).toBe(sprite1);
  152. expect(surface1.getItems()[0]).toEqual(sprite1);
  153. result = surface2.remove(sprite1, true);
  154. expect(result).toEqual(sprite1);
  155. expect(result.destroyed).toBe(true);
  156. expect(surface1.getItems().length).toBe(0);
  157. result = surface2.remove(sprite);
  158. expect(result).toEqual(sprite);
  159. expect(result.destroyed).toBe(false);
  160. result = surface2.remove(sprite, true);
  161. expect(result).toEqual(sprite);
  162. expect(result.destroyed).toBe(true);
  163. surface1.destroy();
  164. surface2.destroy();
  165. });
  166. });
  167. describe('destroy', function () {
  168. it("should fire the 'destroy' event", function () {
  169. var surface = new Ext.draw.Surface,
  170. isFired;
  171. surface.on('destroy', function () {
  172. isFired = true;
  173. });
  174. surface.destroy();
  175. expect(isFired).toBe(true);
  176. });
  177. });
  178. describe('waitFor', function () {
  179. var s1, s2, s3, s4;
  180. beforeEach(function () {
  181. s1 = new Ext.draw.Surface();
  182. s2 = new Ext.draw.Surface();
  183. s3 = new Ext.draw.Surface();
  184. s4 = new Ext.draw.Surface();
  185. });
  186. afterEach(function () {
  187. Ext.destroy(s1, s2, s3, s4);
  188. });
  189. it("should add the given surface to a list of current surface predecessors only once", function () {
  190. s1.waitFor(s2);
  191. expect(s1.predecessors.length).toBe(1);
  192. expect(s1.predecessors[0]).toEqual(s2);
  193. });
  194. it("should only increase own dirty predecessor counter if the given surface is dirty", function () {
  195. s1.waitFor(s2);
  196. expect(s1.dirtyPredecessorCount).toBe(0);
  197. s3.setDirty(true);
  198. s2.waitFor(s3);
  199. expect(s2.dirtyPredecessorCount).toBe(1);
  200. });
  201. it("should be able to wait for multiple surfaces", function () {
  202. s1.waitFor(s2);
  203. s1.waitFor(s3);
  204. s1.waitFor(s4);
  205. expect(s1.predecessors.length).toBe(3);
  206. });
  207. });
  208. describe("'dirty' config", function () {
  209. var s1, s2, s3, s4, s5;
  210. beforeEach(function () {
  211. s1 = new Ext.draw.Surface();
  212. s2 = new Ext.draw.Surface();
  213. s3 = new Ext.draw.Surface();
  214. s4 = new Ext.draw.Surface();
  215. s5 = new Ext.draw.Surface();
  216. });
  217. afterEach(function () {
  218. Ext.destroy(s1, s2, s3, s4, s5);
  219. });
  220. it("should not be dirty upon construction", function () {
  221. expect(s1.getDirty()).toBe(false);
  222. });
  223. it("should be dirty when items are removed but surface is not destroyed", function () {
  224. var sprite = new Ext.draw.sprite.Rect({});
  225. s1.add(sprite);
  226. s1.removeAll();
  227. expect(s1.getDirty()).toBe(true);
  228. s1.destroy();
  229. });
  230. it("should not be dirty when surface is destroyed", function () {
  231. var sprite = new Ext.draw.sprite.Rect({});
  232. s1.add(sprite);
  233. s1.setDirty(false);
  234. s1.destroy();
  235. expect(s1._dirty).toBe(false);
  236. });
  237. it("should increment dirtyPredecessorCount of all successors (not just immediate) when set to true", function () {
  238. s3.waitFor(s2);
  239. s5.waitFor(s4);
  240. s2.waitFor(s1);
  241. s4.waitFor(s1);
  242. // Order of rendering: s1 --> s2 --> s3
  243. // |
  244. // --> s4 --> s5
  245. s1.setDirty(true);
  246. expect(s2.dirtyPredecessorCount).toBe(1);
  247. expect(s3.dirtyPredecessorCount).toBe(1);
  248. expect(s4.dirtyPredecessorCount).toBe(1);
  249. expect(s5.dirtyPredecessorCount).toBe(1);
  250. });
  251. it("should decrement dirtyPredecessorCount of all immediate successors when set to false", function () {
  252. s3.waitFor(s2);
  253. s5.waitFor(s4);
  254. s2.waitFor(s1);
  255. s4.waitFor(s1);
  256. // Order of rendering: s1 --> s2 --> s3
  257. // |
  258. // --> s4 --> s5
  259. s1.setDirty(true);
  260. s1.setDirty(false);
  261. expect(s2.dirtyPredecessorCount).toBe(0);
  262. expect(s4.dirtyPredecessorCount).toBe(0);
  263. expect(s3.dirtyPredecessorCount).toBe(1);
  264. expect(s5.dirtyPredecessorCount).toBe(1);
  265. });
  266. it("should not affect dirtyPredecessorCount of successors if value hasn't changed", function () {
  267. s3.waitFor(s2);
  268. s5.waitFor(s4);
  269. s2.waitFor(s1);
  270. s4.waitFor(s1);
  271. // Order of rendering: s1 --> s2 --> s3
  272. // |
  273. // --> s4 --> s5
  274. s1.setDirty(false); // noop
  275. expect(s2.dirtyPredecessorCount).toBe(0);
  276. expect(s3.dirtyPredecessorCount).toBe(0);
  277. expect(s4.dirtyPredecessorCount).toBe(0);
  278. expect(s5.dirtyPredecessorCount).toBe(0);
  279. s1.setDirty(true); // increments dirtyPredecessorCount of all successors
  280. s1.setDirty(true); // noop
  281. expect(s2.dirtyPredecessorCount).toBe(1);
  282. expect(s3.dirtyPredecessorCount).toBe(1);
  283. expect(s4.dirtyPredecessorCount).toBe(1);
  284. expect(s5.dirtyPredecessorCount).toBe(1);
  285. });
  286. it("should make dirtyPredecessorCount reflect the actual number of immediate dirty predecessors", function () {
  287. s1.waitFor(s2);
  288. s1.waitFor(s3);
  289. s1.waitFor(s4);
  290. s2.setDirty(true);
  291. s3.setDirty(true);
  292. s4.setDirty(true);
  293. expect(s1.dirtyPredecessorCount).toBe(3);
  294. s3.setDirty(false);
  295. expect(s1.dirtyPredecessorCount).toBe(2);
  296. });
  297. });
  298. });