remove.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. import { Client, syncClients, expectClients, clearBuffer } from './utils.js';
  2. describe( 'transform', () => {
  3. let john, kate;
  4. beforeEach( () => {
  5. return Promise.all( [
  6. Client.get( 'john' ).then( client => ( john = client ) ),
  7. Client.get( 'kate' ).then( client => ( kate = client ) )
  8. ] );
  9. } );
  10. afterEach( () => {
  11. clearBuffer();
  12. return Promise.all( [ john.destroy(), kate.destroy() ] );
  13. } );
  14. describe( 'remove', () => {
  15. describe( 'by remove', () => {
  16. it( 'text in different path', () => {
  17. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  18. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  19. john.remove();
  20. kate.remove();
  21. syncClients();
  22. expectClients( '<paragraph>F</paragraph><paragraph>B</paragraph>' );
  23. } );
  24. it( 'text in same path', () => {
  25. john.setData( '<paragraph>F[oo] Bar</paragraph>' );
  26. kate.setData( '<paragraph>Foo B[ar]</paragraph>' );
  27. john.remove();
  28. kate.remove();
  29. syncClients();
  30. expectClients( '<paragraph>F B</paragraph>' );
  31. } );
  32. it( 'text in other user\'s selection #1', () => {
  33. john.setData( '<paragraph>[Foo Bar]</paragraph>' );
  34. kate.setData( '<paragraph>Fo[o B]ar</paragraph>' );
  35. john.remove();
  36. kate.remove();
  37. syncClients();
  38. expectClients( '<paragraph></paragraph>' );
  39. } );
  40. it( 'text in other user\'s selection #2', () => {
  41. john.setData( '<paragraph>[Foo Bar]</paragraph>' );
  42. kate.setData( '<paragraph>[Foo Bar]</paragraph>' );
  43. john.remove();
  44. kate.remove();
  45. syncClients();
  46. expectClients( '<paragraph></paragraph>' );
  47. } );
  48. it( 'element in different path', () => {
  49. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  50. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  51. john.remove();
  52. kate.remove();
  53. syncClients();
  54. expectClients( '<paragraph></paragraph>' );
  55. } );
  56. it( 'text in other user\'s selection, then undo', () => {
  57. john.setData( '<paragraph>[Foo Bar]</paragraph>' );
  58. kate.setData( '<paragraph>Fo[o B]ar</paragraph>' );
  59. john.remove();
  60. kate.remove();
  61. syncClients();
  62. john.undo();
  63. kate.undo();
  64. syncClients();
  65. expectClients( '<paragraph>Foo Bar</paragraph>' );
  66. } );
  67. } );
  68. describe( 'by wrap', () => {
  69. it( 'element in different path', () => {
  70. john.setData( '<paragraph>[Foo]</paragraph><paragraph>Bar</paragraph>' );
  71. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  72. john.remove();
  73. kate.wrap( 'blockQuote' );
  74. syncClients();
  75. expectClients(
  76. '<paragraph></paragraph>' +
  77. '<blockQuote>' +
  78. '<paragraph>Bar</paragraph>' +
  79. '</blockQuote>'
  80. );
  81. } );
  82. it( 'element in same path', () => {
  83. john.setData( '<paragraph>[Foo]</paragraph>' );
  84. kate.setData( '[<paragraph>Foo</paragraph>]' );
  85. john.remove();
  86. kate.wrap( 'blockQuote' );
  87. syncClients();
  88. expectClients( '<blockQuote><paragraph></paragraph></blockQuote>' );
  89. } );
  90. it( 'element while removing', () => {
  91. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  92. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  93. john.remove();
  94. kate.wrap( 'blockQuote' );
  95. syncClients();
  96. expectClients( '<paragraph>Foo</paragraph>' );
  97. } );
  98. it( 'element while removing, then undo', () => {
  99. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  100. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  101. john.remove();
  102. kate.wrap( 'blockQuote' );
  103. syncClients();
  104. expectClients( '<paragraph>Foo</paragraph>' );
  105. john.undo();
  106. syncClients();
  107. // Below would be the expected effect with correct wrap transformation.
  108. // expectClients(
  109. // '<paragraph>Foo</paragraph>' +
  110. // '<blockQuote>' +
  111. // '<paragraph>Bar</paragraph>' +
  112. // '</blockQuote>'
  113. // );
  114. expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  115. } );
  116. it( 'element while removing, then undo #2', () => {
  117. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  118. kate.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  119. john.remove();
  120. john.undo();
  121. kate.wrap( 'blockQuote' );
  122. syncClients();
  123. // Below would be the expected effect with correct wrap transformation.
  124. // expectClients(
  125. // '<paragraph>Foo</paragraph>' +
  126. // '<blockQuote>' +
  127. // '<paragraph>Bar</paragraph>' +
  128. // '</blockQuote>'
  129. // );
  130. expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  131. } );
  132. } );
  133. describe( 'by unwrap', () => {
  134. it( 'element in different path', () => {
  135. john.setData( '<paragraph>[Foo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  136. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  137. john.remove();
  138. kate.unwrap();
  139. syncClients();
  140. expectClients(
  141. '<paragraph></paragraph>' +
  142. '<paragraph>Bar</paragraph>'
  143. );
  144. } );
  145. it( 'text in different path', () => {
  146. john.setData( '<paragraph>[Foo]</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  147. kate.setData( '<paragraph>Foo</paragraph><blockQuote><paragraph>[]Bar</paragraph></blockQuote>' );
  148. john.remove();
  149. kate.unwrap();
  150. syncClients();
  151. expectClients(
  152. '<paragraph></paragraph>' +
  153. '<blockQuote>Bar</blockQuote>'
  154. );
  155. } );
  156. it( 'element in same path', () => {
  157. john.setData( '<blockQuote><paragraph>[Foo]</paragraph></blockQuote>' );
  158. kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
  159. john.remove();
  160. kate.unwrap();
  161. syncClients();
  162. expectClients( '<paragraph></paragraph>' );
  163. } );
  164. it( 'element while removing', () => {
  165. john.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  166. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  167. john.remove();
  168. kate.unwrap();
  169. syncClients();
  170. expectClients( '<paragraph>Foo</paragraph>' );
  171. } );
  172. it( 'element while removing, then undo', () => {
  173. john.setData( '<paragraph>Foo</paragraph><blockQuote>[<paragraph>Bar</paragraph>]</blockQuote>' );
  174. kate.setData( '<paragraph>Foo</paragraph><blockQuote>[]<paragraph>Bar</paragraph></blockQuote>' );
  175. john.remove();
  176. kate.unwrap();
  177. syncClients();
  178. expectClients( '<paragraph>Foo</paragraph>' );
  179. john.undo();
  180. syncClients();
  181. // Below would be the expected effect with correct wrap transformation.
  182. // expectClients(
  183. // '<paragraph>Foo</paragraph>' +
  184. // '<paragraph>Bar</paragraph>'
  185. // );
  186. expectClients( '<paragraph>Foo</paragraph><blockQuote><paragraph>Bar</paragraph></blockQuote>' );
  187. } );
  188. } );
  189. describe( 'by split', () => {
  190. it( 'text in different path', () => {
  191. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  192. kate.setData( '<paragraph>Foo</paragraph><paragraph>B[]ar</paragraph>' );
  193. john.remove();
  194. kate.split();
  195. syncClients();
  196. expectClients(
  197. '<paragraph>F</paragraph>' +
  198. '<paragraph>B</paragraph>' +
  199. '<paragraph>ar</paragraph>'
  200. );
  201. } );
  202. it( 'text in same path', () => {
  203. john.setData( '<paragraph>[Foo] Bar</paragraph>' );
  204. kate.setData( '<paragraph>Foo []Bar</paragraph>' );
  205. john.remove();
  206. kate.split();
  207. syncClients();
  208. expectClients(
  209. '<paragraph> </paragraph>' +
  210. '<paragraph>Bar</paragraph>'
  211. );
  212. } );
  213. it( 'text in other user\'s selection #1', () => {
  214. john.setData( '<paragraph>[Foo] Bar</paragraph>' );
  215. kate.setData( '<paragraph>F[]oo Bar</paragraph>' );
  216. john.remove();
  217. kate.split();
  218. syncClients();
  219. expectClients(
  220. '<paragraph></paragraph>' +
  221. '<paragraph> Bar</paragraph>'
  222. );
  223. } );
  224. it( 'text in other user\'s selection #2', () => {
  225. john.setData( '<paragraph>[Foo Bar]</paragraph>' );
  226. kate.setData( '<paragraph>F[]oo Bar</paragraph>' );
  227. john.remove();
  228. kate.split();
  229. syncClients();
  230. expectClients(
  231. '<paragraph></paragraph>' +
  232. '<paragraph></paragraph>'
  233. );
  234. } );
  235. it( 'text, then remove and undo', () => {
  236. john.setData( '<paragraph>[Foo ]Bar</paragraph>' );
  237. kate.setData( '<paragraph>Foo []Bar</paragraph>' );
  238. john.remove();
  239. kate.split();
  240. syncClients();
  241. john.setSelection( [ 1, 0 ], [ 1, 3 ] );
  242. john.remove();
  243. kate.undo();
  244. syncClients();
  245. expectClients( '<paragraph></paragraph>' );
  246. } );
  247. it( 'remove split element', () => {
  248. john.setData( '[<paragraph>Foo</paragraph>]<paragraph>Bar</paragraph>' );
  249. kate.setData( '<paragraph>Fo[]o</paragraph><paragraph>Bar</paragraph>' );
  250. john.remove();
  251. kate.split();
  252. syncClients();
  253. expectClients( '<paragraph>Bar</paragraph>' );
  254. } );
  255. } );
  256. describe( 'by merge', () => {
  257. it( 'element into paragraph #1', () => {
  258. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  259. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  260. john.remove();
  261. kate.merge();
  262. syncClients();
  263. expectClients( '<paragraph>FBar</paragraph>' );
  264. } );
  265. it( 'element into paragraph #2', () => {
  266. john.setData( '<paragraph>Foo</paragraph><paragraph>B[ar]</paragraph>' );
  267. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  268. john.remove();
  269. kate.merge();
  270. syncClients();
  271. expectClients( '<paragraph>FooB</paragraph>' );
  272. } );
  273. it( 'element into paragraph, then undo', () => {
  274. john.setData( '<paragraph>F[oo]</paragraph><paragraph>Bar</paragraph>' );
  275. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  276. john.remove();
  277. kate.merge();
  278. syncClients();
  279. expectClients( '<paragraph>FBar</paragraph>' );
  280. john.undo();
  281. syncClients();
  282. expectClients( '<paragraph>FooBar</paragraph>' );
  283. } );
  284. it( 'wrapped element into wrapped paragraph #1', () => {
  285. john.setData( '<blockQuote><paragraph>F[oo]</paragraph><paragraph>Bar</paragraph></blockQuote>' );
  286. kate.setData( '<blockQuote><paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph></blockQuote>' );
  287. john.remove();
  288. kate.merge();
  289. syncClients();
  290. expectClients( '<blockQuote><paragraph>FBar</paragraph></blockQuote>' );
  291. } );
  292. it( 'wrapped element into wrapped paragraph #2', () => {
  293. john.setData( '<blockQuote><paragraph>Foo</paragraph><paragraph>B[ar]</paragraph></blockQuote>' );
  294. kate.setData( '<blockQuote><paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph></blockQuote>' );
  295. john.remove();
  296. kate.merge();
  297. syncClients();
  298. expectClients( '<blockQuote><paragraph>FooB</paragraph></blockQuote>' );
  299. } );
  300. it( 'removed element, then undo', () => {
  301. john.setData( '<paragraph>Foo</paragraph>[<paragraph>Bar</paragraph>]' );
  302. kate.setData( '<paragraph>Foo</paragraph>[]<paragraph>Bar</paragraph>' );
  303. john.remove();
  304. kate.merge();
  305. syncClients();
  306. expectClients( '<paragraph>Foo</paragraph>' );
  307. john.undo();
  308. syncClients();
  309. expectClients( '<paragraph>Foo</paragraph><paragraph>Bar</paragraph>' );
  310. } );
  311. } );
  312. describe( 'by rename', () => {
  313. it( 'element in different path', () => {
  314. john.setData( '<paragraph>Foo</paragraph><paragraph>[Bar]</paragraph>' );
  315. kate.setData( '<paragraph>F[]oo</paragraph><paragraph>Bar</paragraph>' );
  316. john.remove();
  317. kate.rename( 'heading1' );
  318. syncClients();
  319. expectClients(
  320. '<heading1>Foo</heading1>' +
  321. '<paragraph></paragraph>'
  322. );
  323. } );
  324. it( 'element in same path', () => {
  325. john.setData( '<paragraph>F[o]o</paragraph>' );
  326. kate.setData( '<paragraph>[]Foo</paragraph>' );
  327. john.remove();
  328. kate.rename( 'heading1' );
  329. syncClients();
  330. expectClients( '<heading1>Fo</heading1>' );
  331. } );
  332. it( 'element in other user\'s selection', () => {
  333. kate.setData( '<paragraph>[Foo]</paragraph>' );
  334. john.setData( '<paragraph>[Foo]</paragraph>' );
  335. kate.remove();
  336. john.rename( 'heading1' );
  337. syncClients();
  338. expectClients( '<heading1></heading1>' );
  339. } );
  340. } );
  341. } );
  342. } );