ranges-tracker-test.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. const { expect } = require('chai')
  2. const RangesTracker = require('../..')
  3. describe('RangesTracker', function () {
  4. describe('with duplicate change ids', function () {
  5. beforeEach(function () {
  6. this.comments = []
  7. this.changes = [
  8. { id: 'id1', op: { p: 1, i: 'hello' } },
  9. { id: 'id2', op: { p: 10, i: 'world' } },
  10. { id: 'id3', op: { p: 20, i: '!!!' } },
  11. { id: 'id1', op: { p: 30, d: 'duplicate' } },
  12. ]
  13. this.rangesTracker = new RangesTracker(this.changes, this.comments)
  14. })
  15. it('getChanges() returns all changes with the given ids', function () {
  16. expect(this.rangesTracker.getChanges(['id1', 'id2'])).to.deep.equal([
  17. this.changes[0],
  18. this.changes[1],
  19. this.changes[3],
  20. ])
  21. })
  22. it('removeChangeIds() removes all changes with the given ids', function () {
  23. this.rangesTracker.removeChangeIds(['id1', 'id2'])
  24. expect(this.rangesTracker.changes).to.deep.equal([this.changes[2]])
  25. })
  26. })
  27. describe('with multiple tracked deletes at the same position', function () {
  28. beforeEach(function () {
  29. this.comments = []
  30. this.changes = [
  31. { id: 'id1', op: { p: 33, d: 'before' } },
  32. { id: 'id2', op: { p: 50, d: 'right before' } },
  33. { id: 'id3', op: { p: 50, d: 'this one' } },
  34. { id: 'id4', op: { p: 50, d: 'right after' } },
  35. { id: 'id5', op: { p: 75, d: 'long after' } },
  36. ]
  37. this.rangesTracker = new RangesTracker(this.changes, this.comments)
  38. })
  39. describe('with the orderedRejections flag', function () {
  40. it('preserves the text order when rejecting changes', function () {
  41. this.rangesTracker.applyOp(
  42. { p: 50, i: 'this one', u: true, orderedRejections: true },
  43. { user_id: 'user-id' }
  44. )
  45. expect(this.rangesTracker.changes).to.deep.equal([
  46. { id: 'id1', op: { p: 33, d: 'before' } },
  47. { id: 'id2', op: { p: 50, d: 'right before' } },
  48. { id: 'id4', op: { p: 58, d: 'right after' } },
  49. { id: 'id5', op: { p: 83, d: 'long after' } },
  50. ])
  51. })
  52. it('moves all tracked deletes after the insert if not rejecting changes', function () {
  53. this.rangesTracker.applyOp(
  54. { p: 50, i: 'some other text', u: true, orderedRejections: true },
  55. { user_id: 'user-id' }
  56. )
  57. expect(this.rangesTracker.changes).to.deep.equal([
  58. { id: 'id1', op: { p: 33, d: 'before' } },
  59. { id: 'id2', op: { p: 65, d: 'right before' } },
  60. { id: 'id3', op: { p: 65, d: 'this one' } },
  61. { id: 'id4', op: { p: 65, d: 'right after' } },
  62. { id: 'id5', op: { p: 90, d: 'long after' } },
  63. ])
  64. })
  65. })
  66. describe('without the orderedRejections flag', function () {
  67. it('puts the insert before tracked deletes when rejecting changes', function () {
  68. this.rangesTracker.applyOp(
  69. { p: 50, i: 'this one', u: true },
  70. { user_id: 'user-id' }
  71. )
  72. expect(this.rangesTracker.changes).to.deep.equal([
  73. { id: 'id1', op: { p: 33, d: 'before' } },
  74. { id: 'id2', op: { p: 58, d: 'right before' } },
  75. { id: 'id4', op: { p: 58, d: 'right after' } },
  76. { id: 'id5', op: { p: 83, d: 'long after' } },
  77. ])
  78. })
  79. it('moves all tracked deletes after the insert if not rejecting changes', function () {
  80. this.rangesTracker.applyOp(
  81. { p: 50, i: 'some other text', u: true },
  82. { user_id: 'user-id' }
  83. )
  84. expect(this.rangesTracker.changes).to.deep.equal([
  85. { id: 'id1', op: { p: 33, d: 'before' } },
  86. { id: 'id2', op: { p: 65, d: 'right before' } },
  87. { id: 'id3', op: { p: 65, d: 'this one' } },
  88. { id: 'id4', op: { p: 65, d: 'right after' } },
  89. { id: 'id5', op: { p: 90, d: 'long after' } },
  90. ])
  91. })
  92. })
  93. })
  94. describe('with multiple tracked deletes at the same position with the same content', function () {
  95. beforeEach(function () {
  96. this.comments = []
  97. this.changes = [
  98. { id: 'id1', op: { p: 10, d: 'cat' } },
  99. { id: 'id2', op: { p: 10, d: 'giraffe' } },
  100. { id: 'id3', op: { p: 10, d: 'cat' } },
  101. { id: 'id4', op: { p: 10, d: 'giraffe' } },
  102. ]
  103. this.rangesTracker = new RangesTracker(this.changes, this.comments)
  104. })
  105. describe('with the orderedRejections flag', function () {
  106. it('removes only the first matching tracked delete', function () {
  107. this.rangesTracker.applyOp(
  108. { p: 10, i: 'giraffe', u: true, orderedRejections: true },
  109. { user_id: 'user-id' }
  110. )
  111. expect(this.rangesTracker.changes).to.deep.equal([
  112. { id: 'id1', op: { p: 10, d: 'cat' } },
  113. { id: 'id3', op: { p: 17, d: 'cat' } },
  114. { id: 'id4', op: { p: 17, d: 'giraffe' } },
  115. ])
  116. })
  117. })
  118. describe('without the orderedRejections flag', function () {
  119. it('removes all matching tracked delete', function () {
  120. this.rangesTracker.applyOp(
  121. { p: 10, i: 'giraffe', u: true },
  122. { user_id: 'user-id' }
  123. )
  124. expect(this.rangesTracker.changes).to.deep.equal([
  125. { id: 'id1', op: { p: 17, d: 'cat' } },
  126. { id: 'id3', op: { p: 17, d: 'cat' } },
  127. ])
  128. })
  129. })
  130. })
  131. describe('with a tracked insert at the same position as a tracked delete', function () {
  132. beforeEach(function () {
  133. this.comments = []
  134. this.changes = [
  135. {
  136. id: 'id1',
  137. op: { p: 5, d: 'before' },
  138. metadata: { user_id: 'user-id' },
  139. },
  140. {
  141. id: 'id2',
  142. op: { p: 10, d: 'delete' },
  143. metadata: { user_id: 'user-id' },
  144. },
  145. {
  146. id: 'id3',
  147. op: { p: 10, i: 'insert' },
  148. metadata: { user_id: 'user-id' },
  149. },
  150. ]
  151. this.rangesTracker = new RangesTracker(this.changes, this.comments)
  152. })
  153. describe('with the orderedRejections flag', function () {
  154. it('places a tracked insert at the same position before both the delete and the insert', function () {
  155. this.rangesTracker.track_changes = true
  156. this.rangesTracker.applyOp(
  157. { p: 10, i: 'incoming', orderedRejections: true },
  158. { user_id: 'user-id' }
  159. )
  160. expect(
  161. this.rangesTracker.changes.map(change => change.op)
  162. ).to.deep.equal([
  163. { p: 5, d: 'before' },
  164. { p: 10, i: 'incoming' },
  165. { p: 18, d: 'delete' },
  166. { p: 18, i: 'insert' },
  167. ])
  168. })
  169. })
  170. describe('without the orderedRejections flag', function () {
  171. it('places a tracked insert at the same position before both the delete and the insert', function () {
  172. this.rangesTracker.track_changes = true
  173. this.rangesTracker.applyOp(
  174. { p: 10, i: 'incoming' },
  175. { user_id: 'user-id' }
  176. )
  177. expect(
  178. this.rangesTracker.changes.map(change => change.op)
  179. ).to.deep.equal([
  180. { p: 5, d: 'before' },
  181. { p: 10, i: 'incoming' },
  182. { p: 18, d: 'delete' },
  183. { p: 18, i: 'insert' },
  184. ])
  185. })
  186. })
  187. })
  188. })