attribute_test.rs 20 KB

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