undo_redo_test.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. pub mod helper;
  2. use crate::helper::{TestOp::*, *};
  3. use flowy_ot::{
  4. client::RECORD_THRESHOLD,
  5. core::{Interval, NEW_LINE, WHITESPACE},
  6. };
  7. #[test]
  8. fn history_insert_undo() {
  9. let ops = vec![
  10. Insert(0, "123", 0),
  11. Undo(0),
  12. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  13. ];
  14. OpTester::new().run_script_with_newline(ops);
  15. }
  16. #[test]
  17. fn history_insert_undo_with_lagging() {
  18. let ops = vec![
  19. Insert(0, "123", 0),
  20. Wait(RECORD_THRESHOLD),
  21. Insert(0, "456", 0),
  22. Undo(0),
  23. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  24. Undo(0),
  25. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  26. ];
  27. OpTester::new().run_script_with_newline(ops);
  28. }
  29. #[test]
  30. fn history_insert_redo() {
  31. let ops = vec![
  32. Insert(0, "123", 0),
  33. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  34. Undo(0),
  35. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  36. Redo(0),
  37. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  38. ];
  39. OpTester::new().run_script_with_newline(ops);
  40. }
  41. #[test]
  42. fn history_insert_redo_with_lagging() {
  43. let ops = vec![
  44. Insert(0, "123", 0),
  45. Wait(RECORD_THRESHOLD),
  46. Insert(0, "456", 3),
  47. Wait(RECORD_THRESHOLD),
  48. AssertStr(0, "123456\n"),
  49. AssertOpsJson(0, r#"[{"insert":"123456\n"}]"#),
  50. Undo(0),
  51. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  52. Redo(0),
  53. AssertOpsJson(0, r#"[{"insert":"123456\n"}]"#),
  54. Undo(0),
  55. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  56. ];
  57. OpTester::new().run_script_with_newline(ops);
  58. }
  59. #[test]
  60. fn history_bold_undo() {
  61. let ops = vec![
  62. Insert(0, "123", 0),
  63. Bold(0, Interval::new(0, 3), true),
  64. Undo(0),
  65. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  66. ];
  67. OpTester::new().run_script_with_newline(ops);
  68. }
  69. #[test]
  70. fn history_bold_undo_with_lagging() {
  71. let ops = vec![
  72. Insert(0, "123", 0),
  73. Wait(RECORD_THRESHOLD),
  74. Bold(0, Interval::new(0, 3), true),
  75. Undo(0),
  76. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  77. ];
  78. OpTester::new().run_script_with_newline(ops);
  79. }
  80. #[test]
  81. fn history_bold_redo() {
  82. let ops = vec![
  83. Insert(0, "123", 0),
  84. Bold(0, Interval::new(0, 3), true),
  85. Undo(0),
  86. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  87. Redo(0),
  88. AssertOpsJson(
  89. 0,
  90. r#" [{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  91. ),
  92. ];
  93. OpTester::new().run_script_with_newline(ops);
  94. }
  95. #[test]
  96. fn history_bold_redo_with_lagging() {
  97. let ops = vec![
  98. Insert(0, "123", 0),
  99. Wait(RECORD_THRESHOLD),
  100. Bold(0, Interval::new(0, 3), true),
  101. Undo(0),
  102. AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
  103. Redo(0),
  104. AssertOpsJson(
  105. 0,
  106. r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  107. ),
  108. ];
  109. OpTester::new().run_script_with_newline(ops);
  110. }
  111. #[test]
  112. fn history_delete_undo() {
  113. let ops = vec![
  114. Insert(0, "123", 0),
  115. AssertOpsJson(0, r#"[{"insert":"123"}]"#),
  116. Delete(0, Interval::new(0, 3)),
  117. AssertOpsJson(0, r#"[]"#),
  118. Undo(0),
  119. AssertOpsJson(0, r#"[{"insert":"123"}]"#),
  120. ];
  121. OpTester::new().run_script(ops);
  122. }
  123. #[test]
  124. fn history_delete_undo_2() {
  125. let ops = vec![
  126. Insert(0, "123", 0),
  127. Bold(0, Interval::new(0, 3), true),
  128. Delete(0, Interval::new(0, 1)),
  129. AssertOpsJson(
  130. 0,
  131. r#"[
  132. {"insert":"23","attributes":{"bold":"true"}},
  133. {"insert":"\n"}]
  134. "#,
  135. ),
  136. Undo(0),
  137. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  138. ];
  139. OpTester::new().run_script_with_newline(ops);
  140. }
  141. #[test]
  142. fn history_delete_undo_with_lagging() {
  143. let ops = vec![
  144. Insert(0, "123", 0),
  145. Wait(RECORD_THRESHOLD),
  146. Bold(0, Interval::new(0, 3), true),
  147. Wait(RECORD_THRESHOLD),
  148. Delete(0, Interval::new(0, 1)),
  149. AssertOpsJson(
  150. 0,
  151. r#"[
  152. {"insert":"23","attributes":{"bold":"true"}},
  153. {"insert":"\n"}]
  154. "#,
  155. ),
  156. Undo(0),
  157. AssertOpsJson(
  158. 0,
  159. r#"[
  160. {"insert":"123","attributes":{"bold":"true"}},
  161. {"insert":"\n"}]
  162. "#,
  163. ),
  164. ];
  165. OpTester::new().run_script_with_newline(ops);
  166. }
  167. #[test]
  168. fn history_delete_redo() {
  169. let ops = vec![
  170. Insert(0, "123", 0),
  171. Wait(RECORD_THRESHOLD),
  172. Delete(0, Interval::new(0, 3)),
  173. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  174. Undo(0),
  175. Redo(0),
  176. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  177. ];
  178. OpTester::new().run_script_with_newline(ops);
  179. }
  180. #[test]
  181. fn history_replace_undo() {
  182. let ops = vec![
  183. Insert(0, "123", 0),
  184. Bold(0, Interval::new(0, 3), true),
  185. Replace(0, Interval::new(0, 2), "ab"),
  186. AssertOpsJson(
  187. 0,
  188. r#"[
  189. {"insert":"ab"},
  190. {"insert":"3","attributes":{"bold":"true"}},{"insert":"\n"}]
  191. "#,
  192. ),
  193. Undo(0),
  194. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  195. ];
  196. OpTester::new().run_script_with_newline(ops);
  197. }
  198. #[test]
  199. fn history_replace_undo_with_lagging() {
  200. let ops = vec![
  201. Insert(0, "123", 0),
  202. Wait(RECORD_THRESHOLD),
  203. Bold(0, Interval::new(0, 3), true),
  204. Wait(RECORD_THRESHOLD),
  205. Replace(0, Interval::new(0, 2), "ab"),
  206. AssertOpsJson(
  207. 0,
  208. r#"[
  209. {"insert":"ab"},
  210. {"insert":"3","attributes":{"bold":"true"}},{"insert":"\n"}]
  211. "#,
  212. ),
  213. Undo(0),
  214. AssertOpsJson(
  215. 0,
  216. r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  217. ),
  218. ];
  219. OpTester::new().run_script_with_newline(ops);
  220. }
  221. #[test]
  222. fn history_replace_redo() {
  223. let ops = vec![
  224. Insert(0, "123", 0),
  225. Bold(0, Interval::new(0, 3), true),
  226. Replace(0, Interval::new(0, 2), "ab"),
  227. Undo(0),
  228. Redo(0),
  229. AssertOpsJson(
  230. 0,
  231. r#"[
  232. {"insert":"ab"},
  233. {"insert":"3","attributes":{"bold":"true"}},{"insert":"\n"}]
  234. "#,
  235. ),
  236. ];
  237. OpTester::new().run_script_with_newline(ops);
  238. }
  239. #[test]
  240. fn history_header_added_undo() {
  241. let ops = vec![
  242. Insert(0, "123456", 0),
  243. Header(0, Interval::new(0, 6), 1, true),
  244. Insert(0, "\n", 3),
  245. Insert(0, "\n", 4),
  246. Undo(0),
  247. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  248. Redo(0),
  249. AssertOpsJson(
  250. 0,
  251. r#"[{"insert":"123"},{"insert":"\n\n","attributes":{"header":"1"}},{"insert":"456"},{"insert":"\n","attributes":{"header":"1"}}]"#,
  252. ),
  253. ];
  254. OpTester::new().run_script_with_newline(ops);
  255. }
  256. #[test]
  257. fn history_link_added_undo() {
  258. let site = "https://appflowy.io";
  259. let ops = vec![
  260. Insert(0, site, 0),
  261. Wait(RECORD_THRESHOLD),
  262. Link(0, Interval::new(0, site.len()), site, true),
  263. Undo(0),
  264. AssertOpsJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
  265. Redo(0),
  266. AssertOpsJson(
  267. 0,
  268. r#"[{"insert":"https://appflowy.io","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  269. ),
  270. ];
  271. OpTester::new().run_script_with_newline(ops);
  272. }
  273. #[test]
  274. fn history_link_auto_format_undo_with_lagging() {
  275. let site = "https://appflowy.io";
  276. let ops = vec![
  277. Insert(0, site, 0),
  278. AssertOpsJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
  279. Wait(RECORD_THRESHOLD),
  280. Insert(0, WHITESPACE, site.len()),
  281. AssertOpsJson(
  282. 0,
  283. r#"[{"insert":"https://appflowy.io","attributes":{"link":"https://appflowy.io/"}},{"insert":" \n"}]"#,
  284. ),
  285. Undo(0),
  286. AssertOpsJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
  287. ];
  288. OpTester::new().run_script_with_newline(ops);
  289. }
  290. #[test]
  291. fn history_bullet_undo() {
  292. let ops = vec![
  293. Insert(0, "1", 0),
  294. Bullet(0, Interval::new(0, 1), true),
  295. Insert(0, NEW_LINE, 1),
  296. Insert(0, "2", 2),
  297. AssertOpsJson(
  298. 0,
  299. r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"2"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  300. ),
  301. Undo(0),
  302. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  303. Redo(0),
  304. AssertOpsJson(
  305. 0,
  306. r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"2"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  307. ),
  308. ];
  309. OpTester::new().run_script_with_newline(ops);
  310. }
  311. #[test]
  312. fn history_bullet_undo_with_lagging() {
  313. let ops = vec![
  314. Insert(0, "1", 0),
  315. Bullet(0, Interval::new(0, 1), true),
  316. Wait(RECORD_THRESHOLD),
  317. Insert(0, NEW_LINE, 1),
  318. Insert(0, "2", 2),
  319. Wait(RECORD_THRESHOLD),
  320. AssertOpsJson(
  321. 0,
  322. r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"2"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  323. ),
  324. Undo(0),
  325. AssertOpsJson(
  326. 0,
  327. r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  328. ),
  329. Undo(0),
  330. AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
  331. Redo(0),
  332. Redo(0),
  333. AssertOpsJson(
  334. 0,
  335. r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"2"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  336. ),
  337. ];
  338. OpTester::new().run_script_with_newline(ops);
  339. }
  340. #[test]
  341. fn history_undo_attribute_on_merge_between_line() {
  342. let ops = vec![
  343. Insert(0, "123456", 0),
  344. Bullet(0, Interval::new(0, 6), true),
  345. Wait(RECORD_THRESHOLD),
  346. Insert(0, NEW_LINE, 3),
  347. Wait(RECORD_THRESHOLD),
  348. AssertOpsJson(
  349. 0,
  350. r#"[{"insert":"123"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  351. ),
  352. Delete(0, Interval::new(3, 4)), // delete the newline
  353. AssertOpsJson(
  354. 0,
  355. r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  356. ),
  357. Undo(0),
  358. AssertOpsJson(
  359. 0,
  360. r#"[{"insert":"123"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
  361. ),
  362. ];
  363. OpTester::new().run_script_with_newline(ops);
  364. }