attribute_test.rs 23 KB

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