attribute_test.rs 22 KB

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