delta_test.dart 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. import 'package:flowy_editor/src/document/attributes.dart';
  2. import 'package:flutter_test/flutter_test.dart';
  3. import 'package:flowy_editor/src/document/text_delta.dart';
  4. void main() {
  5. group('compose', () {
  6. test('test delta', () {
  7. final delta = Delta(<TextOperation>[
  8. TextInsert('Gandalf', {
  9. 'bold': true,
  10. }),
  11. TextInsert(' the '),
  12. TextInsert('Grey', {
  13. 'color': '#ccc',
  14. })
  15. ]);
  16. final death = Delta()
  17. ..retain(12)
  18. ..insert("White", {
  19. 'color': '#fff',
  20. })
  21. ..delete(4);
  22. final restores = delta.compose(death);
  23. expect(restores.toList(), <TextOperation>[
  24. TextInsert('Gandalf', {'bold': true}),
  25. TextInsert(' the '),
  26. TextInsert('White', {'color': '#fff'}),
  27. ]);
  28. });
  29. test('compose()', () {
  30. final a = Delta()..insert('A');
  31. final b = Delta()..insert('B');
  32. final expected = Delta()
  33. ..insert('B')
  34. ..insert('A');
  35. expect(a.compose(b), expected);
  36. });
  37. test('insert + retain', () {
  38. final a = Delta()..insert('A');
  39. final b = Delta()
  40. ..retain(1, {
  41. 'bold': true,
  42. 'color': 'red',
  43. });
  44. final expected = Delta()
  45. ..insert('A', {
  46. 'bold': true,
  47. 'color': 'red',
  48. });
  49. expect(a.compose(b), expected);
  50. });
  51. test('insert + delete', () {
  52. final a = Delta()..insert('A');
  53. final b = Delta()..delete(1);
  54. final expected = Delta();
  55. expect(a.compose(b), expected);
  56. });
  57. test('delete + insert', () {
  58. final a = Delta()..delete(1);
  59. final b = Delta()..insert('B');
  60. final expected = Delta()
  61. ..insert('B')
  62. ..delete(1);
  63. expect(a.compose(b), expected);
  64. });
  65. test('delete + retain', () {
  66. final a = Delta()..delete(1);
  67. final b = Delta()
  68. ..retain(1, {
  69. 'bold': true,
  70. 'color': 'red',
  71. });
  72. final expected = Delta()
  73. ..delete(1)
  74. ..retain(1, {
  75. 'bold': true,
  76. 'color': 'red',
  77. });
  78. expect(a.compose(b), expected);
  79. });
  80. test('delete + delete', () {
  81. final a = Delta()..delete(1);
  82. final b = Delta()..delete(1);
  83. final expected = Delta()..delete(2);
  84. expect(a.compose(b), expected);
  85. });
  86. test('retain + insert', () {
  87. final a = Delta()..retain(1, {'color': 'blue'});
  88. final b = Delta()..insert('B');
  89. final expected = Delta()
  90. ..insert('B')
  91. ..retain(1, {
  92. 'color': 'blue',
  93. });
  94. expect(a.compose(b), expected);
  95. });
  96. test('retain + retain', () {
  97. final a = Delta()
  98. ..retain(1, {
  99. 'color': 'blue',
  100. });
  101. final b = Delta()
  102. ..retain(1, {
  103. 'bold': true,
  104. 'color': 'red',
  105. });
  106. final expected = Delta()
  107. ..retain(1, {
  108. 'bold': true,
  109. 'color': 'red',
  110. });
  111. expect(a.compose(b), expected);
  112. });
  113. test('retain + delete', () {
  114. final a = Delta()
  115. ..retain(1, {
  116. 'color': 'blue',
  117. });
  118. final b = Delta()..delete(1);
  119. final expected = Delta()..delete(1);
  120. expect(a.compose(b), expected);
  121. });
  122. test('insert in middle of text', () {
  123. final a = Delta()..insert('Hello');
  124. final b = Delta()
  125. ..retain(3)
  126. ..insert('X');
  127. final expected = Delta()..insert('HelXlo');
  128. expect(a.compose(b), expected);
  129. });
  130. test('insert and delete ordering', () {
  131. final a = Delta()..insert('Hello');
  132. final b = Delta()..insert('Hello');
  133. final insertFirst = Delta()
  134. ..retain(3)
  135. ..insert('X')
  136. ..delete(1);
  137. final deleteFirst = Delta()
  138. ..retain(3)
  139. ..delete(1)
  140. ..insert('X');
  141. final expected = Delta()..insert('HelXo');
  142. expect(a.compose(insertFirst), expected);
  143. expect(b.compose(deleteFirst), expected);
  144. });
  145. test('delete entire text', () {
  146. final a = Delta()
  147. ..retain(4)
  148. ..insert('Hello');
  149. final b = Delta()..delete(9);
  150. final expected = Delta()..delete(4);
  151. expect(a.compose(b), expected);
  152. });
  153. test('retain more than length of text', () {
  154. final a = Delta()..insert('Hello');
  155. final b = Delta()..retain(10);
  156. final expected = Delta()..insert('Hello');
  157. expect(a.compose(b), expected);
  158. });
  159. test('retain start optimization', () {
  160. final a = Delta()
  161. ..insert('A', {'bold': true})
  162. ..insert('B')
  163. ..insert('C', {'bold': true})
  164. ..delete(1);
  165. final b = Delta()
  166. ..retain(3)
  167. ..insert('D');
  168. final expected = Delta()
  169. ..insert('A', {'bold': true})
  170. ..insert('B')
  171. ..insert('C', {'bold': true})
  172. ..insert('D')
  173. ..delete(1);
  174. expect(a.compose(b), expected);
  175. });
  176. test('retain end optimization', () {
  177. final a = Delta()
  178. ..insert('A', {'bold': true})
  179. ..insert('B')
  180. ..insert('C', {'bold': true});
  181. final b = Delta()..delete(1);
  182. final expected = Delta()
  183. ..insert('B')
  184. ..insert('C', {'bold': true});
  185. expect(a.compose(b), expected);
  186. });
  187. test('retain end optimization join', () {
  188. final a = Delta()
  189. ..insert('A', {'bold': true})
  190. ..insert('B')
  191. ..insert('C', {'bold': true})
  192. ..insert('D')
  193. ..insert('E', {'bold': true})
  194. ..insert('F');
  195. final b = Delta()
  196. ..retain(1)
  197. ..delete(1);
  198. final expected = Delta()
  199. ..insert('AC', {'bold': true})
  200. ..insert('D')
  201. ..insert('E', {'bold': true})
  202. ..insert('F');
  203. expect(a.compose(b), expected);
  204. });
  205. });
  206. group('invert', () {
  207. test('insert', () {
  208. final delta = Delta()
  209. ..retain(2)
  210. ..insert('A');
  211. final base = Delta()..insert('12346');
  212. final expected = Delta()
  213. ..retain(2)
  214. ..delete(1);
  215. final inverted = delta.invert(base);
  216. expect(expected, inverted);
  217. expect(base.compose(delta).compose(inverted), base);
  218. });
  219. test('delete', () {
  220. final delta = Delta()
  221. ..retain(2)
  222. ..delete(3);
  223. final base = Delta()..insert('123456');
  224. final expected = Delta()
  225. ..retain(2)
  226. ..insert('345');
  227. final inverted = delta.invert(base);
  228. expect(expected, inverted);
  229. expect(base.compose(delta).compose(inverted), base);
  230. });
  231. test('retain', () {
  232. final delta = Delta()
  233. ..retain(2)
  234. ..retain(3, {'bold': true});
  235. final base = Delta()..insert('123456');
  236. final expected = Delta()
  237. ..retain(2)
  238. ..retain(3, {'bold': null});
  239. final inverted = delta.invert(base);
  240. expect(expected, inverted);
  241. final t = base.compose(delta).compose(inverted);
  242. expect(t, base);
  243. });
  244. });
  245. group('json', () {
  246. test('toJson()', () {
  247. final delta = Delta()
  248. ..retain(2)
  249. ..insert('A')
  250. ..delete(3);
  251. expect(delta.toJson(), [
  252. {'retain': 2},
  253. {'insert': 'A'},
  254. {'delete': 3}
  255. ]);
  256. });
  257. test('attributes', () {
  258. final delta = Delta()
  259. ..retain(2, {'bold': true})
  260. ..insert('A', {'italic': true});
  261. expect(delta.toJson(), [
  262. {
  263. 'retain': 2,
  264. 'attributes': {'bold': true},
  265. },
  266. {
  267. 'insert': 'A',
  268. 'attributes': {'italic': true},
  269. },
  270. ]);
  271. });
  272. test('fromJson()', () {
  273. final delta = Delta.fromJson([
  274. {'retain': 2},
  275. {'insert': 'A'},
  276. {'delete': 3},
  277. ]);
  278. final expected = Delta()
  279. ..retain(2)
  280. ..insert('A')
  281. ..delete(3);
  282. expect(delta, expected);
  283. });
  284. });
  285. group('runes', () {
  286. test("stringIndexes", () {
  287. final indexes = stringIndexes('😊');
  288. expect(indexes[0], 0);
  289. expect(indexes[1], 0);
  290. });
  291. test("next rune 1", () {
  292. final delta = Delta()..insert('😊');
  293. expect(delta.nextRunePosition(0), 2);
  294. });
  295. test("next rune 2", () {
  296. final delta = Delta()..insert('😊a');
  297. expect(delta.nextRunePosition(0), 2);
  298. });
  299. test("next rune 3", () {
  300. final delta = Delta()..insert('😊陈');
  301. expect(delta.nextRunePosition(2), 3);
  302. });
  303. test("prev rune 1", () {
  304. final delta = Delta()..insert('😊陈');
  305. expect(delta.prevRunePosition(2), 0);
  306. });
  307. test("prev rune 2", () {
  308. final delta = Delta()..insert('😊');
  309. expect(delta.prevRunePosition(2), 0);
  310. });
  311. test("prev rune 3", () {
  312. final delta = Delta()..insert('😊');
  313. expect(delta.prevRunePosition(0), -1);
  314. });
  315. });
  316. group("attributes", () {
  317. test("compose", () {
  318. final attrs = composeAttributes({"a": null}, {"b": null}, true);
  319. expect(attrs != null, true);
  320. expect(attrs!.containsKey("a"), true);
  321. expect(attrs.containsKey("b"), true);
  322. expect(attrs["a"], null);
  323. expect(attrs["b"], null);
  324. });
  325. });
  326. }