ManhattanLayoutSpec.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. import {
  2. connectRectangles,
  3. connectPoints,
  4. repairConnection
  5. } from 'lib/layout/ManhattanLayout';
  6. function point(x, y) {
  7. return { x: x, y: y };
  8. }
  9. function rect(x, y, width, height) {
  10. return { x: x, y: y, width: width, height: height };
  11. }
  12. function expectConnection(connection, expected) {
  13. var len = Math.max(connection.length, expected.length);
  14. for (var i = 0; i < len; i++) {
  15. expect(connection[i]).to.eql(expected[i]);
  16. }
  17. }
  18. function expectConnectionWaypoints(a, b, directions, waypoints) {
  19. return function() {
  20. var connection = connectPoints(a, b, directions);
  21. // expect
  22. expectConnection(connection, waypoints);
  23. };
  24. }
  25. describe('layout/ManhattanLayout', function() {
  26. describe('#connectPoints', function() {
  27. var a = point(100, 100),
  28. b = point(200, 200);
  29. /**
  30. * x----x
  31. * |
  32. * |
  33. * x
  34. */
  35. describe('manhattan connection with 3 waypoints', function() {
  36. var waypoints = [ a, point(200, 100), b ];
  37. it('h:v', expectConnectionWaypoints(a, b, 'h:v', waypoints));
  38. it('r:v', expectConnectionWaypoints(a, b, 'r:v', waypoints));
  39. it('r:t', expectConnectionWaypoints(a, b, 'r:t', waypoints));
  40. it('h:t', expectConnectionWaypoints(a, b, 'h:t', waypoints));
  41. });
  42. /**
  43. * x
  44. * |
  45. * |
  46. * x----x
  47. */
  48. describe('manhattan connection with 3 waypoints', function() {
  49. var waypoints = [ a, point(100, 200), b ];
  50. it('v:h', expectConnectionWaypoints(a, b, 'v:h', waypoints));
  51. it('b:h', expectConnectionWaypoints(a, b, 'b:h', waypoints));
  52. it('b:l', expectConnectionWaypoints(a, b, 'b:l', waypoints));
  53. it('v:l', expectConnectionWaypoints(a, b, 'v:l', waypoints));
  54. });
  55. /**
  56. * x--x
  57. * |
  58. * |
  59. * x--x
  60. */
  61. describe('manhattan connection with 4 waypoints', function() {
  62. var waypoints = [ a, point(150, 100), point(150, 200), b ];
  63. it('h:h', expectConnectionWaypoints(a, b, 'h:h', waypoints));
  64. it('r:h', expectConnectionWaypoints(a, b, 'r:h', waypoints));
  65. it('r:l', expectConnectionWaypoints(a, b, 'r:l', waypoints));
  66. it('h:l', expectConnectionWaypoints(a, b, 'h:l', waypoints));
  67. });
  68. /**
  69. * x----x
  70. * |
  71. * |
  72. * x-x
  73. */
  74. describe('manhattan connection with 4 waypoints', function() {
  75. var waypoints = [ a, point(220, 100), point(220, 200), b ];
  76. it('h:r', expectConnectionWaypoints(a, b, 'h:r', waypoints));
  77. it('r:r', expectConnectionWaypoints(a, b, 'r:r', waypoints));
  78. });
  79. /**
  80. * x-x
  81. * |
  82. * |
  83. * x----x
  84. */
  85. describe('manhattan connection with 4 waypoints', function() {
  86. var waypoints = [ a, point(80, 100), point(80, 200), b ];
  87. it('l:h', expectConnectionWaypoints(a, b, 'l:h', waypoints));
  88. it('l:l', expectConnectionWaypoints(a, b, 'l:l', waypoints));
  89. });
  90. /**
  91. * x--x
  92. * | |
  93. * x |
  94. * |
  95. * x--x
  96. */
  97. describe('manhattan connection with 5 waypoints', function() {
  98. var waypoints = [ a, point(100, 80), point(150, 80), point(150, 200), b ];
  99. it('t:h', expectConnectionWaypoints(a, b, 't:h', waypoints));
  100. it('t:l', expectConnectionWaypoints(a, b, 't:l', waypoints));
  101. });
  102. /**
  103. * x--x
  104. * |
  105. * | x
  106. * | |
  107. * x--x
  108. */
  109. describe('manhattan connection with 5 waypoints', function() {
  110. var waypoints = [ a, point(150, 100), point(150, 220), point(200, 220), b ];
  111. it('h:b', expectConnectionWaypoints(a, b, 'h:b', waypoints));
  112. it('r:b', expectConnectionWaypoints(a, b, 'r:b', waypoints));
  113. });
  114. /**
  115. * x-x
  116. * |
  117. * x----x
  118. * |
  119. * x-x
  120. */
  121. describe('manhattan connection with 6 waypoints', function() {
  122. var waypoints = [ a, point(80, 100), point(80, 150), point(220, 150), point(220, 200), b ];
  123. it('l:r', expectConnectionWaypoints(a, b, 'l:r', waypoints));
  124. });
  125. /**
  126. * x--x
  127. * | |
  128. * x | x
  129. * | |
  130. * x--x
  131. */
  132. describe('manhattan connection with 6 waypoints', function() {
  133. var waypoints = [ a, point(100, 80), point(150, 80), point(150, 220), point(200, 220), b ];
  134. it('t:b', expectConnectionWaypoints(a, b, 't:b', waypoints));
  135. });
  136. describe('misc', function() {
  137. it('should not layout straight connection (h)', function() {
  138. // given
  139. var p0 = point(100, 100),
  140. p1 = point(200, 100);
  141. // when
  142. var connection = connectPoints(p0, p1);
  143. // then
  144. expectConnection(connection, [ p0, p1 ]);
  145. });
  146. it('should not layout straight connection (v)', function() {
  147. // given
  148. var p0 = point(100, 100),
  149. p1 = point(200, 100);
  150. // when
  151. var connection = connectPoints(p0, p1);
  152. // then
  153. expectConnection(connection, [ p0, p1 ]);
  154. });
  155. it('should reverse manhattan layout', function() {
  156. // given
  157. var p0 = point(200, 200),
  158. p1 = point(100, 100);
  159. // when
  160. var connection = connectPoints(p0, p1, 'v:v');
  161. // then
  162. expectConnection(connection, [ p0, point(200, 150), point(100, 150), p1]);
  163. });
  164. });
  165. describe('error handling', function() {
  166. it('should throw error on unknown directions', function() {
  167. expect(function() {
  168. connectPoints(a, b, 'x:y');
  169. }).to.throw(/unknown directions: <x:y>/);
  170. });
  171. });
  172. });
  173. describe('#connectRectangles', function() {
  174. var start = rect(100, 100, 100, 100);
  175. it('should connect top', function() {
  176. // given
  177. var end = rect(100, 0, 50, 50);
  178. // when
  179. var connection = connectRectangles(start, end);
  180. // expect
  181. expectConnection(connection, [
  182. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  183. { x: 150, y: 75 },
  184. { x: 125, y: 75 },
  185. { original: { x: 125, y: 25 }, x: 125, y: 50 }
  186. ]);
  187. });
  188. it('should connect right', function() {
  189. // given
  190. var end = rect(250, 100, 50, 50);
  191. // when
  192. var connection = connectRectangles(start, end);
  193. // expect
  194. expectConnection(connection, [
  195. { original: { x: 150, y: 150 }, x: 200, y: 150 },
  196. { x: 225, y: 150 },
  197. { x: 225, y: 125 },
  198. { original: { x: 275, y: 125 }, x: 250, y: 125 }
  199. ]);
  200. });
  201. it('should connect left', function() {
  202. // given
  203. var end = rect(0, 100, 50, 50);
  204. // when
  205. var connection = connectRectangles(start, end);
  206. // expect
  207. expectConnection(connection, [
  208. { original: { x: 150, y: 150 }, x: 100, y: 150 },
  209. { x: 75, y: 150 },
  210. { x: 75, y: 125 },
  211. { original: { x: 25, y: 125 }, x: 50, y: 125 }
  212. ]);
  213. });
  214. it('should connect bottom', function() {
  215. // given
  216. var end = rect(100, 250, 50, 50);
  217. // when
  218. var connection = connectRectangles(start, end);
  219. // expect
  220. expectConnection(connection, [
  221. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  222. { x: 150, y: 225 },
  223. { x: 125, y: 225 },
  224. { original: { x: 125, y: 275 }, x: 125, y: 250 }
  225. ]);
  226. });
  227. describe('tolerance', function() {
  228. it('should connect default v:v inside tolerance (preferred = default)', function() {
  229. // given
  230. var end = rect(210, 0, 50, 50);
  231. // when
  232. var connection = connectRectangles(start, end);
  233. // expect
  234. // still layouted v:v because h:h would look super ugly
  235. expectConnection(connection, [
  236. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  237. { x: 150, y: 75 },
  238. { x: 235, y: 75 },
  239. { original: { x: 235, y: 25 }, x: 235, y: 50 }
  240. ]);
  241. });
  242. it('should connect h:h outside tolerance (preferred = default)', function() {
  243. // given
  244. var end = rect(230, 0, 50, 50);
  245. // when
  246. var connection = connectRectangles(start, end);
  247. // expect
  248. // layouted h:h
  249. expectConnection(connection, [
  250. { original: { x: 150, y: 150 }, x: 200, y: 150 },
  251. { x: 215, y: 150 },
  252. { x: 215, y: 25 },
  253. { original: { x: 255, y: 25 }, x: 230, y: 25 }
  254. ]);
  255. });
  256. it('should connect v:v inside tolerance (preferred = v:h)', function() {
  257. // given
  258. var end = rect(185, 0, 50, 50);
  259. // when
  260. var connection = connectRectangles(start, end, null, null, {
  261. preferredLayouts: [ 'v:h' ]
  262. });
  263. // expect
  264. // still layouted v:v due to tolerance
  265. expectConnection(connection, [
  266. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  267. { x: 150, y: 75 },
  268. { x: 210, y: 75 },
  269. { original: { x: 210, y: 25 }, x: 210, y: 50 }
  270. ]);
  271. });
  272. it('should connect v:h outside tolerance (preferred = v:h)', function() {
  273. // given
  274. var end = rect(230, 0, 50, 50);
  275. // when
  276. var connection = connectRectangles(start, end, null, null, {
  277. preferredLayouts: [ 'v:h' ]
  278. });
  279. // expect
  280. // layouted v:h
  281. expectConnection(connection, [
  282. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  283. { x: 150, y: 25 },
  284. { original: { x: 255, y: 25 }, x: 230, y: 25 }
  285. ]);
  286. });
  287. it('should connect h:v outside tolerance (preferred = h:v)', function() {
  288. // given
  289. var end = rect(230, 0, 50, 50);
  290. // when
  291. var connection = connectRectangles(start, end, null, null, {
  292. preferredLayouts: [ 'h:v' ]
  293. });
  294. // expect
  295. // layouted h:v
  296. expectConnection(connection, [
  297. { original: { x: 150, y: 150 }, x: 200, y: 150 },
  298. { x: 255, y: 150 },
  299. { original: { x: 255, y: 25 }, x: 255, y: 50 }
  300. ]);
  301. });
  302. });
  303. it('should connect top (directions = t:t)', function() {
  304. // given
  305. var end = rect(200, 100, 50, 50);
  306. // when
  307. var connection = connectRectangles(start, end, null, null, {
  308. preferredLayouts: [ 't:t' ]
  309. });
  310. // expect
  311. expectConnection(connection, [
  312. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  313. { x: 150, y: 80 },
  314. { x: 225, y: 80 },
  315. { original: { x: 225, y: 125 }, x: 225, y: 100 }
  316. ]);
  317. });
  318. it('should connect top (directions = r:r)', function() {
  319. // given
  320. var end = rect(200, 100, 50, 50);
  321. // when
  322. var connection = connectRectangles(start, end, null, null, {
  323. preferredLayouts: [ 'r:r' ]
  324. });
  325. // expect
  326. expectConnection(connection, [
  327. { original: { x: 150, y: 150 }, x: 200, y: 150 },
  328. { x: 270, y: 150 },
  329. { x: 270, y: 125 },
  330. { original: { x: 225, y: 125 }, x: 250, y: 125 }
  331. ]);
  332. });
  333. it('should connection t:t by default when intersecting', function() {
  334. // given
  335. var end = rect(150, 100, 100, 100);
  336. // when
  337. var connection = connectRectangles(start, end);
  338. // expect
  339. expectConnection(connection, [
  340. { original: { x: 150, y: 150 }, x: 150, y: 100 },
  341. { x: 150, y: 80 },
  342. { x: 200, y: 80 },
  343. { original: { x: 200, y: 150 }, x: 200, y: 100 }
  344. ]);
  345. });
  346. });
  347. describe('#repairConnection', function() {
  348. function moved(bounds, delta) {
  349. return {
  350. x: bounds.x + (delta.x || 0),
  351. y: bounds.y + (delta.y || 0),
  352. width: bounds.width,
  353. height: bounds.height
  354. };
  355. }
  356. function connect(start, end, a, b) {
  357. return connectRectangles(start, end, a, b);
  358. }
  359. function repair(start, end, a, b, waypoints, hints) {
  360. return repairConnection(start, end, a, b, waypoints, hints);
  361. }
  362. describe('v:v layout preferred', function() {
  363. it('should relayout vertical', function() {
  364. // given
  365. var start = rect(100, 100, 100, 100),
  366. end = rect(250, 400, 100, 100);
  367. var waypoints = [];
  368. // when
  369. var repaired = repair(start, end, waypoints, { preferredLayouts: [ 'v:v' ] });
  370. // then
  371. expect(repaired).to.eql([
  372. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  373. { x: 150, y: 300 }, // vertical intermediate
  374. { x: 300, y: 300 }, // line segment
  375. { original: { x: 300, y: 450 }, x: 300, y: 400 }
  376. ]);
  377. });
  378. it('should relayout horizontal', function() {
  379. // given
  380. var start = rect(100, 100, 100, 100),
  381. end = rect(300, 50, 100, 300);
  382. var waypoints = [];
  383. // when
  384. var repaired = repair(start, end, waypoints, { preferredLayouts: [ 'v:v' ] });
  385. // then
  386. expect(repaired).to.eql([
  387. { original: { x: 150, y: 150 }, x: 200, y: 150 },
  388. { x: 250, y: 150 }, // horizontal intermediate
  389. { x: 250, y: 200 }, // line segment
  390. { original: { x: 350, y: 200 }, x: 300, y: 200 }
  391. ]);
  392. });
  393. });
  394. describe('straight layout preferred', function() {
  395. it('should layout straight line (horizontal)', function() {
  396. // given
  397. var start = rect(100, 100, 100, 100),
  398. end = rect(300, 50, 100, 300);
  399. var waypoints = [];
  400. // when
  401. var repaired = repair(start, end, waypoints, { preferredLayouts: [ 'straight' ] });
  402. // then
  403. expect(repaired).to.eql([
  404. { x: 150, y: 150 },
  405. { x: 350, y: 150, original: { x: 350, y: 150 } }
  406. ]);
  407. });
  408. it('should layout straight line (horizontal), preserving target docking', function() {
  409. // given
  410. var start = rect(100, 100, 100, 100),
  411. end = rect(300, 50, 100, 300);
  412. var waypoints = [];
  413. // when
  414. var repaired = repair(start, end, waypoints, {
  415. preferredLayouts: [ 'straight' ],
  416. preserveDocking: 'target'
  417. });
  418. // then
  419. expect(repaired).to.eql([
  420. { x: 150, y: 200, original: { x: 150, y: 200 } },
  421. { x: 350, y: 200 }
  422. ]);
  423. });
  424. it('should layout straight line (vertical)', function() {
  425. // given
  426. var start = rect(100, 100, 100, 100),
  427. end = rect(50, 300, 200, 100);
  428. var waypoints = [];
  429. // when
  430. var repaired = repair(start, end, waypoints, { preferredLayouts: [ 'straight' ] });
  431. // then
  432. expect(repaired).to.eql([
  433. { x: 150, y: 150 },
  434. { x: 150, y: 350, original: { x: 150, y: 350 } }
  435. ]);
  436. });
  437. it('should layout straight line (vertical), preserving target docking', function() {
  438. // given
  439. var start = rect(100, 100, 100, 100),
  440. end = rect(50, 300, 200, 100);
  441. var waypoints = [];
  442. // when
  443. var repaired = repair(start, end, waypoints, {
  444. preferredLayouts: [ 'straight' ],
  445. preserveDocking: 'target'
  446. });
  447. // then
  448. expect(repaired).to.eql([
  449. { x: 150, y: 150, original: { x: 150, y: 150 } },
  450. { x: 150, y: 350 }
  451. ]);
  452. });
  453. });
  454. describe('relayout', function() {
  455. it('should relayout if no bendpoints', function() {
  456. // given
  457. var start = rect(100, 100, 100, 100),
  458. end = rect(200, 400, 100, 100);
  459. var waypoints = [];
  460. // when
  461. var repaired = repair(start, end, waypoints);
  462. // then
  463. expect(repaired).to.eql([
  464. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  465. { x: 150, y: 300 },
  466. { x: 250, y: 300 },
  467. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  468. ]);
  469. });
  470. it('should relayout if bendpoints overlapped', function() {
  471. // given
  472. var start = rect(100, 100, 100, 100),
  473. end = rect(100, 400, 100, 100);
  474. var waypoints = [
  475. { x: 150, y: 150 },
  476. { x: 250, y: 150 },
  477. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  478. ];
  479. // when
  480. var repaired = repair(start, end, waypoints, { connectionEnd: true });
  481. // then
  482. expect(repaired).to.eql([
  483. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  484. { original: { x: 150, y: 450 }, x: 150, y: 400 }
  485. ]);
  486. });
  487. });
  488. describe('bendpoint removal', function() {
  489. it('should remove overlapping bendpoints', function() {
  490. // given
  491. var start = rect(100, 100, 100, 100),
  492. end = rect(200, 400, 100, 100),
  493. newEnd = moved(end, { x: 50, y: -100 }); // move on second bendpoint
  494. var waypoints = [
  495. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  496. { x: 150, y: 300 },
  497. { x: 250, y: 300 },
  498. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  499. ];
  500. // when
  501. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  502. // then
  503. expect(repaired).to.eql([
  504. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  505. { x: 150, y: 350 },
  506. { x: 300, y: 350 }
  507. ]);
  508. });
  509. it('should remove all from overlapping bendpoint', function() {
  510. // given
  511. var start = rect(100, 100, 100, 100),
  512. end = rect(200, 400, 100, 100),
  513. newEnd = moved(end, { x: 50, y: -100 }); // move on second bendpoint
  514. var waypoints = [
  515. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  516. { x: 150, y: 300 },
  517. // <custom garbage bendpoints>
  518. { x: 250, y: 300 },
  519. { x: 150, y: 300 },
  520. // </custom garbage bendpoints>
  521. { x: 250, y: 300 },
  522. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  523. ];
  524. // when
  525. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  526. // then
  527. expect(repaired).to.eql([
  528. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  529. { x: 150, y: 350 },
  530. { x: 300, y: 350 }
  531. ]);
  532. });
  533. });
  534. describe('bendpoint adjustment', function() {
  535. describe('misc', function() {
  536. it('should adjust single bendpoints', function() {
  537. // given
  538. var start = rect(50, 100, 100, 100),
  539. end = rect(200, 400, 100, 100),
  540. newStart = moved(start, { x: 50 });
  541. var waypoints = [
  542. { x: 100, y: 150 },
  543. { x: 250, y: 150 },
  544. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  545. ];
  546. // when
  547. var repaired = repair(newStart, end, waypoints, { connectionStart: true });
  548. // then
  549. expect(repaired).to.eql([
  550. { x: 150, y: 150 },
  551. { x: 250, y: 150 },
  552. { original: { x: 250, y: 450 }, x: 250, y: 400 }
  553. ]);
  554. });
  555. it('should not layout free flow', function() {
  556. // given
  557. var start = rect(100, 100, 100, 100),
  558. end = rect(200, 400, 100, 100),
  559. newEnd = moved(end, { x: 100, y: 50 });
  560. var waypoints = [
  561. { original: { x: 150, y: 150 }, x: 150, y: 200 },
  562. { x: 150, y: 300 },
  563. // diagonal connection
  564. { x: 250, y: 450 }
  565. ];
  566. // when
  567. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  568. // then
  569. expect(repaired).to.eql(waypoints.slice(0, 2).concat([ { x: 350, y: 500 } ]));
  570. });
  571. });
  572. describe('repair start', function() {
  573. var start = rect(100, 100, 100, 100),
  574. end = rect(200, 400, 100, 100);
  575. it('should repair move x', function() {
  576. // given
  577. var waypoints = connect(start, end),
  578. newStart = moved(start, { x: 50 });
  579. // when
  580. var repaired = repair(newStart, end, waypoints, { connectionStart: true });
  581. // then
  582. expect(repaired).to.eql([ { x: 200, y: 150 }, { x: 200, y: 300 } ].concat(waypoints.slice(2)));
  583. });
  584. it('should repair move y', function() {
  585. // given
  586. var waypoints = connect(start, end),
  587. newStart = moved(start, { y: 50 });
  588. // when
  589. var repaired = repair(newStart, end, waypoints, { connectionStart: true });
  590. // then
  591. expect(repaired).to.eql([ { x: 150, y: 200 }, { x: 150, y: 300 } ].concat(waypoints.slice(2)));
  592. });
  593. it('should repair move x,y', function() {
  594. // given
  595. var waypoints = connect(start, end),
  596. newStart = moved(start, { x: 100, y: -50 });
  597. // when
  598. var repaired = repair(newStart, end, waypoints, { connectionStart: true });
  599. // then
  600. expect(repaired).to.eql([ { x: 250, y: 100 }, { x: 250, y: 300 } ].concat(waypoints.slice(2)));
  601. });
  602. });
  603. describe('repair end', function() {
  604. var start = rect(100, 100, 100, 100),
  605. end = rect(150, 400, 100, 100);
  606. it('should repair move x', function() {
  607. // given
  608. var waypoints = connect(start, end),
  609. newEnd = moved(end, { x: 50 });
  610. // when
  611. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  612. // then
  613. expect(repaired).to.eql(waypoints.slice(0, 2).concat([ { x: 250, y: 300 }, { x: 250, y: 450 } ]));
  614. });
  615. it('should repair move y', function() {
  616. // given
  617. var waypoints = connect(start, end),
  618. newEnd = moved(end, { y: 50 });
  619. // when
  620. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  621. // then
  622. expect(repaired).to.eql(waypoints.slice(0, 3).concat([ { x: 200, y: 500 } ]));
  623. });
  624. it('should repair move x,y', function() {
  625. // given
  626. var waypoints = connect(start, end),
  627. newEnd = moved(end, { x: 100, y: -50 });
  628. // when
  629. var repaired = repair(start, newEnd, waypoints, { connectionEnd: true });
  630. // then
  631. expect(repaired).to.eql(waypoints.slice(0, 2).concat([ { x: 300, y: 300 }, { x: 300, y: 400 } ]));
  632. });
  633. });
  634. });
  635. });
  636. });