undo_redo_test.rs 10 KB

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