attributedelta.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import transformations from '../../../../src/model/delta/basic-transformations'; // eslint-disable-line no-unused-vars
  6. import deltaTransform from '../../../../src/model/delta/transform';
  7. const transform = deltaTransform.transform;
  8. import Element from '../../../../src/model/element';
  9. import Text from '../../../../src/model/text';
  10. import Position from '../../../../src/model/position';
  11. import Range from '../../../../src/model/range';
  12. import AttributeDelta from '../../../../src/model/delta/attributedelta';
  13. import AttributeOperation from '../../../../src/model/operation/attributeoperation';
  14. import {
  15. expectDelta,
  16. getFilledDocument,
  17. getAttributeDelta,
  18. getWeakInsertDelta,
  19. getSplitDelta
  20. } from '../../../../tests/model/delta/transform/_utils/utils';
  21. describe( 'transform', () => {
  22. let doc, root, baseVersion;
  23. beforeEach( () => {
  24. doc = getFilledDocument();
  25. root = doc.getRoot();
  26. baseVersion = doc.version;
  27. } );
  28. describe( 'AttributeDelta by', () => {
  29. describe( 'WeakInsertDelta', () => {
  30. it( 'weak insert inside attribute range should "fix" splitting the range', () => {
  31. const attrRange = new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 3, 3, 9 ] ) );
  32. const attrDelta = getAttributeDelta( attrRange, 'key', 'old', 'new', baseVersion );
  33. const insertPosition = new Position( root, [ 3, 3, 0 ] );
  34. const insertDelta = getWeakInsertDelta(
  35. insertPosition,
  36. [
  37. 'a',
  38. new Text( 'b', { key: 'new' } ),
  39. new Text( 'c', { key: 'different' } ),
  40. 'de'
  41. ],
  42. baseVersion
  43. );
  44. const transformed = transform( attrDelta, insertDelta );
  45. expect( transformed.length ).to.equal( 2 );
  46. baseVersion = insertDelta.operations.length;
  47. expectDelta( transformed[ 0 ], {
  48. type: AttributeDelta,
  49. operations: [
  50. {
  51. type: AttributeOperation,
  52. range: new Range( new Position( root, [ 3, 3, 5 ] ), new Position( root, [ 3, 3, 8, 9 ] ) ),
  53. key: 'key',
  54. oldValue: 'old',
  55. newValue: 'new',
  56. baseVersion
  57. },
  58. {
  59. type: AttributeOperation,
  60. range: new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 3, 0 ] ) ),
  61. key: 'key',
  62. oldValue: 'old',
  63. newValue: 'new',
  64. baseVersion: baseVersion + 1
  65. }
  66. ]
  67. } );
  68. expectDelta( transformed[ 1 ], {
  69. type: AttributeDelta,
  70. operations: [
  71. {
  72. type: AttributeOperation,
  73. range: new Range( new Position( root, [ 3, 3, 0 ] ), new Position( root, [ 3, 3, 1 ] ) ),
  74. key: 'key',
  75. oldValue: null,
  76. newValue: 'new',
  77. baseVersion: baseVersion + 2
  78. },
  79. {
  80. type: AttributeOperation,
  81. range: new Range( new Position( root, [ 3, 3, 2 ] ), new Position( root, [ 3, 3, 3 ] ) ),
  82. key: 'key',
  83. oldValue: 'different',
  84. newValue: 'new',
  85. baseVersion: baseVersion + 3
  86. },
  87. {
  88. type: AttributeOperation,
  89. range: new Range( new Position( root, [ 3, 3, 3 ] ), new Position( root, [ 3, 3, 5 ] ) ),
  90. key: 'key',
  91. oldValue: null,
  92. newValue: 'new',
  93. baseVersion: baseVersion + 4
  94. }
  95. ]
  96. } );
  97. } );
  98. it( 'should be normally transformed if weak insert is not in the attribute range', () => {
  99. const attrRange = new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 3, 3, 9 ] ) );
  100. const attrDelta = getAttributeDelta( attrRange, 'key', 'old', 'new', baseVersion );
  101. const insertPosition = new Position( root, [ 5 ] );
  102. const insertDelta = getWeakInsertDelta( insertPosition, 'abc', baseVersion );
  103. const transformed = transform( attrDelta, insertDelta );
  104. expect( transformed.length ).to.equal( 1 );
  105. baseVersion = insertDelta.operations.length;
  106. expectDelta( transformed[ 0 ], {
  107. type: AttributeDelta,
  108. operations: [
  109. {
  110. type: AttributeOperation,
  111. range: new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 3, 3, 9 ] ) ),
  112. key: 'key',
  113. oldValue: 'old',
  114. newValue: 'new',
  115. baseVersion
  116. }
  117. ]
  118. } );
  119. } );
  120. } );
  121. describe( 'SplitDelta', () => {
  122. it( 'change attribute of split element', () => {
  123. const attrRange1 = Range.createFromParentsAndOffsets( root, 0, root, 1 );
  124. const attrRange2 = new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 4 ] ) );
  125. const attrDelta = new AttributeDelta();
  126. attrDelta.addOperation( new AttributeOperation( attrRange1, 'key', 'old', 'new', baseVersion ) );
  127. attrDelta.addOperation( new AttributeOperation( attrRange2, 'key', 'old', 'new', baseVersion ) );
  128. const splitPosition = new Position( root, [ 3, 3, 3, 3 ] );
  129. const splitDelta = getSplitDelta( splitPosition, new Element( 'p' ), 9, baseVersion );
  130. const transformed = transform( attrDelta, splitDelta );
  131. expect( transformed.length ).to.equal( 2 );
  132. baseVersion = splitDelta.operations.length;
  133. expectDelta( transformed[ 0 ], {
  134. type: AttributeDelta,
  135. operations: [
  136. {
  137. type: AttributeOperation,
  138. range: new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
  139. key: 'key',
  140. oldValue: 'old',
  141. newValue: 'new',
  142. baseVersion
  143. },
  144. {
  145. type: AttributeOperation,
  146. range: new Range( new Position( root, [ 3, 3, 5 ] ), new Position( root, [ 3, 4 ] ) ),
  147. key: 'key',
  148. oldValue: 'old',
  149. newValue: 'new',
  150. baseVersion: baseVersion + 1
  151. },
  152. {
  153. type: AttributeOperation,
  154. range: new Range( new Position( root, [ 3, 2 ] ), new Position( root, [ 3, 3, 4 ] ) ),
  155. key: 'key',
  156. oldValue: 'old',
  157. newValue: 'new',
  158. baseVersion: baseVersion + 2
  159. },
  160. {
  161. type: AttributeOperation,
  162. range: new Range( new Position( root, [ 3, 3, 4, 0 ] ), new Position( root, [ 3, 3, 4, 9 ] ) ),
  163. key: 'key',
  164. oldValue: 'old',
  165. newValue: 'new',
  166. baseVersion: baseVersion + 3
  167. }
  168. ]
  169. } );
  170. expectDelta( transformed[ 1 ], {
  171. type: AttributeDelta,
  172. operations: [
  173. {
  174. type: AttributeOperation,
  175. range: new Range( new Position( root, [ 3, 3, 4 ] ), new Position( root, [ 3, 3, 4, 0 ] ) ),
  176. key: 'key',
  177. oldValue: null,
  178. newValue: 'new',
  179. baseVersion: baseVersion + 4
  180. }
  181. ]
  182. } );
  183. } );
  184. // A different case.
  185. it( 'change attribute of split element #2', () => {
  186. const attrRange = new Range( new Position( root, [ 3, 3, 3 ] ), new Position( root, [ 3, 3, 3, 0 ] ) );
  187. const attrDelta = new AttributeDelta();
  188. attrDelta.addOperation( new AttributeOperation( attrRange, 'foo', null, 'bar', baseVersion ) );
  189. const splitPosition = new Position( root, [ 3, 3, 3, 3 ] );
  190. const splitDelta = getSplitDelta( splitPosition, new Element( 'p', { foo: 'old' } ), 9, baseVersion );
  191. const transformed = transform( attrDelta, splitDelta );
  192. expect( transformed.length ).to.equal( 2 );
  193. baseVersion = splitDelta.operations.length;
  194. expectDelta( transformed[ 0 ], {
  195. type: AttributeDelta,
  196. operations: [
  197. {
  198. type: AttributeOperation,
  199. range: new Range( new Position( root, [ 3, 3, 3 ] ), new Position( root, [ 3, 3, 3, 0 ] ) ),
  200. key: 'foo',
  201. oldValue: null,
  202. newValue: 'bar',
  203. baseVersion
  204. }
  205. ]
  206. } );
  207. expectDelta( transformed[ 1 ], {
  208. type: AttributeDelta,
  209. operations: [
  210. {
  211. type: AttributeOperation,
  212. range: new Range( new Position( root, [ 3, 3, 4 ] ), new Position( root, [ 3, 3, 4, 0 ] ) ),
  213. key: 'foo',
  214. oldValue: 'old',
  215. newValue: 'bar',
  216. baseVersion: baseVersion + 1
  217. }
  218. ]
  219. } );
  220. } );
  221. } );
  222. } );
  223. } );