connection_db_test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * @license
  3. * Blockly Tests
  4. *
  5. * Copyright 2015 Google Inc.
  6. * https://developers.google.com/blockly/
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. 'use strict';
  21. function verify_DB_(msg, expected, db) {
  22. var equal = (expected.length == db.length);
  23. if (equal) {
  24. for (var i = 0; i < expected.length; i++) {
  25. if (expected[i] != db[i]) {
  26. equal = false;
  27. break;
  28. }
  29. }
  30. }
  31. if (equal) {
  32. assertTrue(msg, true);
  33. } else {
  34. assertEquals(msg, expected, db);
  35. }
  36. }
  37. function test_DB_addConnection() {
  38. var db = new Blockly.ConnectionDB();
  39. var o2 = {y_: 2, sourceBlock_: {},
  40. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  41. db.addConnection(o2);
  42. verify_DB_('Adding connection #2', [o2], db);
  43. var o4 = {y_: 4, sourceBlock_: {},
  44. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  45. db.addConnection(o4);
  46. verify_DB_('Adding connection #4', [o2, o4], db);
  47. var o1 = {y_: 1, sourceBlock_: {},
  48. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  49. db.addConnection(o1);
  50. verify_DB_('Adding connection #1', [o1, o2, o4], db);
  51. var o3a = {y_: 3, sourceBlock_: {},
  52. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  53. db.addConnection(o3a);
  54. verify_DB_('Adding connection #3a', [o1, o2, o3a, o4], db);
  55. var o3b = {y_: 3, sourceBlock_: {},
  56. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  57. db.addConnection(o3b);
  58. verify_DB_('Adding connection #3b', [o1, o2, o3b, o3a, o4], db);
  59. }
  60. function test_DB_removeConnection() {
  61. var db = new Blockly.ConnectionDB();
  62. var o1 = {y_: 1, sourceBlock_: {},
  63. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  64. var o2 = {y_: 2, sourceBlock_: {},
  65. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  66. var o3a = {y_: 3, sourceBlock_: {},
  67. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  68. var o3b = {y_: 3, sourceBlock_: {},
  69. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  70. var o3c = {y_: 3, sourceBlock_: {},
  71. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  72. var o4 = {y_: 4, sourceBlock_: {},
  73. getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
  74. db.addConnection(o1);
  75. db.addConnection(o2);
  76. db.addConnection(o3c);
  77. db.addConnection(o3b);
  78. db.addConnection(o3a);
  79. db.addConnection(o4);
  80. verify_DB_('Adding connections 1-4', [o1, o2, o3a, o3b, o3c, o4], db);
  81. db.removeConnection_(o2);
  82. verify_DB_('Removing connection #2', [o1, o3a, o3b, o3c, o4], db);
  83. db.removeConnection_(o4);
  84. verify_DB_('Removing connection #4', [o1, o3a, o3b, o3c], db);
  85. db.removeConnection_(o1);
  86. verify_DB_('Removing connection #1', [o3a, o3b, o3c], db);
  87. db.removeConnection_(o3a);
  88. verify_DB_('Removing connection #3a', [o3b, o3c], db);
  89. db.removeConnection_(o3c);
  90. verify_DB_('Removing connection #3c', [o3b], db);
  91. db.removeConnection_(o3b);
  92. verify_DB_('Removing connection #3b', [], db);
  93. }
  94. function test_DB_getNeighbours() {
  95. var db = new Blockly.ConnectionDB();
  96. // Search an empty list.
  97. assertEquals(helper_getNeighbours(db,
  98. 10 /* x */, 10 /* y */, 100 /* radius */).length, 0);
  99. // Set up some connections.
  100. for (var i = 0; i < 10; i++) {
  101. db.addConnection(helper_createConnection(0, i,
  102. Blockly.PREVIOUS_STATEMENT, null, true));
  103. }
  104. // Test block belongs at beginning.
  105. var result = helper_getNeighbours(db, 0, 0, 4);
  106. assertEquals(5, result.length);
  107. for (i = 0; i < result.length; i++) {
  108. assertNotEquals(result.indexOf(db[i]), -1); // contains
  109. }
  110. // Test block belongs at middle.
  111. result = helper_getNeighbours(db, 0, 4, 2);
  112. assertEquals(5, result.length);
  113. for (i = 0; i < result.length; i++) {
  114. assertNotEquals(result.indexOf(db[i + 2]), -1); // contains
  115. }
  116. // Test block belongs at end.
  117. result = helper_getNeighbours(db, 0, 9, 4);
  118. assertEquals(5, result.length);
  119. for (i = 0; i < result.length; i++) {
  120. assertNotEquals(result.indexOf(db[i + 5]), -1); // contains
  121. }
  122. // Test block has no neighbours due to being out of range in the x direction.
  123. result = helper_getNeighbours(db, 10, 9, 4);
  124. assertEquals(result.length, 0);
  125. // Test block has no neighbours due to being out of range in the y direction.
  126. result = helper_getNeighbours(db, 0, 19, 4);
  127. assertEquals(result.length, 0);
  128. // Test block has no neighbours due to being out of range diagonally.
  129. result = helper_getNeighbours(db, -2, -2, 2);
  130. assertEquals(result.length, 0);
  131. }
  132. function test_DB_findPositionForConnection() {
  133. var db = new Blockly.ConnectionDB();
  134. db.addConnection(helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT,
  135. null, true));
  136. db.addConnection(helper_createConnection(0, 1, Blockly.PREVIOUS_STATEMENT,
  137. null, true));
  138. db.addConnection(helper_createConnection(0, 2, Blockly.PREVIOUS_STATEMENT,
  139. null, true));
  140. db.addConnection(helper_createConnection(0, 4, Blockly.PREVIOUS_STATEMENT,
  141. null, true));
  142. db.addConnection(helper_createConnection(0, 5, Blockly.PREVIOUS_STATEMENT,
  143. null, true));
  144. assertEquals(5, db.length);
  145. var conn = helper_createConnection(0, 3, Blockly.PREVIOUS_STATEMENT, null,
  146. true);
  147. assertEquals(3, db.findPositionForConnection_(conn));
  148. }
  149. function test_DB_findConnection() {
  150. var db = new Blockly.ConnectionDB();
  151. for (var i = 0; i < 10; i++) {
  152. db.addConnection(helper_createConnection(i, 0,
  153. Blockly.PREVIOUS_STATEMENT, null, true));
  154. db.addConnection(helper_createConnection(0, i,
  155. Blockly.PREVIOUS_STATEMENT, null, true));
  156. }
  157. var conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null,
  158. true);
  159. db.addConnection(conn);
  160. assertEquals(conn, db[db.findConnection(conn)]);
  161. conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null, true);
  162. assertEquals(-1, db.findConnection(conn));
  163. }
  164. function test_DB_ordering() {
  165. var db = new Blockly.ConnectionDB();
  166. for (var i = 0; i < 10; i++) {
  167. db.addConnection(helper_createConnection(0, 9 - i,
  168. Blockly.PREVIOUS_STATEMENT), null, true);
  169. }
  170. for (i = 0; i < 10; i++) {
  171. assertEquals(i, db[i].y_);
  172. }
  173. // quasi-random
  174. var xCoords = [-29, -47, -77, 2, 43, 34, -59, -52, -90, -36, -91, 38, 87, -20,
  175. 60, 4, -57, 65, -37, -81, 57, 58, -96, 1, 67, -79, 34, 93, -90, -99, -62,
  176. 4, 11, -36, -51, -72, 3, -50, -24, -45, -92, -38, 37, 24, -47, -73, 79,
  177. -20, 99, 43, -10, -87, 19, 35, -62, -36, 49, 86, -24, -47, -89, 33, -44,
  178. 25, -73, -91, 85, 6, 0, 89, -94, 36, -35, 84, -9, 96, -21, 52, 10, -95, 7,
  179. -67, -70, 62, 9, -40, -95, -9, -94, 55, 57, -96, 55, 8, -48, -57, -87, 81,
  180. 23, 65];
  181. var yCoords = [-81, 82, 5, 47, 30, 57, -12, 28, 38, 92, -25, -20, 23, -51, 73,
  182. -90, 8, 28, -51, -15, 81, -60, -6, -16, 77, -62, -42, -24, 35, 95, -46,
  183. -7, 61, -16, 14, 91, 57, -38, 27, -39, 92, 47, -98, 11, -33, -72, 64, 38,
  184. -64, -88, -35, -59, -76, -94, 45, -25, -100, -95, 63, -97, 45, 98, 99, 34,
  185. 27, 52, -18, -45, 66, -32, -38, 70, -73, -23, 5, -2, -13, -9, 48, 74, -97,
  186. -11, 35, -79, -16, -77, 83, -57, -53, 35, -44, 100, -27, -15, 5, 39, 33,
  187. -19, -20, -95];
  188. for (i = 0; i < xCoords.length; i++) {
  189. db.addConnection(helper_createConnection(xCoords[i], yCoords[i],
  190. Blockly.PREVIOUS_STATEMENT), null, true);
  191. }
  192. for (i = 1; i < xCoords.length; i++) {
  193. assertTrue(db[i].y_ >= db[i - 1].y_);
  194. }
  195. }
  196. function test_SearchForClosest() {
  197. var db = new Blockly.ConnectionDB();
  198. var sharedWorkspace = {id: "Shared workspace"};
  199. // Search an empty list.
  200. assertEquals(null, helper_searchDB(db, 10 /* x */, 10 /* y */,
  201. 100 /* radius */));
  202. db.addConnection(helper_createConnection(100, 0, Blockly.PREVIOUS_STATEMENT,
  203. sharedWorkspace, true));
  204. assertEquals(null, helper_searchDB(db, 0, 0, 5, sharedWorkspace));
  205. db = new Blockly.ConnectionDB();
  206. for (var i = 0; i < 10; i++) {
  207. var tempConn = helper_createConnection(0, i, Blockly.PREVIOUS_STATEMENT,
  208. sharedWorkspace, true);
  209. tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
  210. db.addConnection(tempConn);
  211. }
  212. // Should be at 0, 9.
  213. var last = db[db.length - 1];
  214. // Correct connection is last in db; many connections in radius.
  215. assertEquals(last, helper_searchDB(db, 0, 10, 15, sharedWorkspace));
  216. // Nothing nearby.
  217. assertEquals(null, helper_searchDB(db, 100, 100, 3, sharedWorkspace));
  218. // First in db, exact match.
  219. assertEquals(db[0], helper_searchDB(db, 0, 0, 0, sharedWorkspace));
  220. tempConn = helper_createConnection(6, 6, Blockly.PREVIOUS_STATEMENT,
  221. sharedWorkspace, true);
  222. tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
  223. db.addConnection(tempConn);
  224. tempConn = helper_createConnection(5, 5, Blockly.PREVIOUS_STATEMENT,
  225. sharedWorkspace, true);
  226. tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
  227. db.addConnection(tempConn);
  228. var result = helper_searchDB(db, 4, 6, 3, sharedWorkspace);
  229. assertEquals(5, result.x_);
  230. assertEquals(5, result.y_);
  231. }
  232. function helper_getNeighbours(db, x, y, radius) {
  233. return db.getNeighbours(helper_createConnection(x, y, Blockly.NEXT_STATEMENT,
  234. null, true),
  235. radius);
  236. }
  237. function helper_searchDB(db, x, y, radius, shared_workspace) {
  238. var tempConn = helper_createConnection(x, y,
  239. Blockly.NEXT_STATEMENT, shared_workspace, true);
  240. tempConn.sourceBlock_ = helper_makeSourceBlock(shared_workspace);
  241. var closest = db.searchForClosest(tempConn, radius, {x: 0, y: 0});
  242. return closest.connection;
  243. }
  244. function helper_makeSourceBlock(sharedWorkspace) {
  245. return {workspace: sharedWorkspace,
  246. parentBlock_: null,
  247. getParent: function() { return null; },
  248. movable_: true,
  249. isMovable: function() { return true; },
  250. isShadow: function() { return false; }
  251. };
  252. }
  253. function helper_createConnection(x, y, type, opt_shared_workspace,
  254. opt_rendered) {
  255. var workspace = opt_shared_workspace ? opt_shared_workspace : {};
  256. if (opt_rendered) {
  257. var conn = new Blockly.RenderedConnection({workspace: workspace}, type);
  258. } else {
  259. var conn = new Blockly.Connection({workspace: workspace}, type);
  260. }
  261. conn.x_ = x;
  262. conn.y_ = y;
  263. return conn;
  264. }