attribute_test.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. #![cfg_attr(rustfmt, rustfmt::skip)]
  2. use crate::editor::{TestBuilder, TestOp::*};
  3. use flowy_document::services::doc::{FlowyDoc, PlainDoc};
  4. use flowy_ot::core::{Delta, Interval, OperationTransformable, NEW_LINE, WHITESPACE};
  5. #[test]
  6. fn attributes_bold_added() {
  7. let ops = vec![
  8. Insert(0, "123456", 0),
  9. Bold(0, Interval::new(3, 5), true),
  10. AssertDocJson(
  11. 0,
  12. r#"[
  13. {"insert":"123"},
  14. {"insert":"45","attributes":{"bold":"true"}},
  15. {"insert":"6"}
  16. ]"#,
  17. ),
  18. ];
  19. TestBuilder::new().run_script::<PlainDoc>(ops);
  20. }
  21. #[test]
  22. fn attributes_bold_added_and_invert_all() {
  23. let ops = vec![
  24. Insert(0, "123", 0),
  25. Bold(0, Interval::new(0, 3), true),
  26. AssertDocJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}}]"#),
  27. Bold(0, Interval::new(0, 3), false),
  28. AssertDocJson(0, r#"[{"insert":"123"}]"#),
  29. ];
  30. TestBuilder::new().run_script::<PlainDoc>(ops);
  31. }
  32. #[test]
  33. fn attributes_bold_added_and_invert_partial_suffix() {
  34. let ops = vec![
  35. Insert(0, "1234", 0),
  36. Bold(0, Interval::new(0, 4), true),
  37. AssertDocJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
  38. Bold(0, Interval::new(2, 4), false),
  39. AssertDocJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
  40. ];
  41. TestBuilder::new().run_script::<PlainDoc>(ops);
  42. }
  43. #[test]
  44. fn attributes_bold_added_and_invert_partial_suffix2() {
  45. let ops = vec![
  46. Insert(0, "1234", 0),
  47. Bold(0, Interval::new(0, 4), true),
  48. AssertDocJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
  49. Bold(0, Interval::new(2, 4), false),
  50. AssertDocJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
  51. Bold(0, Interval::new(2, 4), true),
  52. AssertDocJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
  53. ];
  54. TestBuilder::new().run_script::<PlainDoc>(ops);
  55. }
  56. #[test]
  57. fn attributes_bold_added_with_new_line() {
  58. let ops = vec![
  59. Insert(0, "123456", 0),
  60. Bold(0, Interval::new(0, 6), true),
  61. AssertDocJson(
  62. 0,
  63. r#"[{"insert":"123456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  64. ),
  65. Insert(0, "\n", 3),
  66. AssertDocJson(
  67. 0,
  68. r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"},{"insert":"456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  69. ),
  70. Insert(0, "\n", 4),
  71. AssertDocJson(
  72. 0,
  73. r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n\n"},{"insert":"456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  74. ),
  75. Insert(0, "a", 4),
  76. AssertDocJson(
  77. 0,
  78. r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\na\n"},{"insert":"456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
  79. ),
  80. ];
  81. TestBuilder::new().run_script::<FlowyDoc>(ops);
  82. }
  83. #[test]
  84. fn attributes_bold_added_and_invert_partial_prefix() {
  85. let ops = vec![
  86. Insert(0, "1234", 0),
  87. Bold(0, Interval::new(0, 4), true),
  88. AssertDocJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
  89. Bold(0, Interval::new(0, 2), false),
  90. AssertDocJson(0, r#"[{"insert":"12"},{"insert":"34","attributes":{"bold":"true"}}]"#),
  91. ];
  92. TestBuilder::new().run_script::<PlainDoc>(ops);
  93. }
  94. #[test]
  95. fn attributes_bold_added_consecutive() {
  96. let ops = vec![
  97. Insert(0, "1234", 0),
  98. Bold(0, Interval::new(0, 1), true),
  99. AssertDocJson(0, r#"[{"insert":"1","attributes":{"bold":"true"}},{"insert":"234"}]"#),
  100. Bold(0, Interval::new(1, 2), true),
  101. AssertDocJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
  102. ];
  103. TestBuilder::new().run_script::<PlainDoc>(ops);
  104. }
  105. #[test]
  106. fn attributes_bold_added_italic() {
  107. let ops = vec![
  108. Insert(0, "1234", 0),
  109. Bold(0, Interval::new(0, 4), true),
  110. Italic(0, Interval::new(0, 4), true),
  111. AssertDocJson(
  112. 0,
  113. r#"[{"insert":"1234","attributes":{"italic":"true","bold":"true"}},{"insert":"\n"}]"#,
  114. ),
  115. Insert(0, "5678", 4),
  116. AssertDocJson(
  117. 0,
  118. r#"[{"insert":"12345678","attributes":{"bold":"true","italic":"true"}},{"insert":"\n"}]"#,
  119. ),
  120. ];
  121. TestBuilder::new().run_script::<FlowyDoc>(ops);
  122. }
  123. #[test]
  124. fn attributes_bold_added_italic2() {
  125. let ops = vec![
  126. Insert(0, "123456", 0),
  127. Bold(0, Interval::new(0, 6), true),
  128. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  129. Italic(0, Interval::new(0, 2), true),
  130. AssertDocJson(
  131. 0,
  132. r#"[
  133. {"insert":"12","attributes":{"italic":"true","bold":"true"}},
  134. {"insert":"3456","attributes":{"bold":"true"}}]
  135. "#,
  136. ),
  137. Italic(0, Interval::new(4, 6), true),
  138. AssertDocJson(
  139. 0,
  140. r#"[
  141. {"insert":"12","attributes":{"italic":"true","bold":"true"}},
  142. {"insert":"34","attributes":{"bold":"true"}},
  143. {"insert":"56","attributes":{"italic":"true","bold":"true"}}]
  144. "#,
  145. ),
  146. ];
  147. TestBuilder::new().run_script::<PlainDoc>(ops);
  148. }
  149. #[test]
  150. fn attributes_bold_added_italic3() {
  151. let ops = vec![
  152. Insert(0, "123456789", 0),
  153. Bold(0, Interval::new(0, 5), true),
  154. Italic(0, Interval::new(0, 2), true),
  155. AssertDocJson(
  156. 0,
  157. r#"[
  158. {"insert":"12","attributes":{"bold":"true","italic":"true"}},
  159. {"insert":"345","attributes":{"bold":"true"}},{"insert":"6789"}]
  160. "#,
  161. ),
  162. Italic(0, Interval::new(2, 4), true),
  163. AssertDocJson(
  164. 0,
  165. r#"[
  166. {"insert":"1234","attributes":{"bold":"true","italic":"true"}},
  167. {"insert":"5","attributes":{"bold":"true"}},
  168. {"insert":"6789"}]
  169. "#,
  170. ),
  171. Bold(0, Interval::new(7, 9), true),
  172. AssertDocJson(
  173. 0,
  174. r#"[
  175. {"insert":"1234","attributes":{"bold":"true","italic":"true"}},
  176. {"insert":"5","attributes":{"bold":"true"}},
  177. {"insert":"67"},
  178. {"insert":"89","attributes":{"bold":"true"}}]
  179. "#,
  180. ),
  181. ];
  182. TestBuilder::new().run_script::<PlainDoc>(ops);
  183. }
  184. #[test]
  185. fn attributes_bold_added_italic_delete() {
  186. let ops = vec![
  187. Insert(0, "123456789", 0),
  188. Bold(0, Interval::new(0, 5), true),
  189. Italic(0, Interval::new(0, 2), true),
  190. AssertDocJson(
  191. 0,
  192. r#"[
  193. {"insert":"12","attributes":{"italic":"true","bold":"true"}},
  194. {"insert":"345","attributes":{"bold":"true"}},{"insert":"6789"}]
  195. "#,
  196. ),
  197. Italic(0, Interval::new(2, 4), true),
  198. AssertDocJson(
  199. 0,
  200. r#"[
  201. {"insert":"1234","attributes":{"bold":"true","italic":"true"}}
  202. ,{"insert":"5","attributes":{"bold":"true"}},{"insert":"6789"}]"#,
  203. ),
  204. Bold(0, Interval::new(7, 9), true),
  205. AssertDocJson(
  206. 0,
  207. r#"[
  208. {"insert":"1234","attributes":{"bold":"true","italic":"true"}},
  209. {"insert":"5","attributes":{"bold":"true"}},{"insert":"67"},
  210. {"insert":"89","attributes":{"bold":"true"}}]
  211. "#,
  212. ),
  213. Delete(0, Interval::new(0, 5)),
  214. AssertDocJson(0, r#"[{"insert":"67"},{"insert":"89","attributes":{"bold":"true"}}]"#),
  215. ];
  216. TestBuilder::new().run_script::<PlainDoc>(ops);
  217. }
  218. #[test]
  219. fn attributes_merge_inserted_text_with_same_attribute() {
  220. let ops = vec![
  221. InsertBold(0, "123", Interval::new(0, 3)),
  222. AssertDocJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}}]"#),
  223. InsertBold(0, "456", Interval::new(3, 6)),
  224. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  225. ];
  226. TestBuilder::new().run_script::<PlainDoc>(ops);
  227. }
  228. #[test]
  229. fn attributes_compose_attr_attributes_with_attr_attributes_test() {
  230. let ops = vec![
  231. InsertBold(0, "123456", Interval::new(0, 6)),
  232. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  233. InsertBold(1, "7", Interval::new(0, 1)),
  234. AssertDocJson(1, r#"[{"insert":"7","attributes":{"bold":"true"}}]"#),
  235. Transform(0, 1),
  236. AssertDocJson(0, r#"[{"insert":"1234567","attributes":{"bold":"true"}}]"#),
  237. AssertDocJson(1, r#"[{"insert":"1234567","attributes":{"bold":"true"}}]"#),
  238. ];
  239. TestBuilder::new().run_script::<PlainDoc>(ops);
  240. }
  241. #[test]
  242. fn attributes_compose_attr_attributes_with_attr_attributes_test2() {
  243. let ops = vec![
  244. Insert(0, "123456", 0),
  245. Bold(0, Interval::new(0, 6), true),
  246. Italic(0, Interval::new(0, 2), true),
  247. Italic(0, Interval::new(4, 6), true),
  248. AssertDocJson(
  249. 0,
  250. r#"[
  251. {"insert":"12","attributes":{"bold":"true","italic":"true"}},
  252. {"insert":"34","attributes":{"bold":"true"}},
  253. {"insert":"56","attributes":{"italic":"true","bold":"true"}}]
  254. "#,
  255. ),
  256. InsertBold(1, "7", Interval::new(0, 1)),
  257. AssertDocJson(1, r#"[{"insert":"7","attributes":{"bold":"true"}}]"#),
  258. Transform(0, 1),
  259. AssertDocJson(
  260. 0,
  261. r#"[
  262. {"insert":"12","attributes":{"italic":"true","bold":"true"}},
  263. {"insert":"34","attributes":{"bold":"true"}},
  264. {"insert":"56","attributes":{"italic":"true","bold":"true"}},
  265. {"insert":"7","attributes":{"bold":"true"}}]
  266. "#,
  267. ),
  268. AssertDocJson(
  269. 1,
  270. r#"[
  271. {"insert":"12","attributes":{"italic":"true","bold":"true"}},
  272. {"insert":"34","attributes":{"bold":"true"}},
  273. {"insert":"56","attributes":{"italic":"true","bold":"true"}},
  274. {"insert":"7","attributes":{"bold":"true"}}]
  275. "#,
  276. ),
  277. ];
  278. TestBuilder::new().run_script::<PlainDoc>(ops);
  279. }
  280. #[test]
  281. fn attributes_compose_attr_attributes_with_no_attr_attributes_test() {
  282. let expected = r#"[{"insert":"123456","attributes":{"bold":"true"}},{"insert":"7"}]"#;
  283. let ops = vec![
  284. InsertBold(0, "123456", Interval::new(0, 6)),
  285. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  286. Insert(1, "7", 0),
  287. AssertDocJson(1, r#"[{"insert":"7"}]"#),
  288. Transform(0, 1),
  289. AssertDocJson(0, expected),
  290. AssertDocJson(1, expected),
  291. ];
  292. TestBuilder::new().run_script::<PlainDoc>(ops);
  293. }
  294. #[test]
  295. fn attributes_replace_heading() {
  296. let ops = vec![
  297. InsertBold(0, "123456", Interval::new(0, 6)),
  298. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  299. Delete(0, Interval::new(0, 2)),
  300. AssertDocJson(0, r#"[{"insert":"3456","attributes":{"bold":"true"}}]"#),
  301. ];
  302. TestBuilder::new().run_script::<PlainDoc>(ops);
  303. }
  304. #[test]
  305. fn attributes_replace_trailing() {
  306. let ops = vec![
  307. InsertBold(0, "123456", Interval::new(0, 6)),
  308. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  309. Delete(0, Interval::new(5, 6)),
  310. AssertDocJson(0, r#"[{"insert":"12345","attributes":{"bold":"true"}}]"#),
  311. ];
  312. TestBuilder::new().run_script::<PlainDoc>(ops);
  313. }
  314. #[test]
  315. fn attributes_replace_middle() {
  316. let ops = vec![
  317. InsertBold(0, "123456", Interval::new(0, 6)),
  318. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  319. Delete(0, Interval::new(0, 2)),
  320. AssertDocJson(0, r#"[{"insert":"3456","attributes":{"bold":"true"}}]"#),
  321. Delete(0, Interval::new(2, 4)),
  322. AssertDocJson(0, r#"[{"insert":"34","attributes":{"bold":"true"}}]"#),
  323. ];
  324. TestBuilder::new().run_script::<PlainDoc>(ops);
  325. }
  326. #[test]
  327. fn attributes_replace_all() {
  328. let ops = vec![
  329. InsertBold(0, "123456", Interval::new(0, 6)),
  330. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  331. Delete(0, Interval::new(0, 6)),
  332. AssertDocJson(0, r#"[]"#),
  333. ];
  334. TestBuilder::new().run_script::<PlainDoc>(ops);
  335. }
  336. #[test]
  337. fn attributes_replace_with_text() {
  338. let ops = vec![
  339. InsertBold(0, "123456", Interval::new(0, 6)),
  340. AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
  341. Replace(0, Interval::new(0, 3), "ab"),
  342. AssertDocJson(0, r#"[{"insert":"ab"},{"insert":"456","attributes":{"bold":"true"}}]"#),
  343. ];
  344. TestBuilder::new().run_script::<PlainDoc>(ops);
  345. }
  346. #[test]
  347. fn attributes_header_insert_newline_at_middle() {
  348. let ops = vec![
  349. Insert(0, "123456", 0),
  350. Header(0, Interval::new(0, 6), 1),
  351. AssertDocJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":1}}]"#),
  352. Insert(0, "\n", 3),
  353. AssertDocJson(
  354. 0,
  355. r#"[{"insert":"123"},{"insert":"\n","attributes":{"header":1}},{"insert":"456"},{"insert":"\n","attributes":{"header":1}}]"#,
  356. ),
  357. ];
  358. TestBuilder::new().run_script::<FlowyDoc>(ops);
  359. }
  360. #[test]
  361. fn attributes_header_insert_double_newline_at_middle() {
  362. let ops = vec![
  363. Insert(0, "123456", 0),
  364. Header(0, Interval::new(0, 6), 1),
  365. Insert(0, "\n", 3),
  366. AssertDocJson(
  367. 0,
  368. r#"[{"insert":"123"},{"insert":"\n","attributes":{"header":1}},{"insert":"456"},{"insert":"\n","attributes":{"header":1}}]"#,
  369. ),
  370. Insert(0, "\n", 4),
  371. AssertDocJson(
  372. 0,
  373. r#"[{"insert":"123"},{"insert":"\n\n","attributes":{"header":1}},{"insert":"456"},{"insert":"\n","attributes":{"header":1}}]"#,
  374. ),
  375. Insert(0, "\n", 4),
  376. AssertDocJson(
  377. 0,
  378. r#"[{"insert":"123"},{"insert":"\n\n","attributes":{"header":1}},{"insert":"\n456"},{"insert":"\n","attributes":{"header":1}}]"#,
  379. ),
  380. ];
  381. TestBuilder::new().run_script::<FlowyDoc>(ops);
  382. }
  383. #[test]
  384. fn attributes_header_insert_newline_at_trailing() {
  385. let ops = vec![
  386. Insert(0, "123456", 0),
  387. Header(0, Interval::new(0, 6), 1),
  388. Insert(0, "\n", 6),
  389. AssertDocJson(
  390. 0,
  391. r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":1}},{"insert":"\n"}]"#,
  392. ),
  393. ];
  394. TestBuilder::new().run_script::<FlowyDoc>(ops);
  395. }
  396. #[test]
  397. fn attributes_header_insert_double_newline_at_trailing() {
  398. let ops = vec![
  399. Insert(0, "123456", 0),
  400. Header(0, Interval::new(0, 6), 1),
  401. Insert(0, "\n", 6),
  402. Insert(0, "\n", 7),
  403. AssertDocJson(
  404. 0,
  405. r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":1}},{"insert":"\n\n"}]"#,
  406. ),
  407. ];
  408. TestBuilder::new().run_script::<FlowyDoc>(ops);
  409. }
  410. #[test]
  411. fn attributes_link_added() {
  412. let ops = vec![
  413. Insert(0, "123456", 0),
  414. Link(0, Interval::new(0, 6), "https://appflowy.io"),
  415. AssertDocJson(
  416. 0,
  417. r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  418. ),
  419. ];
  420. TestBuilder::new().run_script::<FlowyDoc>(ops);
  421. }
  422. #[test]
  423. fn attributes_link_format_with_bold() {
  424. let ops = vec![
  425. Insert(0, "123456", 0),
  426. Link(0, Interval::new(0, 6), "https://appflowy.io"),
  427. Bold(0, Interval::new(0, 3), true),
  428. AssertDocJson(
  429. 0,
  430. r#"[
  431. {"insert":"123","attributes":{"bold":"true","link":"https://appflowy.io"}},
  432. {"insert":"456","attributes":{"link":"https://appflowy.io"}},
  433. {"insert":"\n"}]
  434. "#,
  435. ),
  436. ];
  437. TestBuilder::new().run_script::<FlowyDoc>(ops);
  438. }
  439. #[test]
  440. fn attributes_link_insert_char_at_head() {
  441. let ops = vec![
  442. Insert(0, "123456", 0),
  443. Link(0, Interval::new(0, 6), "https://appflowy.io"),
  444. AssertDocJson(
  445. 0,
  446. r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  447. ),
  448. Insert(0, "a", 0),
  449. AssertDocJson(
  450. 0,
  451. r#"[{"insert":"a"},{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  452. ),
  453. ];
  454. TestBuilder::new().run_script::<FlowyDoc>(ops);
  455. }
  456. #[test]
  457. fn attributes_link_insert_char_at_middle() {
  458. let ops = vec![
  459. Insert(0, "1256", 0),
  460. Link(0, Interval::new(0, 4), "https://appflowy.io"),
  461. Insert(0, "34", 2),
  462. AssertDocJson(
  463. 0,
  464. r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  465. ),
  466. ];
  467. TestBuilder::new().run_script::<FlowyDoc>(ops);
  468. }
  469. #[test]
  470. fn attributes_link_insert_char_at_trailing() {
  471. let ops = vec![
  472. Insert(0, "123456", 0),
  473. Link(0, Interval::new(0, 6), "https://appflowy.io"),
  474. AssertDocJson(
  475. 0,
  476. r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  477. ),
  478. Insert(0, "a", 6),
  479. AssertDocJson(
  480. 0,
  481. r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"a\n"}]"#,
  482. ),
  483. ];
  484. TestBuilder::new().run_script::<FlowyDoc>(ops);
  485. }
  486. #[test]
  487. fn attributes_link_insert_newline_at_middle() {
  488. let ops = vec![
  489. Insert(0, "123456", 0),
  490. Link(0, Interval::new(0, 6), "https://appflowy.io"),
  491. Insert(0, NEW_LINE, 3),
  492. AssertDocJson(
  493. 0,
  494. r#"[{"insert":"123","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"},{"insert":"456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
  495. ),
  496. ];
  497. TestBuilder::new().run_script::<FlowyDoc>(ops);
  498. }
  499. #[test]
  500. fn attributes_link_auto_format() {
  501. let site = "https://appflowy.io";
  502. let ops = vec![
  503. Insert(0, site, 0),
  504. AssertDocJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
  505. Insert(0, WHITESPACE, site.len()),
  506. AssertDocJson(
  507. 0,
  508. r#"[{"insert":"https://appflowy.io","attributes":{"link":"https://appflowy.io/"}},{"insert":" \n"}]"#,
  509. ),
  510. ];
  511. TestBuilder::new().run_script::<FlowyDoc>(ops);
  512. }
  513. #[test]
  514. fn attributes_link_auto_format_exist() {
  515. let site = "https://appflowy.io";
  516. let ops = vec![
  517. Insert(0, site, 0),
  518. Link(0, Interval::new(0, site.len()), site),
  519. Insert(0, WHITESPACE, site.len()),
  520. AssertDocJson(
  521. 0,
  522. r#"[{"insert":"https://appflowy.io","attributes":{"link":"https://appflowy.io/"}},{"insert":" \n"}]"#,
  523. ),
  524. ];
  525. TestBuilder::new().run_script::<FlowyDoc>(ops);
  526. }
  527. #[test]
  528. fn attributes_link_auto_format_exist2() {
  529. let site = "https://appflowy.io";
  530. let ops = vec![
  531. Insert(0, site, 0),
  532. Link(0, Interval::new(0, site.len() / 2), site),
  533. Insert(0, WHITESPACE, site.len()),
  534. AssertDocJson(
  535. 0,
  536. r#"[{"insert":"https://a","attributes":{"link":"https://appflowy.io"}},{"insert":"ppflowy.io \n"}]"#,
  537. ),
  538. ];
  539. TestBuilder::new().run_script::<FlowyDoc>(ops);
  540. }
  541. #[test]
  542. fn attributes_bullet_added() {
  543. let ops = vec![
  544. Insert(0, "12", 0),
  545. Bullet(0, Interval::new(0, 1), true),
  546. AssertDocJson(0, r#"[{"insert":"12"},{"insert":"\n","attributes":{"list":"bullet"}}]"#),
  547. ];
  548. TestBuilder::new().run_script::<FlowyDoc>(ops);
  549. }
  550. #[test]
  551. fn attributes_bullet_added_2() {
  552. let ops = vec![
  553. Insert(0, "1", 0),
  554. Bullet(0, Interval::new(0, 1), true),
  555. AssertDocJson(0, r#"[{"insert":"1"},{"insert":"\n","attributes":{"list":"bullet"}}]"#),
  556. Insert(0, NEW_LINE, 1),
  557. AssertDocJson(
  558. 0,
  559. r#"[{"insert":"1"},{"insert":"\n\n","attributes":{"list":"bullet"}}]"#,
  560. ),
  561. Insert(0, "2", 2),
  562. AssertDocJson(
  563. 0,
  564. r#"[{"insert":"1"},{"insert":"\n","attributes":{"list":"bullet"}},{"insert":"2"},{"insert":"\n","attributes":{"list":"bullet"}}]"#,
  565. ),
  566. ];
  567. TestBuilder::new().run_script::<FlowyDoc>(ops);
  568. }
  569. #[test]
  570. fn attributes_bullet_remove_partial() {
  571. let ops = vec![
  572. Insert(0, "1", 0),
  573. Bullet(0, Interval::new(0, 1), true),
  574. Insert(0, NEW_LINE, 1),
  575. Insert(0, "2", 2),
  576. Bullet(0, Interval::new(2, 3), false),
  577. AssertDocJson(
  578. 0,
  579. r#"[{"insert":"1"},{"insert":"\n","attributes":{"list":"bullet"}},{"insert":"2\n"}]"#,
  580. ),
  581. ];
  582. TestBuilder::new().run_script::<FlowyDoc>(ops);
  583. }
  584. #[test]
  585. fn attributes_bullet_auto_exit() {
  586. let ops = vec![
  587. Insert(0, "1", 0),
  588. Bullet(0, Interval::new(0, 1), true),
  589. Insert(0, NEW_LINE, 1),
  590. Insert(0, NEW_LINE, 2),
  591. AssertDocJson(
  592. 0,
  593. r#"[{"insert":"1"},{"insert":"\n","attributes":{"list":"bullet"}},{"insert":"\n"}]"#,
  594. ),
  595. ];
  596. TestBuilder::new().run_script::<FlowyDoc>(ops);
  597. }
  598. #[test]
  599. fn attributes_preserve_block_when_insert_newline_inside() {
  600. let ops = vec![
  601. Insert(0, "12", 0),
  602. Bullet(0, Interval::new(0, 2), true),
  603. Insert(0, NEW_LINE, 2),
  604. AssertDocJson(
  605. 0,
  606. r#"[{"insert":"12"},{"insert":"\n\n","attributes":{"list":"bullet"}}]"#,
  607. ),
  608. Insert(0, "34", 3),
  609. AssertDocJson(
  610. 0,
  611. r#"[
  612. {"insert":"12"},{"insert":"\n","attributes":{"list":"bullet"}},
  613. {"insert":"34"},{"insert":"\n","attributes":{"list":"bullet"}}
  614. ]"#,
  615. ),
  616. Insert(0, NEW_LINE, 3),
  617. AssertDocJson(
  618. 0,
  619. r#"[
  620. {"insert":"12"},{"insert":"\n\n","attributes":{"list":"bullet"}},
  621. {"insert":"34"},{"insert":"\n","attributes":{"list":"bullet"}}
  622. ]"#,
  623. ),
  624. Insert(0, "ab", 3),
  625. AssertDocJson(
  626. 0,
  627. r#"[
  628. {"insert":"12"},{"insert":"\n","attributes":{"list":"bullet"}},
  629. {"insert":"ab"},{"insert":"\n","attributes":{"list":"bullet"}},
  630. {"insert":"34"},{"insert":"\n","attributes":{"list":"bullet"}}
  631. ]"#,
  632. ),
  633. ];
  634. TestBuilder::new().run_script::<FlowyDoc>(ops);
  635. }
  636. #[test]
  637. fn attributes_preserve_header_format_on_merge() {
  638. let ops = vec![
  639. Insert(0, "123456", 0),
  640. Header(0, Interval::new(0, 6), 1),
  641. Insert(0, NEW_LINE, 3),
  642. AssertDocJson(
  643. 0,
  644. r#"[{"insert":"123"},{"insert":"\n","attributes":{"header":1}},{"insert":"456"},{"insert":"\n","attributes":{"header":1}}]"#,
  645. ),
  646. Delete(0, Interval::new(3, 4)),
  647. AssertDocJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":1}}]"#),
  648. ];
  649. TestBuilder::new().run_script::<FlowyDoc>(ops);
  650. }
  651. #[test]
  652. fn attributes_preserve_list_format_on_merge() {
  653. let ops = vec![
  654. Insert(0, "123456", 0),
  655. Bullet(0, Interval::new(0, 6), true),
  656. Insert(0, NEW_LINE, 3),
  657. AssertDocJson(
  658. 0,
  659. r#"[{"insert":"123"},{"insert":"\n","attributes":{"list":"bullet"}},{"insert":"456"},{"insert":"\n","attributes":{"list":"bullet"}}]"#,
  660. ),
  661. Delete(0, Interval::new(3, 4)),
  662. AssertDocJson(
  663. 0,
  664. r#"[{"insert":"123456"},{"insert":"\n","attributes":{"list":"bullet"}}]"#,
  665. ),
  666. ];
  667. TestBuilder::new().run_script::<FlowyDoc>(ops);
  668. }
  669. #[test]
  670. fn delta_compose() {
  671. let mut delta = Delta::from_json(r#"[{"insert":"\n"}]"#).unwrap();
  672. let deltas = vec![
  673. Delta::from_json(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(),
  674. Delta::from_json(r#"[{"insert":"a"}]"#).unwrap(),
  675. Delta::from_json(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(),
  676. Delta::from_json(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(),
  677. ];
  678. for d in deltas {
  679. delta = delta.compose(&d).unwrap();
  680. }
  681. assert_eq!(
  682. delta.to_json(),
  683. r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\n"}]"#
  684. );
  685. let ops = vec![
  686. AssertDocJson(0, r#"[{"insert":"\n"}]"#),
  687. Insert(0, "a", 0),
  688. AssertDocJson(0, r#"[{"insert":"a\n"}]"#),
  689. Bullet(0, Interval::new(0, 1), true),
  690. AssertDocJson(0, r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"bullet"}}]"#),
  691. Insert(0, NEW_LINE, 1),
  692. AssertDocJson(
  693. 0,
  694. r#"[{"insert":"a"},{"insert":"\n\n","attributes":{"list":"bullet"}}]"#,
  695. ),
  696. Insert(0, NEW_LINE, 2),
  697. AssertDocJson(
  698. 0,
  699. r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"bullet"}},{"insert":"\n"}]"#,
  700. ),
  701. ];
  702. TestBuilder::new().run_script::<FlowyDoc>(ops);
  703. }